Public changelog page with admin CRUD. Multi-locale JSONB content following the CMS pattern. Toggle via appConfig.features.changelog.
Public Page
Timeline layout at /changelog. Version badges, color-coded type badges. Markdown rendering. ISR (1h). JSON-LD structured data.
Admin CRUD
/admin-dashboard/changelog — create, edit, publish/unpublish, delete. Locale tabs for title + content.
Entry Types
Feature (violet), Improvement (blue), Fix (green), Breaking (red), Security (orange). DB-level check constraint.
Security
Markdown sanitized before storage (strips scripts, iframes, event handlers). Admin-only RLS with WITH CHECK. UUID validation on all params.
| API Route | Method | Description |
|---|---|---|
/api/admin/changelog | GET | List all entries (including drafts) |
/api/admin/changelog | POST | Create entry |
/api/admin/changelog | PATCH | Update entry |
/api/admin/changelog | DELETE | Delete entry |
Documentation release snapshots
The documentation has two layers: content/docs/current/ is the editable preview served at /docs/next, while every validated release is preserved under content/docs/versions/<version>/ and served from /docs/<version>.
A version is validated when changelog.md contains a dated ## [version] - YYYY-MM-DD heading. The same change must run pnpm run docs:version:create -- <version>. CI rejects a release heading without its immutable documentation snapshot.
pnpm run docs:version:create -- 2.0
pnpm run docs:versions:check
The creation command snapshots MDX content, navigation, and onboarding metadata, updates the latest-version registry, and refuses to overwrite an existing release. Former unversioned /docs/... URLs remain temporary aliases to the latest validated version.