feat(sources): ajoute quitoque.fr comme source de recettes importable #52

Merged
kyuno merged 1 commit from feat/quitoque-recipe-source into main 2026-09-06 01:28:03 +02:00
Owner

Corrige l'issue #37 — 5e adaptateur de source.

Conception

Calqué sur marmiton.ts, le plus fin des wrappers scrapés :

  • fetchDetail / parse délèguent tels quels à jsonLdRecipeAdapter — une page recette quitoque.fr porte un Recipe schema.org, seul élément d'un tableau JSON-LD de premier niveau, déjà géré nativement par findRecipeNode (vérifié dans le ticket). rekeySourceError re-labellise jsonLdRecipe → quitoque (copie locale, comme 750g / manger-bouger).
  • Seul list() est site-spécifique : GET https://www.quitoque.fr/recettes?page=N (page 1 implicite si pas de curseur), scrape des cartes <a class="card__content_header" href="/recettes/…"> — image réelle dans data-src (src n'est qu'un placeholder lazy-load), href relatif résolu contre l'origine. L'extraction est agnostique à l'ordre des attributs.
  • Pas de vraie recherche serveur → query est un filtre sous-chaîne best effort sur les titres de la page courante (même lacune assumée que 750g.ts). Fin de liste = page sans aucune carte (comme marmiton.ts) ; le filtre query ne bloque pas l'avancée si la page brute avait des cartes.

Enregistré dans registerAllRecipeSources() → syncRecipeSources crée sa ligne Source (household-toggleable).

Tests

  • apps/api/test/recipe-sources/quitoque.test.ts (stubFetchHtml, pas de base) : scrape de plusieurs cartes → RecipeSourceListItems (URL absolue, image depuis data-src), nextCursor: "2" ; page vide → fin de liste ; curseur → ?page=N (URL capturée) ; filtre par query ; erreurs RecipeSourceFetchError/ParseError re-labellisées quitoque ; parse sur un JSON-LD tableau-de-premier-niveau → portions/ingredients/steps corrects. Vérifié localement : 9/9.
  • apps/api/test/sources/sources-index.test.ts : nouveau cas « registers Quitoque ».

Docs

backend-architecture.md — section quitoque.ts ajoutée, et la ligne « registerAllRecipeSources() n'enregistre aujourd'hui que TheMealDB » (fausse depuis longtemps) corrigée en theMealDb, marmiton, 750g, mangerBouger, quitoque. Le reste de la staleness de cette section (paragraphes Marmiton/750g/MangerBouger absents) est laissé au rattrapage global mentionné sur le ticket.

build + lint verts.

🤖 Generated with Claude Code

Corrige l'[issue #37](https://git.dev.kyuno.fr/kyuno/batchCooking/issues/37) — 5e adaptateur de source. ## Conception Calqué sur `marmiton.ts`, le plus fin des wrappers scrapés : - `fetchDetail` / `parse` **délèguent tels quels** à `jsonLdRecipeAdapter` — une page recette quitoque.fr porte un `Recipe` schema.org, seul élément d'un tableau JSON-LD de premier niveau, déjà géré nativement par `findRecipeNode` (vérifié dans le ticket). `rekeySourceError` re-labellise `jsonLdRecipe` → `quitoque` (copie locale, comme 750g / manger-bouger). - Seul `list()` est site-spécifique : `GET https://www.quitoque.fr/recettes?page=N` (page 1 implicite si pas de curseur), scrape des cartes `<a class="card__content_header" href="/recettes/…">` — **image réelle dans `data-src`** (`src` n'est qu'un placeholder lazy-load), `href` relatif résolu contre l'origine. L'extraction est agnostique à l'ordre des attributs. - Pas de vraie recherche serveur → `query` est un filtre sous-chaîne *best effort* sur les titres de la page courante (même lacune assumée que `750g.ts`). Fin de liste = page sans aucune carte (comme `marmiton.ts`) ; le filtre `query` ne bloque pas l'avancée si la page brute avait des cartes. Enregistré dans `registerAllRecipeSources()` → `syncRecipeSources` crée sa ligne `Source` (household-toggleable). ## Tests - `apps/api/test/recipe-sources/quitoque.test.ts` (`stubFetchHtml`, pas de base) : scrape de plusieurs cartes → `RecipeSourceListItem`s (URL absolue, image depuis `data-src`), `nextCursor: "2"` ; page vide → fin de liste ; curseur → `?page=N` (URL capturée) ; filtre par `query` ; erreurs `RecipeSourceFetchError`/`ParseError` re-labellisées `quitoque` ; `parse` sur un JSON-LD tableau-de-premier-niveau → `portions`/`ingredients`/`steps` corrects. **Vérifié localement : 9/9.** - `apps/api/test/sources/sources-index.test.ts` : nouveau cas « registers Quitoque ». ## Docs `backend-architecture.md` — section `quitoque.ts` ajoutée, et la ligne « `registerAllRecipeSources()` n'enregistre aujourd'hui que TheMealDB » (fausse depuis longtemps) corrigée en `theMealDb, marmiton, 750g, mangerBouger, quitoque`. Le reste de la staleness de cette section (paragraphes Marmiton/750g/MangerBouger absents) est laissé au rattrapage global mentionné sur le ticket. `build` + `lint` verts. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-09-06 01:12:11 +02:00
feat(sources): ajoute quitoque.fr comme source de recettes importable
All checks were successful
CI / build (push) Successful in 3m28s
CI / lint (push) Successful in 3m33s
CI / intent-service-test (push) Successful in 4m54s
CI / e2e (push) Successful in 7m20s
CI / test (push) Successful in 15m33s
4906accd85
5e adaptateur, calqué sur `marmiton.ts` (le plus fin des wrappers
scrapés) : `fetchDetail`/`parse` délèguent tels quels à
`jsonLdRecipeAdapter` — une page recette quitoque.fr porte un `Recipe`
schema.org, seul élément d'un tableau JSON-LD de premier niveau, déjà géré
nativement par `findRecipeNode`. Seul `list()` est spécifique :
`GET /recettes?page=N` (page 1 implicite si curseur absent), scrape des
cartes `<a class="card__content_header" href="/recettes/…">` (image réelle
dans `data-src`, `src` n'étant qu'un placeholder lazy-load ; `href`
relatif résolu contre l'origine). Extraction agnostique à l'ordre des
attributs.

Pas de vraie recherche serveur sur le site → `query` est un filtre
sous-chaîne « best effort » sur les titres de la page courante (même
lacune assumée que `750g.ts`). Fin de liste = page sans aucune carte
(comme `marmiton.ts`). `rekeySourceError` dupliqué localement (750g /
manger-bouger en ont chacun une copie).

Enregistré dans `registerAllRecipeSources()`.

Tests : `quitoque.test.ts` (`stubFetchHtml`, pas de base) — scrape des
cartes, pagination `?page=N`, filtre par query, fin de liste, erreurs
re-labellisées `quitoque`, `parse` sur un JSON-LD tableau-de-premier-
niveau. Vérifié localement, 9/9. + `sources-index.test.ts` couvre
l'enregistrement.

Docs : section `quitoque.ts` dans `backend-architecture.md` (+ correction
de la ligne « n'enregistre que TheMealDB », devenue fausse).

Closes #37

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno merged commit 8a29889175 into main 2026-09-06 01:28:03 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/batchCooking#52
No description provided.