fix(3b): delad kompletteringsväg för legacy /cook + deterministiska cooking-assumptions

- cookRecipeInputSchema utökas med actualPortionsEaten, leftoverEstimatePortions, leftoverNote
- completeCookingSession-wrapper i apps/api/src/lib/cooking.ts hanterar summavalidering,
  persistens av svar, profiluppdateringar och analytics (started+completed) för båda vägarna
- Legacy POST /v1/recipes/:id/cook använder wrappern med emitStartedEvent
- GET /v1/recipes/:id/cooking-assumptions väljer deterministiskt bland icke-valfria ingredienser
- i18n: nyckel cooked.portionsSumExceedsPlanned i samtliga 12 lokaler + server-i18n
- Nya tester för legacy /cook och cooking-assumptions med valfri första ingrediens

Refs: steg 3b-fix, granskningsrunda 2026-08-07
This commit is contained in:
Sven (AAMOS AI)
2026-08-07 05:13:35 +07:00
parent e46281b9b5
commit bbe7526ef3
18 changed files with 457 additions and 162 deletions
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Bekræft alle",
"scan.diff.noChanges": "Ingen forskelle fundet.",
"scan.diff.undo": "Fortryd",
"scan.diff.undoHint": "Hver ændring kan fortrydes fra varedetaljevisningen."
"scan.diff.undoHint": "Hver ændring kan fortrydes fra varedetaljevisningen.",
"cooked.portionsSumExceedsPlanned": "Antal spiste portioner og rester må ikke overstige det samlede antal portioner."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Alle bestätigen",
"scan.diff.noChanges": "Keine Unterschiede gefunden.",
"scan.diff.undo": "Rückgängig",
"scan.diff.undoHint": "Jede Änderung kann in der Artikeldetailansicht rückgängig gemacht werden."
"scan.diff.undoHint": "Jede Änderung kann in der Artikeldetailansicht rückgängig gemacht werden.",
"cooked.portionsSumExceedsPlanned": "Gegessene Portionen und Reste dürfen die Gesamtanzahl der Portionen nicht überschreiten."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Confirm all",
"scan.diff.noChanges": "No differences found.",
"scan.diff.undo": "Undo",
"scan.diff.undoHint": "Each change can be undone from the item detail view."
"scan.diff.undoHint": "Each change can be undone from the item detail view.",
"cooked.portionsSumExceedsPlanned": "Eaten portions and leftovers cannot exceed the total number of portions."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Confirmar todo",
"scan.diff.noChanges": "No se encontraron diferencias.",
"scan.diff.undo": "Deshacer",
"scan.diff.undoHint": "Cada cambio se puede deshacer desde la vista de detalle del producto."
"scan.diff.undoHint": "Cada cambio se puede deshacer desde la vista de detalle del producto.",
"cooked.portionsSumExceedsPlanned": "Las raciones comidas y las sobras no pueden superar el número total de raciones."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Vahvista kaikki",
"scan.diff.noChanges": "Eroja ei löytynyt.",
"scan.diff.undo": "Kumoa",
"scan.diff.undoHint": "Jokainen muutos voidaan kumota tuotteen tietonäkymästä."
"scan.diff.undoHint": "Jokainen muutos voidaan kumota tuotteen tietonäkymästä.",
"cooked.portionsSumExceedsPlanned": "Syödyt annokset ja tähteet eivät voi ylittää annosten kokonaismäärää."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Tout confirmer",
"scan.diff.noChanges": "Aucune différence trouvée.",
"scan.diff.undo": "Annuler",
"scan.diff.undoHint": "Chaque modification peut être annulée depuis la vue détail de l'article."
"scan.diff.undoHint": "Chaque modification peut être annulée depuis la vue détail de l'article.",
"cooked.portionsSumExceedsPlanned": "Les portions mangées et les restes ne peuvent pas dépasser le nombre total de portions."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Conferma tutto",
"scan.diff.noChanges": "Nessuna differenza trovata.",
"scan.diff.undo": "Annulla",
"scan.diff.undoHint": "Ogni modifica può essere annullata dalla vista dettaglio dell'articolo."
"scan.diff.undoHint": "Ogni modifica può essere annullata dalla vista dettaglio dell'articolo.",
"cooked.portionsSumExceedsPlanned": "Le porzioni mangiate e gli avanzi non possono superare il numero totale di porzioni."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Bekreft alle",
"scan.diff.noChanges": "Ingen forskjeller funnet.",
"scan.diff.undo": "Angre",
"scan.diff.undoHint": "Hver endring kan angres fra varedetaljvisningen."
"scan.diff.undoHint": "Hver endring kan angres fra varedetaljvisningen.",
"cooked.portionsSumExceedsPlanned": "Antall spiste porsjoner og rester kan ikke overstige det totale antallet porsjoner."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Alles bevestigen",
"scan.diff.noChanges": "Geen verschillen gevonden.",
"scan.diff.undo": "Ongedaan maken",
"scan.diff.undoHint": "Elke wijziging kan ongedaan worden gemaakt vanuit de detailweergave."
"scan.diff.undoHint": "Elke wijziging kan ongedaan worden gemaakt vanuit de detailweergave.",
"cooked.portionsSumExceedsPlanned": "Gegeten porties en restjes mogen het totaal aantal porties niet overschrijden."
}
+2 -1
View File
@@ -396,5 +396,6 @@
"scan.diff.acceptAll": "Potwierdź wszystko",
"scan.diff.noChanges": "Nie znaleziono różnic.",
"scan.diff.undo": "Cofnij",
"scan.diff.undoHint": "Każdą zmianę można cofnąć z widoku szczegółów produktu."
"scan.diff.undoHint": "Każdą zmianę można cofnąć z widoku szczegółów produktu.",
"cooked.portionsSumExceedsPlanned": "Zjedzone porcje i resztki nie mogą przekroczyć całkowitej liczby porcji."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Confirmar tudo",
"scan.diff.noChanges": "Nenhuma diferença encontrada.",
"scan.diff.undo": "Desfazer",
"scan.diff.undoHint": "Cada alteração pode ser desfeita a partir da vista de detalhes do item."
"scan.diff.undoHint": "Cada alteração pode ser desfeita a partir da vista de detalhes do item.",
"cooked.portionsSumExceedsPlanned": "As porções comidas e as sobras não podem ultrapassar o número total de porções."
}
+2 -1
View File
@@ -382,5 +382,6 @@
"scan.diff.acceptAll": "Bekräfta alla",
"scan.diff.noChanges": "Inga skillnader hittades.",
"scan.diff.undo": "Ångra",
"scan.diff.undoHint": "Varje ändring kan ångras från varans detaljvy."
"scan.diff.undoHint": "Varje ändring kan ångras från varans detaljvy.",
"cooked.portionsSumExceedsPlanned": "Antalet ätna portioner och rester får inte överstiga det totala antalet portioner."
}