Commit Graph

7 Commits

Author SHA1 Message Date
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 5ff8ef5547 fix(deploy): bake NEXT_PUBLIC_* vars in at build time, not runtime
NEXT_PUBLIC_VAPID_PUBLIC_KEY (and the OAuth *_ENABLED flags) are inlined
into the client bundle by next build — setting them as container env vars
at runtime does nothing, since the client JS was already built without
them. Client bundle shipped with applicationServerKey: undefined, so
pushManager.subscribe() threw and the button always failed with "Failed
to enable notifications."

Wire them as Docker build args (Dockerfile ARG/ENV before `next build`,
compose.prod.yml build.args), sourced from the same stack env vars used
at runtime so they stay in sync.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-02 07:24:18 +02:00
Arnaud fbae04f824 fix(deploy): forward SMTP/OAuth/AI env vars to web container
compose.prod.yml only whitelisted DB/redis/storage/auth/VAPID/Google/
OpenRouter vars in web.environment — Portainer stack env alone doesn't
reach the container unless the compose file declares the ${VAR} ref, so
SMTP_HOST etc were set in Portainer but silently ignored. Add the full
set from .env.example (SMTP, GitHub/Discord/Authentik OAuth + their
NEXT_PUBLIC_*_ENABLED flags, Stripe, remaining AI provider keys).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-02 07:17:11 +02:00
Arnaud 7e93c332ce fix: add missing OAuth i18n keys, remap dev redis off port 6379
login page referenced auth.continueWithGithub/Discord/Authentik keys that
didn't exist in en/fr message files, crashing the login page. Also remap
docker/compose.yml redis to 6380 since 6379 collides with an unrelated
local container on this machine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 16:29:28 +02:00
Arnaud a4fb62c86c feat(deploy): auto-run db migrations + seed on stack deploy
Add a migrator Dockerfile target (drizzle-kit migrate + tier-definitions
seed, both idempotent) and wire it as a one-shot compose service that web
waits on via service_completed_successfully. No more manual exec step
after first deploy — runs safely on every redeploy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 16:23:54 +02:00
Arnaud 4a90ad910c feat(deploy): dockerize web app for portainer git-stack deploy behind external traefik
Add root Dockerfile (standalone Next output, multi-stage pnpm build), drop
in-stack caddy in favor of publishing web's port for an external traefik
LXC (file-provider dynamic config included), and document the portainer
deploy flow.

Also fixes issues that blocked any production build: a bad auth-client
type cast, the ai SDK's mimeType->mediaType rename, an implicit-any
callback param, and push.ts eagerly calling webpush.setVapidDetails at
module import time (which crashed page-data collection whenever VAPID
env vars weren't present at build) — now lazily configured on first send.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-01 16:20:34 +02:00
Arnaud ae7c5d943e chore: init pnpm monorepo workspace
Root config: pnpm workspaces, tsconfig base, docker compose (postgres, redis, minio), .npmrc.
2026-07-01 08:08:29 +02:00