Frigo Adaptatif
Cook what you already have, throw less away, decide without thinking about it — running in production at fridge.jjoly.eu
the problem
Households throw away a substantial share of what they buy, simply because they don't know what is sitting at the back of the fridge or what expires next. Recipe apps suggest dishes you cannot actually make with what you have, ignore use-by dates, and expect everything to be typed in by hand without ever learning from habits.
the solution
A self-hosted kitchen assistant that starts from the real contents of the fridge and reasons about them: what to cook today, what to buy, what to rescue before it spoils. All the decision logic runs locally, with no AI; AI is an optional, clearly signposted bonus.
- Multi-input inventory: barcode scanning (Open Food Facts), manual entry, or a photo of the fridge or till receipt read by AI — with quantities and use-by dates.
- Suggestions per meal type (breakfast, lunch, dinner, dessert, snacks), ranked by what is genuinely cookable right now and what rescues an ingredient close to its date.
- Fully local meal planning: automatic generation over a period based on habits, or manual slot-by-slot composition; batch cooking ("cooked once, eaten twice"), handling of real life (skipped meals, late shopping, forgotten leftovers) with automatic readjustment.
- Waste anticipation: a consumption model that projects run-out dates, plus a monthly waste-reduction score.
- Diners & constraints: per-member profiles (diet, allergies, disliked foods), filtering of both suggestions and plan, adjustable number of servings per meal.
- Budget & seasonality: estimated cost of recipes and shopping lists, an "in season" badge and a scoring bonus by month.
- Proactive rituals via push notification: Sunday review, evening check, morning expiry alert.
the stance: science in the background, never on screen
Every suggestion carries a why — never a generic tip. Plan generation never goes through a language model: it is a deterministic scoring engine (ingredient coverage, waste avoidance, habits, variety, recency) that stays explainable and reproducible. When AI is enabled, it only handles isolated creative tasks (emptying the fridge, substituting an ingredient, step-by-step cooking guidance, reading a photo), and its failure is handled cleanly — never blocking the app, never leaking a technical detail.
technical choices
- Single-binary Go backend (~200 MB of RAM) with SQLite in pure Go (CGO disabled), distroless Docker image, framework-free frontend.
- Installable PWA: manifest, service worker, offline reading,
Web Push notifications (VAPID) — mobile-first and accessible (real buttons,
aria-labels, managed focus, touch target sizes,
prefers-reduced-motion). - Data sovereignty: fully self-hosted, GDPR compliance by design (explicit consent, articles 15-22 rights, audit log with 12-month rotation), zero trackers.
- Security: households by invitation only, TOTP 2FA on by default, AES-GCM encrypted integration tokens, AI key held server-side (SOPS/age secret) and never in the browser.
- Abstracted, configurable AI: Anthropic or OpenAI selected by environment variable, and fully disableable.
a problem worth telling
SQLite in a single file means a single writer. That constraint propagates all
the way up: one connection, one replica, and a Recreate deployment
strategy — so a few seconds of downtime on every update. The obvious fix would
have corrupted the database. The full diagnosis, including the hour I spent on
the wrong lead, is written up in
this note
(in French).
in production
deployment k3s + Flux CD (GitOps) — see the infrastructure case study
pipeline push to main → tests → build → Trivy scan → GHCR → staging
tag vX.Y.Z → production (rollback = git revert)
data one SQLite database per household, encrypted backups, WAL
status V3 deployed — freezer zones, recipe import, leftovers as
first-class inventory, real spending, precision nutrition,
predictive shopping, menu optimiser, PDF reports, event mode
The version actually running is shown, and dated, on the home page.