batchCooking/specs/batch-cooking-architecture.md
Nicolas 6b60c11408 feat(cooking): endpoint GET /cooking-session (plan de cuisine optimise)
Module cooking-session : charge le Planning couvrant ?date= (meme requete
"plage couvrante" + degradation "jamais null" que /shopping-list), mappe
chaque PlanningItem vers l'entree pure de optimizeCookingPlan (ingredients/
unites/techniques/ustensiles resolus via toIngredientView/toUnitView
reutilisees de recipe.service), renvoie OptimizedCookingPlanView.

- cookingSessionPlanningInclude reprend le sous-arbre steps de recipeInclude.
- Route requireAuth, contrat ?date= identique a /shopping-list.
- Monte /cooking-session dans app.ts.
- Tests d'integration Mocha (401, date invalide, plan vide sans foyer /
  sans planning, mutualisation d'une decoupe entre 2 recettes planifiees).
- specs/batch-cooking-architecture.md : module "Calcul batch-cooking" TODO
  -> v1 implementee ; nouvelle section dans backend-architecture.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 19:06:24 +02:00

114 lines
6.1 KiB
Markdown

# 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**
```mermaid
flowchart TB
subgraph SERVER["Server"]
API["API (REST)"]
CALC["Calcul batch-cooking<br/><i>v1 implémentée (GET /cooking-session)</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 — le module v1 est un `GET`
recalculé à chaque visite, pas de temps réel ; 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](./backend-architecture.md).
### Module « Calcul batch-cooking »
Logique de calcul du batch-cooking (optimisation des recettes entre elles selon le planning). **Statut : v1 implémentée**`GET /cooking-session?date=``optimizeCookingPlan` (`apps/api/src/lib/recipe-matching/cooking-optimizer.ts`, pur) réorganise les recettes d'une semaine planifiée en **phases ordonnées** : une « mise en place » qui mutualise la découpe commune (même technique de découpe + même ingrédient dans une étape purement prep de ≥ 2 recettes = une seule tâche), puis des phases de cuisson qui interclassent les recettes en poussant les cuissons passives (mijotage, four…) en tâche de fond. v1 hors périmètre : fusion de cuissons, durées estimées, persistance/progression, canal websocket. Détail : [backend-architecture.md](./backend-architecture.md#cooking-session--optimisation-des-étapes-planifiées).
### Module « Import d'une recette »
**Statut : implémenté.** Pipeline en trois étapes, comme prévu à la conception :
1. **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 table
`sources`. 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.
2. **Traduction en étapes**`recipe-translation.ts` orchestre 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).
3. **Sauvegarde** — persistance en base (`recipe.service.ts`'s
`createImportedRecipe`), 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](./backend-architecture.md#sources-externes--adaptateur-registre-synchronisation)
côté API, [frontend-architecture.md](./frontend-architecture.md#recettes--catalogue-favoris-import-depuis-une-source-externe)
côté web.
### Database (PostgreSQL)
Stockage de l'ensemble des données de l'application (voir
[batch-cooking-modele.md](./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](./backend-architecture.md#liste-de-courses--agrégation-des-ingrédients-planifiés))
— 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, optimise les
recettes **entre elles** (mutualiser une préparation commune, paralléliser
les cuissons passives) — **v1 implémentée** via `GET /cooking-session`
(voir [backend-architecture.md](./backend-architecture.md#cooking-session--optimisation-des-étapes-planifiées)).
- 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). Le calcul
batch-cooking v1 est un simple `GET` recalculé à chaque visite (comme la
liste de courses), pas de temps réel ; à reconsidérer si une session de
cuisine partagée/synchronisée est ajoutée.
---
## 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](./batch-cooking-modele.md) — schéma de données complet
- [backend-architecture.md](./backend-architecture.md) — organisation d'`apps/api` (modules, sources, matching)
- [frontend-architecture.md](./frontend-architecture.md) — organisation d'`apps/web`
- [error-handling.md](./error-handling.md) — contrat d'erreurs partagé entre l'API et le client