Extends ChangelogEntry with an optional highlights field (editorial, per-version, plain language -- most versions won't have one) instead of forking a second content source. One new users column (lastSeenChangelogVersion, backfilled to current APP_VERSION on migration so existing users aren't flooded with history), two routes, one component mirroring NotificationBell's existing bell/badge/dropdown shape.
4.3 KiB
"What's New" Plan
Status: planning only — nothing in this doc is implemented yet
The problem this solves: apps/web/lib/changelog.ts's CHANGELOG array is
a dev log — migration reminders, bug-fix jargon, internal notes ("not
applied in sandbox") mixed in with real feature announcements. Correctly
not public (per VITRINE_PLAN.md §6, which flagged this gap). Users have
no clean way to see what's new since they last looked.
Existing precedent to mirror, not reinvent: apps/web/components/social/notification-bell.tsx
is exactly this UI shape already — bell icon, unread badge, dropdown list,
polling GET on an interval, a "mark read" POST. Same skeleton, new data
source.
1. Content — extend ChangelogEntry, don't fork a second data source
Add one optional field to the existing type in apps/web/lib/changelog.ts:
export type ChangelogEntry = {
version: string;
date: string;
added?: string[];
fixed?: string[];
security?: string[];
notes?: string;
highlights?: string[]; // user-facing, plain language — only set on entries worth telling users about
};
Only versions with highlights populated ever show up in the "What's New"
panel — everything else in CHANGELOG stays exactly as dev-facing as it is
today. This is a deliberate editorial step, not automatic: when a version
ships something a real user would care about, someone (you) writes one or
two highlights lines in plain language, same commit as the added/fixed
entries. Retroactively, only add highlights to past entries actually worth
surfacing — no need to backfill all 47+ versions, most were internal
fixes/refactors nobody needs a notification about.
2. Schema
One column, apps/web/packages/db/src/schema/users.ts:
lastSeenChangelogVersion: text("last_seen_changelog_version"),
Nullable. On the migration, backfill existing users to the current
APP_VERSION at migration time (not null) — otherwise every existing
user sees the entire history of highlights entries as "new" the moment
this ships, which is noise, not a useful announcement. New signups after
this ships get set to APP_VERSION at account-creation time for the same
reason — someone who just joined doesn't need to be told about features
that existed before they showed up.
3. API
GET /api/v1/whats-new— compares the user'slastSeenChangelogVersionagainstCHANGELOG(imported directly, no DB query needed for the content itself — it's a static in-code array), returns every entry withhighlightswhose version is newer (semver comparison, not string comparison —"0.9.0" < "0.10.0"is false under plain string compare). A tiny local semver-compare helper is enough; no need for a package for a 3-segment version string this app already controls end to end.POST /api/v1/whats-new/seen— setslastSeenChangelogVersionto the currentAPP_VERSIONfor the calling user. Called when the panel opens (or on explicit dismiss — same UX choiceNotificationBell'smarkAllReadalready made for regular notifications, mirror whichever this app's notifications settled on).
Both gated by requireSessionOrApiKey, same as every other authenticated
route — no new auth pattern needed.
4. UI
New component apps/web/components/layout/whats-new-bell.tsx, structurally
identical to NotificationBell: bell/gift icon, badge showing count of
unseen highlighted versions, dropdown listing them (version, date, bullet
list of that version's highlights), placed in apps/web/components/layout/nav.tsx
next to the existing NotificationBell/MessagesNavLink icons in the
authenticated header.
Not a public/vitrine concern — this lives entirely inside the authenticated
app shell, unrelated to VITRINE_PLAN.md's route group.
5. Rollout order
- Schema migration (backfill existing users to current
APP_VERSION) — no visible change yet. highlightsfield onChangelogEntry+ write it for the next few versions going forward, so there's something to show once the UI ships.- API routes.
WhatsNewBellcomponent wired intonav.tsx.- Retroactively add
highlightsto a handful of past standout versions (the tier system, the cooking-assistant tools, followers-only visibility) if you want new/returning users to see a bit of history on first exposure, not just what ships after this point.