Parse @username in comment content, notify mentioned users (dedup
against recipe-author/parent-author who are already notified via
comment/reply), and render @username as a link to their profile.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Part of the social-feature backlog (follow, comments, reactions, ratings,
feed, threading) audited earlier — see conversation.
- notifications table: follow/comment/reply/reaction/rating events,
replaces the fully-dead feed_items table (feed_item_type enum existed
but had zero references anywhere in the codebase).
- Bell UI in the nav with unread badge, mark-all-read, 30s poll.
- Rate limiting on comment posting (20/min), follow/unfollow (30/min),
and comment reactions (60/min) — previously unthrottled.
- /recipes/[id] queried by (id, authorId=session.user) only, so any
recipe not owned by the viewer 404'd regardless of visibility.
Widen the query to include public/unlisted recipes and gate the
owner-only actions (edit, delete, version history, translate, AI
content generation) behind an isOwner check.
- user_follows had no primary key/unique constraint, so the follow
route's onConflictDoNothing() was a silent no-op — concurrent follow
clicks could insert duplicate rows and inflate follower counts. Add
a composite primary key on (follower_id, following_id).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Nav links were `hidden md:flex` with no mobile fallback — sub-768px
viewports showed only logo + avatar, no way to reach Explore, Feed,
Collections, etc. Add a Sheet-based hamburger menu with the same links.
Settings layout header ("Settings" / "Manage your account,
preferences, and integrations.") was hardcoded English, shown on
every settings sub-page.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pantry-page-header's Print button, the pantry-manager add/remove
form (item name, qty, unit, expiry badges), and the print/pantry
page (title, column headers, item count, empty state, footer) were
all hardcoded English.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mobile:
- Recipes search bar full-width on mobile instead of capped narrow
- Cook mode ingredients panel stacks above the step instead of
squeezing it into a narrow column
- Version history Compare/Restore buttons wrap onto their own row
- Recipe edit ingredient fields wrap instead of forcing horizontal
scroll on narrow viewports
i18n: translates remaining hardcoded strings across recipes
filter/sort, adapt-recipe and AI variations dialogs, the full
settings section (sidebar + 6 sub-pages + BYOK/model-prefs/
API-keys/webhooks managers), explore tab, collections (new/fork/
share dialogs), meal planning (planner, AI generation phases, new
shopping list, shared-plan view), photo import, recipe bulk-select
toolbar, and recipe action-button tooltips. Also fixes the recipes
page subtitle, which wasn't just unworded but missing its {count}
interpolation entirely — it always rendered as the bare word
"results" regardless of how many recipes existed.
Feature: adds a ShareRecipeButton that copies the public /r/{id}
link to the clipboard, with a notice when the recipe isn't Public
yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Implements the six previously-unscoped feature ideas plus a mobile
layout fix reported via screenshot:
- Mobile: Recipes/Collections/Pantry/Meal Plan/Shopping Lists headers
now stack and wrap instead of clipping buttons on narrow viewports.
- Recipe diff/compare view: word/list diff against any past version,
next to Restore in version history.
- Shared meal plans & shopping lists: new shoppingListMembers/
mealPlanMembers tables (viewer/editor roles, mirrors
collectionMembers), share dialogs, membership-checked routes.
- PDF cookbook export: /print/collection/[id] renders a whole
collection with page breaks, using the existing print-CSS pattern
instead of adding a PDF rendering dependency.
- Grocery delivery handoff: shopping lists can copy-as-text (works
today) or send to Instacart once INSTACART_API_KEY is configured
(stub adapter — real API needs a partner agreement).
- Personalized "For You" feed tab: ranks public recipes by tag/
dietary overlap with the user's favorited/highly-rated history.
- PWA: added manifest.json + icons on top of the existing service
worker so the app is installable; cook-mode pages were already
cached for offline use.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Recipe cards, the recipe detail page, and meal planner still rendered raw
"{n} servings"/"{n}m cook"/"{n} srv" text and untranslated difficulty labels
outside the earlier i18n pass. Also wires the user's locale into AI features
that previously always answered in English regardless of app language:
recipe chat, ingredient substitution, recipe ideas, and generate-from-idea.
The recipe-language picker in the AI generate dialog now defaults to the
user's locale instead of always defaulting to English.
Wires dozens of components and server pages to next-intl instead of hardcoded
English text, and adds a lightweight getMessages/formatMessage helper for
server components (print pages, public recipe page, cook metadata) since
next-intl/server isn't wired into this app's routing. Backfills missing
en/fr message keys that existing code already referenced but fr.json lacked.
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>