- Substitute finder never applied the user's BYOK/admin AI key (only fell
back to raw process.env), so it silently failed whenever the key was
stored via settings rather than a literal env var. Now resolves via
getDefaultProviderWithKey like every other AI route. Popover also
surfaces real error messages instead of swallowing failures.
- Ingredients with quantity 0 (salt, pepper, "to taste") rendered the
literal digit "0" in cooking mode, print view, public recipe page,
shopping lists, and serving scaler — several sites relied on generic
truthiness/filter(Boolean), which doesn't catch a stored "0" string.
Added a shared hasQuantity() helper and applied it everywhere quantity
is rendered, plus in the AI recipe-chat context sent to the model.
- Recipe chat panel rendered a duplicate close button on top of shadcn
Sheet's own built-in close X, producing a garbled overlapping glyph.
Removed the duplicate.
- Recipe chat assistant replies are markdown from the model but were
rendered as raw text; added react-markdown so formatting actually
renders.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>
Sticky sidebar with back-to-app link. Overview: user counts, recipe photos, AI calls/month.
User management with role/tier editing. Audit log (all admin actions).
Storage page with photo breakdown by tier. AI config showing DB vs .env key source.
Site settings page to override .env values at runtime (encrypted in DB).
Follow/unfollow users. Recipe favorites. Threaded comments with emoji reactions.
Collections (public/private) with shared member invite. Activity feed.
Public profile pages at /u/[username].