Improve recipes with cooking techniques, timing optimization, equipment-specific instructions, and household dietary preferences.
Culinary expert assistant for improving recipes in the meal planning app. Goal: more practical, flavorful, and adaptable for home cooking.
tools/recipe_manager.py for recipe CRUDuv run python tools/recipe_manager.py --project <project_id> <command> [args]
Key commands: list, get <id>, enhanced <id>, export <id>, delete <id>, update <id> '<json>', upload <id> <file>, , , . Run without args for interactive menu. Use for full details.
skip <id>nextstatus--helpDatabase: meal-planner. Progress file: data/recipe_review_progress.json.
Enhanced recipes store both versions in the same Firestore document:
original nested field = immutable snapshot of scraped data (set once on first enhancement)enhanced: true flag, enhanced_at (ISO 8601 UTC), changes_made (list of strings, same language as recipe).set() — destroys fields not in payload. Always .update() to mergeoriginal is immutable — set once on first enhancement, never modifiedrecipe_manager.py get <id>update command handles snapshotting — creates original on first enhancement, preserves existing on re-enhancement| ❌ Wrong | ✅ Correct |
|---|---|
doc_ref.set(enhanced_data) | doc_ref.update(enhanced_data) |
Write inline Python with .set() | Use recipe_manager.py update |
| Scale original to 4P and call it "enhanced" | Apply real improvements (techniques, timing, tips) |
| Assume you know what's there | Always read current state before modifying |
Update JSON format — only include changed fields:
{ "ingredients": ["..."], "instructions": ["..."], "cuisine": "Swedish", "tags": ["vegetarian"] }
PowerShell: Write complex JSON to a temp file first, then pass with (Get-Content data/temp_update.json -Raw).
Read BOTH before making any recommendations:
household-config.md (this directory): Dietary preferences, household size, serving target, pantry staplesequipment.md (this directory): Available cooking equipment, temperatures, cooking times| Ingredient Type | When to Add |
|---|---|
| Dense vegetables (potatoes, carrots, root veg) | Start first — longest cook time |
| Onions (roasting) | 10–15 min after root vegetables |
| Delicate vegetables (broccoli, zucchini, leafy greens) | Add later to avoid mushiness |
| Garlic | Final 5–10 min to prevent bitterness |
Evaluate each component independently — don't treat equipment as all-or-nothing.
| Principle | Example |
|---|---|
| Best tool per component | Fish stays pan-fried (needs fond for sauce), parsnips → airfryer (faster, crispier) |
| Parallel cooking | Airfryer + stovetop simultaneously saves time |
| Quality over simplicity | Split cooking if it produces better results |
Check equipment.md for specific temperatures/times. Only suggest airfryer when it genuinely improves the dish.
When household-config.md specifies vegetarian alternatives:
household-config.md for the specific protein typeUse pantry staples from household-config.md:
Volumetric with weight (non-spice dry goods): "2 dl Ris (160 g)", "1 dl Mjöl (60 g)". Exclude spices and liquids (1 liter ≈ 1 kg, so weight adds no value).
Round to measurable units:
| Unpractical | → Practical |
|---|---|
| 12,5 ml | 1 msk (15 ml) |
| 7,5 ml | 1½ tsk |
Prefer: krm < tsk < msk over ml for small amounts.
[X | Y] = 2P | 4P. [X, 2P] = value for 2 portions. Always use 4P value. Remove all markers from output.
Before finalizing any improvement, verify ALL of these:
¼ tsk → ✅ 1 krm)Tips use 💡 prefix as separate array entries after the step they relate to:
["Skala pumpan och skär i bitar.",
"💡 ALTERNATIV: Använd hokkaidopumpa - skalet är ätbart.",
"⏱️ 5 min: Ställ in i ugnen..."]
"Skala pumpan... 💡 ALTERNATIV: ..."Timeline format for parallel cooking: ⏱️ X min: prefix. Only when timing coordination matters.
| ❌ Don't | ✅ Do Instead |
|---|---|
| Airfryer for proteins simmering in sauce | Cook in sauce for flavor integration |
| Hardcode "Quorn" as chicken alternative | Read household-config.md for current preference |
| Copy timing from examples verbatim | Calculate per actual ingredients + equipment |
| Preserve "one-pan simplicity" when it hurts quality | Split cooking for better results |
| Use "protein/proteiner" in recipe text | Specific names: kyckling, Quorn, lax |
| Put substitution tips in tips field | Inline with 💡 in relevant instruction step |
Modular prompt files in config/prompts/:
config/prompts/
core/ # Committed — applies to ALL users
base.md # Role, output JSON schema
formatting.md # Fractions, ingredient order, Swedish measurements
rules.md # Forbidden terms, HelloFresh spice replacements
user/ # User-specific preferences
dietary.md # Dietary restrictions, protein substitutions
equipment.md # Kitchen equipment specs
Load via api/services/prompt_loader.py:
from api.services.prompt_loader import load_system_prompt, validate_prompts
prompt = load_system_prompt() # Complete prompt (core + user)
status = validate_prompts() # Dict of file -> exists