Overhaul of the backend AI module to produce better recipes, better
images, more reliably, and cheaper.
New src/ai/ module:
- prompts.ts: long 'Chef Antoine' system prompt (~1500 tokens) with
explicit originality rules, technical precision requirements, vocal
transcription handling, and 3 few-shot style examples. Long enough
to benefit from OpenAI's automatic prompt caching (-50% on cached
portion from the 2nd call onward).
- recipe-generator.ts: uses Structured Outputs (json_schema strict).
Rich schema: titre, description, origine_inspiration, ingredients
with quantity/notes/complement flag, numbered etapes with per-step
duration, conseils array, accord_boisson. No more JSON.parse crashes.
- image-generator.ts: switched from dall-e-3 to gpt-image-1 (medium
quality by default). Much better photographic realism. Dedicated
magazine-style prompt (editorial food photography, 45-deg overhead,
natural light, stoneware). Slugify preserves extended Latin chars
(cote-de-boeuf not c-te-de-b-uf).
- transcriber.ts: migrated from whisper-1 to gpt-4o-mini-transcribe
(50% cheaper, better on French). Includes a context prompt to bias
toward culinary vocabulary.
- cost.ts: centralized pricing table + helpers. Every OpenAI call now
emits a structured log with model, durationMs, costUsd, usage, and
cacheHit flag.
Plugin refactor:
- plugins/ai.ts now delegates to src/ai/* and only keeps the Fastify
decoration glue + storage fallback for audio.
- OpenAI client configured with maxRetries=3, timeout=60s.
- Image generation runs in parallel with the recipe flatten/serialize
step (minor speedup, ~0.5s).
- flattenRecipe() converts the rich structured recipe into the legacy
flat RecipeData shape (for Prisma columns) while preserving the
structured form in recipeData.structured.
Routes:
- recipes.ts stores the structured JSON in generatedRecipe (instead
of the aplatissement lossy), enabling future frontends to render
rich recipes with per-ingredient notes and step timers.
Env vars:
- OPENAI_TRANSCRIBE_MODEL, OPENAI_IMAGE_MODEL, OPENAI_IMAGE_QUALITY,
OPENAI_IMAGE_SIZE, OPENAI_MAX_RETRIES, OPENAI_TIMEOUT_MS
Cost per recipe (estimated):
- Before: ~$0.044 (whisper $0.003 + 4o-mini $0.0004 + dall-e-3 $0.04)
- After : ~$0.018 (4o-mini-transcribe $0.0015 + 4o-mini $0.0004
+ gpt-image-1 medium $0.0165), ~-59%.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>