GET /shopping-list?date= (shopping-list.service.ts/.routes.ts) somme les ingrédients de chaque recette planifiée sur la semaine, mis à l'échelle par les portions de chaque créneau (PlanningItem.portions / Recipe.portions), regroupés par paire (ingredientId, unitId) — jamais null contrairement à GET /planning, une semaine vide redescend en items: []. Côté web, ShoppingListPage rend cette liste groupée par rayon (même IngredientCategory que IngredientPicker), triée alphabétiquement en français à l'intérieur d'un rayon (shopping-list.ts, logique pure extraite du composant). WeekNavigator (flèches + calendrier) est extrait de PlanningPage vers features/planning/ pour être partagé entre les deux pages ; ses libellés migrent de planning.* vers common.weekNav.*/ common.calendar.*/common.days.*, plus génériques pour une page qui n'est plus seulement le planning. ComingSoonPage retiré (plus aucun appelant, Liste de courses avait le dernier stub restant). Tests : Mocha (agrégation, mise à l'échelle par portions, unités non fusionnées) + Cucumber (shopping-list.feature : liste vide, groupement/tri, navigation de semaine) + mise à jour de layout.cy.ts/planning-page.cy.ts pour le nouveau rendu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.4 KiB
Architecture technique — Projet Batch-cooking
Documentation de l'architecture serveur/client de l'application.
Vue d'ensemble
L'application repose sur une architecture client-serveur classique :
- Un serveur exposant une API (échanges standards) et un canal websocket (communication temps réel)
- Plusieurs clients (Client 1, Client 2, Client 3...) connectés simultanément au serveur
- Une base de données PostgreSQL
flowchart TB
subgraph SERVER["Server"]
API["API (REST)"]
CALC["Calcul batch-cooking<br/><i>(TODO)</i>"]
IMPORT["Import d'une recette<br/><i>implémenté</i>"]
IMP1["Import depuis source<br/>(RecipeSourceAdapter)"]
IMP2["Traduction en étapes<br/>(ingrédients + techniques)"]
IMP3["Sauvegarde<br/>(sur ajout au planning, ou revue manuelle)"]
DB[("Database<br/>PostgreSQL")]
IMPORT --> IMP1 --> IMP2 --> IMP3 --> DB
end
C1["Client 1"]
C2["Client 2"]
C3["Client 3"]
API <--> C1
API <--> C2
API <--> C3
style SERVER fill:none,stroke:#888,stroke-width:1px
(Le canal websocket envisagé dans la conception d'origine pour le calcul batch-cooking temps réel n'existe pas encore — rien à documenter tant que ce module reste TODO ; voir la note plus bas.)
Composants
API
Point d'entrée principal pour les échanges entre les clients et le serveur — REST classique, requireAuth (cookie JWT httpOnly) sur toute route qui n'est pas une donnée de référence publique. Détail complet des modules : backend-architecture.md.
Module « Calcul batch-cooking »
Logique de calcul du batch-cooking (optimisation du planning/des recettes selon le planning). Statut : TODO — reste à développer, avec packages/shared's assertIsNever déjà en place comme outil prêt à l'emploi pour ce futur module (voir backend-architecture.md).
Module « Import d'une recette »
Statut : implémenté. Pipeline en trois étapes, comme prévu à la conception :
- Import depuis source — chaque source concrète (aujourd'hui : TheMealDB,
API officielle) implémente le contrat
RecipeSourceAdapter(apps/api/src/lib/recipe-sources/recipe-source-adapter.ts—list/fetchDetail/parse), enregistré dans un registre en mémoire et synchronisé vers la tablesources. Un scraper générique JSON-LD/schema.org (json-ld-recipe.ts) existe aussi, en briques réutilisables par un futur adaptateur dédié à un site précis — volontairement pas lui-même une source sélectionnable. - Traduction en étapes —
recipe-translation.tsorchestre la résolution des ingrédients/unités en texte libre contre les catalogues de référence (ingredient-matcher.ts, anglais uniquement pour l'instant) et la détection des techniques (tech-step-matcher.ts, matching par expressions régulières pondérées, avec résolution des chevauchements). - Sauvegarde — persistance en base (
recipe.service.ts'screateImportedRecipe), déclenchée soit automatiquement quand un import "complet" (aucune ligne à arbitrer) est ajouté au planning, soit après une revue manuelle (ingrédients non résolus complétés à la main).
Détail complet du flux (endpoints, algorithmes, décisions produit) : backend-architecture.md côté API, frontend-architecture.md côté web.
Database (PostgreSQL)
Stockage de l'ensemble des données de l'application (voir batch-cooking-modele.md pour le détail des tables — le modèle a beaucoup grandi par rapport à la conception d'origine : sources externes, catalogue d'ingrédients/unités normalisé, techniques détectées, favoris, visibilité des recettes).
Notes
- La « Liste de courses » est implémentée (
GET /shopping-list, voir backend-architecture.md) — une simple agrégation des ingrédients déjà planifiés (somme par ingrédient/unité, mise à l'échelle par les portions de chaque créneau), pas une optimisation. Le module « Calcul batch-cooking » lui-même resteTODO: il désigne quelque chose de plus ambitieux qu'une somme d'ingrédients — optimiser le planning/les recettes entre elles (ex. mutualiser une préparation entre plusieurs recettes de la semaine), pas encore défini plus précisément. C'est le principal chantier restant côté serveur. - Le canal websocket envisagé pour la communication temps réel n'a pas encore été construit — rien ne le remplace aujourd'hui (pas de polling), à reconsidérer au moment d'attaquer le calcul batch-cooking.
Documents liés
Documentation d'implémentation (ajoutée au fil des features, complète ce document conceptuel sans le remplacer) :
- batch-cooking-modele.md — schéma de données complet
- backend-architecture.md — organisation d'
apps/api(modules, sources, matching) - frontend-architecture.md — organisation d'
apps/web - error-handling.md — contrat d'erreurs partagé entre l'API et le client