Commit Graph

4 Commits

Author SHA1 Message Date
Arnaud 9566e19cd0 fix: weekly meal-plan nutrition compared a week's total against a daily goal
userNutritionGoals are daily targets (the nutrition diary already compares
a single day's totals against them directly) — but the weekly meal-plan
route summed an entire week's entries and compared that raw total straight
against the same daily number, so coverage read roughly 7x too high.

Now computes a daily average (across days that actually have planned
meals) and compares that against the goal instead, adds a per-day
breakdown (byDay) for a future day-view, and tracks unknownCount for
entries whose recipe has no nutrition data yet, matching the diary route.

Also fixed a real bug this surfaced: meal-plan/page.tsx and print/meal-plan
parsed the ?week= date via new Date(dateStr) (UTC midnight) then read
.getDay() (local time) — in positive-UTC-offset timezones this resolves to
the wrong Monday, and the reverse (Date -> string via toISOString()) has
the same mismatch in the other direction. Both now do local y/m/d math
throughout.

Verified locally: correct daily-average math end to end (recipe entry +
batch-dish entry, which already attributed nutrition correctly via its
required parent recipeId — no separate fix needed there), and confirmed
the meal-plan page now resolves the right week and renders real coverage
bars against actual planned entries.
2026-07-12 18:35:58 +02:00
Arnaud 9c545a5bb3 feat: private accounts, explore/people merge, meal-plan fixes, i18n and theme cleanup
- Private accounts: users.isPrivate hides a user from search and their
  recipes from search/trending/for-you discovery surfaces (follow-aware
  where the route already has session context, blanket exclusion where it
  doesn't); existing followers and direct links are unaffected, no
  follow-request approval flow was built (explicit scope limit)
- Merged /people into the Explore tab (tab=people query param); the old
  standalone route now redirects there
- "Get Ideas" vs "Surprise Me" were doing the same empty-prompt call;
  Surprise Me now injects a real random constraint (5-ingredient, one-pot,
  etc.), matching the existing pattern in the AI recipe-generate dialog
- Meal-plan day cells now link to their recipe (was dead text) and gained
  a one-click "mark as cooked" action
- Theme toggle is now a real three-way light/dark/system control instead
  of a binary flip
- Nutrition goals form had zero i18n wiring; fully localized now

New migration 0027 (users.is_private) generated, left unapplied like the
others. Verified with typecheck, lint, and a clean --no-cache docker build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 09:26:03 +02:00
Arnaud b0849c3989 feat: cooking history/gallery, unit conversion, nutrition diary, pantry scan, digest cron, nutrition-targeted meal plans
Six M-sized items from HANDOFF.md's new-features backlog:

- Profile tabs: cooking-history stats (total cooked, last-cooked, streak)
  and a "cooked it" photo gallery, both owner-only
- Display-time unit conversion (metric<->imperial) for recipe ingredients,
  respecting each user's unitPref; original value always shown alongside
  the conversion
- Nutrition daily diary: per-day macro totals computed from cooking history
  x recipe nutritionData, compared against user goals
- Pantry scan: real barcode lookup (zxing + Open Food Facts, no API key)
  with an AI-vision fallback for unbarcoded items, always confirm-before-
  insert, both paths tier/rate-limited like other AI features
- Weekly digest email: new followers/comments/ratings + trending recipes,
  sent via a new `cron` Docker stage (alpine+crond+curl) and `digest-cron`
  compose service hitting a bearer-token-protected internal route
- Meal-plan generation can now target a user's nutrition goals as a
  prompt-level nudge (recipes are AI-invented, not DB-sourced, so this
  can't be a hard macro constraint)

Caught a real deploy-breaking issue while adding the cron stage: appending
it after `runner` silently changed the Dockerfile's default build target,
and `web`'s compose config didn't pin one — fixed by pinning `target:
runner` explicitly. Verified with typecheck, lint, and three separate
`docker build --target` runs (runner/cron/migrator) plus `docker compose
config` validation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 08:06:28 +02:00
Arnaud 3636ab27ae feat(meal-plan): weekly planner, pantry, shopping lists, nutrition tracking
AI-generated weekly meal plans with pantry-awareness. Manual entry per slot.
Pantry inventory management. Auto-generated shopping lists from meal plan.
Weekly nutrition bar chart vs daily goals. Nutrition goals settings.
2026-07-01 08:10:39 +02:00