- Generate recipes in English (reverted prompt to English-only)
- Add TranslateRecipes to OpenAI client (translate.go) — sends compact
JSON payload of translatable fields, merges back into original recipes
- recommendation/handler.go: translate recipes in-memory before response
when lang != "en"; falls back to English on error
- dish/repository.go: Create() now returns (dishID, recipeID, err) so
callers can upsert dish_translations after saving
- menu/handler.go: saveRecipes returns savedRecipeEntry slice with dishID;
saveDishTranslations calls TranslateRecipes then UpsertTranslation for
each dish when the request locale is not English
- savedrecipe/repository.go: updated to ignore dishID from Create()
- init.go: wire openaiClient as RecipeTranslator and dishRepository as
DishTranslator for menu.NewHandler
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Inserts a new PlanProductsSheet as step 1 of the planning flow.
Users see their current products as a multi-select checklist (all
selected by default) before choosing the planning mode and dates.
- Empty state explains the benefit and offers "Add products" CTA
while always allowing "Plan without products" to skip
- Selected product IDs flow through PlanMenuSheet →
PlanDatePickerSheet → MenuService.generateForDates → backend
- Backend: added ProductIDs field to generate-menu request body;
uses ListForPromptByIDs when set, ListForPrompt otherwise
- Backend: added Repository.ListForPromptByIDs (filtered SQL query)
- All 12 ARB locale files updated with planProducts* keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend fixes:
- migration 003: add 'menu' value to recipe_source enum (was causing SQLSTATE 22P02)
- migration 004: rename recipe_products→recipe_ingredients, product_id→ingredient_id (was causing SQLSTATE 42P01)
- dish/repository.go: fix INSERT INTO tags using $1/$1 for two columns → $1/$2 (was causing SQLSTATE 42P08)
- home/handler.go: replace non-existent saved_recipes table with correct joins (recipes→dishes→dish_translations, user_saved_recipes) so today's plan and recommendations load correctly
- reqlog: new slog.Handler wrapper that adds request_id and stack trace to ERROR-level logs
- all handlers: slog.Error→slog.ErrorContext so error logs include request context; writeError includes request_id in response body
Client:
- home_screen.dart: extend home screen to future dates, show planned meals as ghost entries
- l10n: add new localisation keys for home screen date navigation and planned meal UI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>