Files
Epicure/WHATS_NEW_PLAN.md
T
Arnaud 2a256a8943 docs: scope the "What's New" in-app announcement feature
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.
2026-07-18 09:24:03 +02:00

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's lastSeenChangelogVersion against CHANGELOG (imported directly, no DB query needed for the content itself — it's a static in-code array), returns every entry with highlights whose 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 — sets lastSeenChangelogVersion to the current APP_VERSION for the calling user. Called when the panel opens (or on explicit dismiss — same UX choice NotificationBell's markAllRead already 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

  1. Schema migration (backfill existing users to current APP_VERSION) — no visible change yet.
  2. highlights field on ChangelogEntry + write it for the next few versions going forward, so there's something to show once the UI ships.
  3. API routes.
  4. WhatsNewBell component wired into nav.tsx.
  5. Retroactively add highlights to 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.