12 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| b725ec1016 |
feat(recipes): première source concrète (TheMealDB) + icône de source
Marmiton s'est avéré inaccessible pour du scraping (bloqué même via WebFetch, signe de protection anti-bot) — TheMealDB (themealdb.com) est une vraie API JSON publique et gratuite, sans scraping, testée en conditions réelles (list → fetchDetail → parse fonctionnent bout en bout contre l'API live). - Source.iconUrl (nullable) + RecipeSourceAdapter.iconUrl (requis, même convention que `official`) synchronisé par syncRecipeSources. - apps/api/src/sources/the-meal-db.ts : premier RecipeSourceAdapter réel — official: true (API officielle, pas de scraping), utilise fetch natif (aucune dépendance ajoutée). list() fait une recherche (pas de vrai "browse" côté TheMealDB, mais une requête vide renvoie un échantillon de secours) ; parse() éclate les instructions en étapes par ligne et ignore les emplacements d'ingrédients vides. - apps/api/src/sources/index.ts : registerAllRecipeSources(), appelé par server.ts (process réel) et prisma/seed.ts — délibérément PAS importé par app.ts, pour ne jamais dépendre de l'ordre des tests. - SourceSelect (web) affiche désormais le logo de la source à côté de son nom. Vérifié en conditions réelles : seed → table sources peuplée avec le vrai logo TheMealDB ; endpoint /reference/sources sur serveur réel ; parcours navigateur complet (onboarding → étape sources visible avec icône chargée → activation → paramètres foyer reflète le choix). 186 tests passent (16 nouveaux, dont le moteur TheMealDB testé avec un stub de fetch — aucun appel réseau réel dans la suite automatisée). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| 766d48eaa5 |
feat(recipes): préférences de sources par foyer + distinction officielle/non-officielle
Répond à deux besoins : permettre à chaque foyer de choisir quelles sources apparaissent dans ses onglets de recettes, et distinguer les sources à API officielle des sources scrapées. - RecipeSourceAdapter.official (booléen, sans défaut — chaque adaptateur doit le déclarer explicitement) synchronisé sur Source.official par syncRecipeSources. - HouseSource : table de jointure opt-in (House <-> Source) — aucune ligne = source masquée. Un foyer nouvellement créé ne voit aucune source tant qu'il ne les active pas explicitement. - GET /reference/sources (catalogue des sources implémentées, avec le flag officiel). - GET/PATCH /house/current/sources (lecture/remplacement complet des sources activées par le foyer courant). - recipe.service.ts : sourceVisibilityWhere() filtre désormais TOUS les onglets (perso/foyer/publique/favoris) — une recette sans source reste toujours visible ; une recette importée ne l'est que si sa source est activée pour le foyer du viewer. Un viewer sans foyer ne voit aucune recette sourcée. Côté web : - Nouvelle étape /onboarding/sources dans le wizard d'inscription, atteinte uniquement si un foyer vient d'être créé/rejoint (sinon on saute direct aux allergènes) ; s'auto-saute aussi si aucune source n'est encore implémentée (catalogue vide aujourd'hui). - Nouvelle section « Sources de recettes » dans /parametres/foyer (masquée dans les mêmes conditions), avec sauvegarde à la volée (même pattern que les autres préférences hot-saved). - SourceSelect (features/house/), grille de cases à cocher avec badge officiel/non-officielle, sur le même principe qu'AllergySelect. 172 tests backend passent (dont 25 nouveaux). Build et lint propres. Vérifié manuellement en navigateur : le parcours d'onboarding saute bien l'étape sources (catalogue vide) et affiche « 4 sur 4 » quand un foyer a été créé ; la section paramètres reste invisible tant qu'aucune source n'existe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| 5026a23bd5 |
feat(recipes): catalogue de techniques culinaires (tech steps)
Rend opérationnel le squelette TechStep/TechStepMapping/Step.techStepId présent dans le schéma depuis le premier commit mais jamais implémenté : - TechStep gagne un `key` unique (camelCase, même convention que Diet/Unit) ; TechStepMapping gagne un `locale` pour pouvoir porter plusieurs jeux de règles de matching par langue. - Catalogue statique de 25 techniques françaises courantes (Cuire, Frire, Déglacer, Mijoter, ...), chacune associée à une ou plusieurs expressions régulières + un poids, seedées de façon idempotente dans reference-seed-data.ts. - Nouveau moteur de matching (apps/api/src/lib/tech-step-matcher.ts) : normalisation accents/casse (NFD) puis test des expressions, résolution du meilleur match par poids. Pur et testé unitairement. - Câblé dans recipe.service.ts : à la création/modification d'une recette, chaque étape voit son techStepId calculé automatiquement à partir de sa description (locale "fr" en dur pour l'instant, faute de préférence de langue utilisateur dans l'app). - Reste backend-only : StepView n'expose pas encore techStepId, conformément au commentaire existant. - Endpoint GET /reference/tech-steps + TechStepView, en cohérence avec les autres catalogues de référence. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| de500e1a8a |
feat(recipes): catalogue de référence pour les unités d'ingrédients
Remplace l'unité texte libre de RecipeIngredient (max 20 caractères, "g"/"grammes"/"G"... jamais fiable à additionner) par une référence vers un nouveau catalogue Unit (id/key/type/toBaseFactor), même traitement que Diet/Allergy/Ingredient : GET /reference/units, seedé par reference-seed-data.ts (14 unités : gram/kilogram/milliliter/ centiliter/liter/tablespoon/teaspoon/piece/pinch/slice/clove/bunch/ sachet/sprig), sélectionnable uniquement via un <select> dans le formulaire recette (plus de saisie libre). `toBaseFactor` (combien d'unités de base — gramme pour MASS, millilitre pour VOLUME — vaut une unité) pose les bases d'une future fonctionnalité de conversion (ex. liste de courses additionnant "500g" + "0.5kg") sans construire cette fonctionnalité elle-même — les unités COUNT restent à toBaseFactor=1, non convertibles entre elles (une "pincée" n'est pas une fraction fixe d'une "gousse"). Migration : recipe_ingredient.unit → unit_id (FK), breaking change sans backfill assumé (pas de recette réelle en prod actuellement, voir commentaire de migration) — mêmes garde-fous service-side que ingredientId (404 UNIT_NOT_FOUND) et mêmes tests de couverture. |
|||
| 978fe71a11 |
feat(recipes): flag les ingrédients faisables maison + suggestion de recherche
Remplace la FK morte `Ingredient.alternateRecipeId` (jamais branchée nulle part — confirmé par exploration : zéro usage en dehors de schema.prisma) par un flag booléen `reproducible`, plus simple : pas de liaison recette↔ingrédient en base, juste une info "ça vaut le coup d'être fait maison" plus un raccourci de recherche. - Migration : drop `alternate_recipe` (colonne + FK), ajoute `reproducible BOOLEAN NOT NULL DEFAULT false` sur `ingredients`. - `reference-seed-data.ts` : `IngredientSeed` gagne `reproducible?`, threadé dans le flatten + la réconciliation `seedReferenceData`. Premier lot de 27 ingrédients marqués (pains, pâtes à cuire, sauces de base, bouillons/fonds) — même logique que la curation Ciqual : un lot solide plutôt qu'exhaustif sur les 546 ingrédients. - `IngredientView` (shared) + les deux endroits qui la construisent (`reference.service.ts`, `recipe.service.ts`) gagnent `reproducible`. - `ReproducibleBadge` (nouveau) : pastille "Faisable maison" — simple dans `IngredientPicker` (avec son propre toggle d'affichage), lien cliquable dans `IngredientRow` vers `/recettes?search=<nom>` ouvert dans un nouvel onglet (pour ne jamais perdre le formulaire de recette en cours — pas de persistance de brouillon dans `RecipeFormPage`). - `RecipesPage` lit `?search=` au montage pour permettre ce deep-link. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
|
|
c34eaa89d0
|
chore(web): session de polish global — version, checkbox, danger zone, icônes (#20)
* chore(web): session de polish global — version, checkbox, danger zone, icônes
- Affiche le numéro de version (package.json, injecté via Vite) en bas de
la sidebar, masqué en mode collapse et en mobile.
- Factorise les checkbox/radio dupliqués (AllergySelect, DietTagSelect,
IngredientPicker, UserPreferencesPage) en composants partagés
CheckboxOption/RadioOption (components/ui/), et inverse le layout pour
que la case soit à gauche du label.
- Teinte la "zone de danger" de suppression de compte en rouge (fond +
bordure), pas seulement le bouton.
- Migre les icônes de navigation générale vers lucide-react (nav-icons.tsx
devient un fichier de ré-export) ; les pictogrammes d'ingrédients métier
restent en SVG custom (pas d'équivalents fins côté lucide).
Vérifié : pnpm build, pnpm lint, pnpm --filter web e2e (43/43), et
vérification visuelle manuelle (sidebar desktop/collapsed/mobile, light/dark).
* feat(web): icônes d'ingrédients depuis foodiconpack.com + page de crédits
- Remplace 19 des 22 pictogrammes génériques d'ingrédients par des icônes
curées du pack gratuit "Common ingredient icons"/"Common Utensils" de
foodiconpack.com (CC BY 4.0) : carotte, pomme, basilic, bœuf, poulet,
saumon, crevette, riz, pois chiches, amandes, lait, cheddar, œufs,
cannelle, miel, huile d'olive, bière, marmite, sucre.
- BREAD/DOUGH/SPROUT restent en SVG custom : pas d'équivalent net dans le
pack (packs "ingrédients"/"ustensiles"/"plats"/"boissons" vérifiés).
Architecture inchangée : `icon` reste un enum de 22 valeurs partagées en
base (pas de migration, pas de mapping par ingrédient — cf. le
commentaire du fichier sur l'historique emoji→enum générique).
- Nouveau wrapper FilledIcon (fill="currentColor", viewBox 2048) à côté du
wrapper Icon existant (stroke) — les deux stylent au même endroit via
CSS, donc le mélange des 19+3 icônes reste visuellement homogène.
- Ajoute /parametres/credits (CreditsPage) créditant foodiconpack.com et
liant la licence CC BY 4.0, requis par la licence des icônes utilisées ;
nouvelle entrée de nav "Crédits" (icône lucide Info).
Vérifié : pnpm build, pnpm lint, pnpm --filter web e2e (43/43), et
vérification visuelle (grille des 22 icônes dans le picker, page crédits).
* feat(web,api): zone dangereuse rouge, préférences élargies, onglet favoris par défaut, e2e recettes, catalogue en uid+i18n
- Zone dangereuse (compte) : le bouton "Supprimer mon compte" est rouge.
- Pages préférences/paramétrage : contenu centré et élargi (32rem -> 56rem)
au lieu de coller à gauche sur un écran large.
- Page recettes : l'onglet "Favoris" est sélectionné par défaut.
- Ajout de apps/web/cypress/e2e/recipes.cy.ts (onglets, recherche, sélection
master-detail, favori, suppression, lien nouvelle recette).
- Catalogue de référence (ingrédients/régimes/allergènes) : la colonne
`name` (le libellé français, utilisé comme clé unique) devient `key`, un
slug stable et opaque au sens produit (ex. "vegetarien", "boeuf_hache").
Le libellé lui-même déménage entièrement côté client, dans
apps/web/src/locales/fr/translation.json sous le namespace `catalog.*`,
résolu via `t(\`catalog.ingredients.${key}\`)` etc. — même schéma que
IngredientCategory/IngredientSubcategory. Migration Prisma
(rename + backfill des ~456 lignes déjà seedées), seed/service/tests API
et composants web mis à jour en conséquence.
- apps/api/src/utils/slugify.ts + scripts/generate-catalog-i18n.ts
(regénère le fichier de traduction depuis reference-seed-data.ts).
- 102 tests Mocha + 32 scénarios Cucumber passent contre la base migrée.
Note : cypress run plante dans cet environnement (le processus GPU
Chromium/Electron crash même headless, indépendamment des flags) — les
recipes.cy.ts n'ont pas pu être exécutés ici ; vérifiés par lecture du code
source des composants visés et par un passage manuel dans le navigateur de
prévisualisation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(api): les uids du catalogue sont en anglais, pas des slugs français
reference-seed-data.ts reste rédigé en français (c'est juste le libellé
d'autoring, jamais stocké/exposé), mais la clé stable (`Diet.key`/
`Category.key`/`Ingredient.key`) qu'on en dérive doit elle-même être un
identifiant anglais, indépendant de la langue d'autoring — pas juste le
même texte français passé à slugify().
- apps/api/src/db/catalog-en-keys.ts : dictionnaire écrit à la main
(label français -> clé anglaise) pour les 5 régimes, 14 allergènes et
437 ingrédients ; getEnglishKey() lève une erreur explicite si un
nouvel élément n'a pas encore d'entrée plutôt que de retomber sur un
slug français silencieux.
- scripts/validate-catalog-en-keys.ts : vérifie que chaque diet/allergène/
ingrédient de reference-seed-data.ts a une entrée, et que les clés
anglaises résultantes sont uniques (437/437, 14/14, 5/5 — zéro manquant,
zéro collision).
- reference-seed-data.ts et scripts/generate-catalog-i18n.ts utilisent
désormais getEnglishKey() au lieu de slugify(nom français).
- Nouvelle migration (20260818193000_catalog_keys_to_english) qui
remappe les lignes déjà seedées avec un slug français (par la migration
précédente) vers leur clé anglaise définitive.
- apps/web/src/locales/fr/translation.json régénéré : catalog.* est
maintenant indexé par clé anglaise ("vegetarian", "eggs",
"ground_beef"...), toujours avec le libellé français en valeur.
- Tests/step-definitions mis à jour (getEnglishKey() au lieu de
slugify()) ; 102 tests Mocha + 32 scénarios Cucumber passent contre la
base migrée. Vérifié aussi en direct via GET /reference/diets et
/reference/allergies.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(web): crypto.randomUUID plante hors contexte sécurisé, empêchant d'associer un ingrédient
Écran noir + "TypeError: crypto.randomUUID is not a function" au clic sur
une carte d'ingrédient dans le formulaire de recette. crypto.randomUUID()
n'est défini que dans un "contexte sécurisé" (https, ou littéralement le
host "localhost") — il est absent sur une IP locale (test sur un vrai
appareil), dans une WebView Capacitor (l'enrobage mobile prévu pour cette
app), ou en http sur un vrai domaine. RecipeFormPage/StepListEditor s'en
servaient pour générer l'identité React (`key`) de chaque ligne
d'ingrédient/étape en brouillon.
- apps/web/src/lib/client-key.ts : remplace par un générateur qui ne
touche jamais `crypto` — un compteur + Math.random suffit, cette valeur
n'a besoin d'être unique que le temps de la session de rendu, jamais
envoyée au serveur.
- apps/web/cypress/e2e/recipe-form.cy.ts : couvre l'association d'un
ingrédient (recherche, sélection, exclusion du picker une fois
sélectionné, retrait), la création et l'édition d'une recette, et un
test de non-régression dédié qui supprime crypto.randomUUID avant le
chargement de la page (comme le ferait un vrai contexte non sécurisé)
pour vérifier que l'ajout de plusieurs ingrédients/étapes ne plante
plus.
Vérifié en direct dans le navigateur de prévisualisation en supprimant
crypto.randomUUID à la main (reproduit le crash), puis en confirmant que
l'ajout d'ingrédient fonctionne à nouveau après le correctif. cypress run
ne peut toujours pas s'exécuter dans cet environnement (voir le commit
précédent) — non exécutés avec Cypress lui-même, mais vérifiés par
lecture des sélecteurs réels et rejoués à la main dans le navigateur.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(ci): corrige les specs Cypress cassées par le refactor uid+i18n, applique biome
- onboarding.cy.ts / preferences.cy.ts / recipes.cy.ts mockaient encore
GET /reference/diets|allergies avec l'ancienne forme {id, name}. Depuis
les deux derniers commits l'API renvoie {id, key} (uid anglais) et le
composant résout le libellé via i18n (t(`catalog.diets.${key}`)) — avec
key manquant, ça affichait littéralement "catalog.diets.undefined" au
lieu de "Végétarien"/"Omnivore"/etc., faisant échouer cy.select()/
cy.contains() dans ces 3 specs. Corrigé pour mocker {key: "vegetarian"},
{key: "peanuts"}, etc.
- recipes.cy.ts : le test "shows a not-found message" utilisait le
mauvais code d'erreur (4041 au lieu de ErrorCode.RECIPE_NOT_FOUND =
4045), donc RecipeDetailPanel tombait dans son état d'erreur générique
au lieu du message "Cette recette n'existe pas." — bug dans mon propre
test, sans rapport avec le refactor.
- pnpm lint (biome) : les fichiers touchés par le refactor précédent
avaient quelques soucis de formatage/tri d'imports (des sed multi-
fichiers, pas d'édition via l'outil habituel) — corrigés par
`biome check --write`.
Vérifié : ces 3 specs + recipe-form.cy.ts passent maintenant dans le job
CI GitHub Actions (Linux, Cypress s'y exécute réellement — contrairement
à cet environnement Windows sandboxé, voir les commits précédents) ; 102
tests Mocha + 32 scénarios Cucumber toujours au vert en local.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
|
||
| 9775cbe38f |
feat(recipes): refonte de la catégorisation des ingrédients façon rayons de supermarché
Remplace les 18 catégories plates (mélangeant rayons génériques et cuisines d'origine — un ingrédient pouvait finir dans "légumes" ou "cuisine italienne" selon l'angle choisi) par une hiérarchie à 2 niveaux sur le modèle d'un supermarché français : - 🥦 Produits frais (légumes, fruits, herbes fraîches) - 🥩 Boucherie & poissonnerie (viandes, volailles, poissons, crustacés & fruits de mer) - 🥫 Épicerie sèche (féculents, légumineuses, graines & fruits secs, autres produits secs/conserves) - 🍞 Boulangerie (pains, pâtes à cuire — 4 nouveaux ingrédients : pâte feuilletée/brisée/à pizza/à tarte sablée) - 🧈 Crémerie & fromage (produits laitiers, œufs, alternatives végétales) - 🧂 Condiments & épices (épices, sauces, assaisonnements) - 🍳 Aides culinaires (bases, épaississants, sucres) - Schéma : nouvel enum IngredientCategory (7 valeurs) + nouvel enum IngredientSubcategory (22 valeurs) + colonne Ingredient.subcategory. Migration appliquée via reset (données de référence, aucune perte réelle) car les anciennes valeurs d'enum n'existent plus dans les nouvelles. - reference-seed-data.ts entièrement réorganisé par (catégorie, sous- catégorie), tous les 437 ingrédients recatégorisés un par un. - packages/shared : INGREDIENT_CATEGORIES (7), INGREDIENT_SUBCATEGORIES (22) et INGREDIENT_CATEGORY_SUBCATEGORIES (mapping catégorie → sous-catégories, pour piloter le picker) remplacent l'ancienne liste plate. - IngredientPicker : drill-down à 2 niveaux — la ligne de sous- catégories (couleur --color-tag, visuellement subordonnée) apparaît une fois une catégorie choisie, et se réinitialise au changement de catégorie. - i18n : nouvelles clés recipes.form.category.* (7) et recipes.form.subcategory.* (22). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| 5890c62462 |
fix(recipes): overflow des préférences + régimes liés aux ingrédients
- Fix overflow horizontal sur /parametres/preferences : <fieldset> a un min-width: min-content par défaut du navigateur, ce qui empêchait la grille de l'IngredientPicker de wrapper (page entière poussée à ~3100px de large). Reset min-width: 0 sur .disliked-ingredients-field. - Recatégorise les laits/crèmes végétaux (coco, amande, avoine) de PRODUITS_LAITIERS_OEUFS vers LIQUIDES_BOISSONS — ce ne sont pas des produits laitiers. - Nouveau modèle IngredientDiet (many-to-many ingrédient <-> régime) : quels régimes (Végétarien, Végan, Pescétarien) chaque ingrédient respecte. Omnivore volontairement absent (trivial) et Sans gluten aussi (déjà dérivable de l'allergène Gluten existant). - reference-seed-data.ts : chaque groupe de catégorie porte un defaultDiets, avec dietNames en override pour les exceptions (fromages, viandes, poissons, sauces à base d'œuf/poisson...). - IngredientView.diets exposé par /reference/ingredients et /recipes, affiché via DietBadges dans IngredientPicker et IngredientRow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| ea86a4a7f1 |
feat(recipes): catégories d'ingrédients + nouveau sélecteur
- Prisma: enum IngredientCategory (18 valeurs) + Ingredient.category, migration appliquée - reference-seed-data.ts restructuré en 18 groupes de catégories - packages/shared: INGREDIENT_CATEGORIES + IngredientView.category - API: category exposé par /reference/ingredients et /recipes - Web: nouveau IngredientPicker (chips catégories + recherche + grille de cartes) remplaçant IngredientAutocomplete, branché dans le formulaire de recette et le champ aliments-pas-aimés - i18n: clés recipes.form.category.* et libellés du picker - Fix test reference.test.ts pour la nouvelle forme d'IngredientView Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| acab18ac4a |
feat(recipes): catalogue v2 - visibilité, favoris, régimes et catalogue d'ingrédients exhaustif
Recipe catalog v2: - Recipe gagne visibility (PERSONAL/HOUSE/PUBLIC), authorId, authorHouseId - Favoris par utilisateur (RecipeFavorite), régimes associés (RecipeDiet) - Aliments "pas aimés" par utilisateur (UserProfileDislikedIngredient), distinct des allergies médicales - API: GET /recipes?tab=favoris|perso|foyer|publique avec contrôle d'accès complet, POST/DELETE /recipes/:id/favorite, édition/suppression réservées à l'auteur (403 NOT_RECIPE_AUTHOR), GET/PATCH /profile/disliked-ingredients - Frontend: vue maître-détail (onglets + tableau + panneau détail), formulaire enrichi (visibilité, régimes), section préférences pour les aliments pas aimés Catalogue d'ingrédients de référence: - Extension du seed de 39 à ~430 ingrédients (viandes, poissons/fruits de mer, légumes, fruits, féculents, condiments/sauces, épices/herbes, pains à sandwich, cuisines italienne/asiatique/mexicaine/maghrébine, liquides et boissons de cuisine, bouillons/fonds) - Chaque ingrédient lié à ses allergènes UE (IngredientAllergy) — les 14 allergènes réglementaires restent tous couverts - Seeding optimisé en requêtes groupées (createMany/diff ciblé) plutôt qu'un upsert par ligne, pour garder resetDatabase() rapide en test Tests: 102 tests Mocha + 32 scénarios BDD, tous verts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
|||
| 6cfa71730c |
API: séparer allergies et intolérances (kind sur Category) (step 7/8)
Retour fonctionnel : les allergies et intolérances doivent être
distinguées, pas listées ensemble.
- schema.prisma: enum AllergenKind (ALLERGY|INTOLERANCE) + Category.kind
(@default(ALLERGY), migration écrite à la main comme précédemment —
`migrate dev` refuse en environnement non-interactif ici — SQL généré
via `prisma migrate diff`).
- reference-seed-data.ts: classification par substance (Gluten et
Sulfites = INTOLERANCE, les 12 autres = ALLERGY — réaction
non-immunitaire documentée vs réaction immunitaire classique).
Corrige au passage l'upsert : `update: { kind }` au lieu de `update:
{}` — un reseed doit pouvoir corriger `kind` sur une Category déjà
existante, pas juste no-op.
- reference.service.ts / packages/shared: AllergyView gagne `kind`.
PATCH /profile/allergies ne change pas (une seule liste d'IDs, kind
ne sert qu'au groupement d'affichage côté client).
- Tests Mocha (29 passing) + Cucumber (15 scenarios, inchangés).
Classifié par substance (pas par utilisateur) — documenté comme
limitation connue dans le README. Web (split UI + hot saving sur
/foyer) dans le commit suivant.
|
|||
| 9b7c955019 |
API: seed régimes/allergènes + GET /reference/diets, /reference/allergies (step 1/6)
- schema.prisma: Diet.name/Category.name deviennent @unique (pas dans le doc spec d'origine — ajouté pour que le seed soit idempotent par upsert). Migration écrite à la main + appliquée via `migrate deploy` (`migrate dev` refuse en environnement non-interactif ici) — SQL généré via `prisma migrate diff` pour matcher exactement les conventions Prisma. - src/db/reference-seed-data.ts: seedReferenceData() — 5 régimes, 14 allergènes (règlement UE 1169/2011 annexe II). Chaque allergène = une Category (upsert par nom) + une unique Allergy sous cette catégorie (Allergy elle-même ne porte pas de nom, voir schema.prisma). Réutilisée par prisma/seed.ts (CLI, `prisma db seed`) ET test-support/reset-db.ts (chaque test repart avec ces données de référence, pas des tables vides). - modules/reference/: GET /reference/diets, GET /reference/allergies — publics (pas de requireAuth), lisibles avant qu'un compte existe (wizard d'inscription). - packages/shared: DietView, AllergyView (name résolu côté serveur depuis Category, le split Allergy/Category reste invisible du client). - Tests Mocha + Cucumber, doc README. Premier commit de la feature profil/foyer/régime/allergènes (planifiée en chat) — endpoints foyer/profil dans le commit suivant. |