v0.4.0 (2026-09-05)
Theme: Admin operations loop + data-layer testing + integration wiring
v0.4.0 focuses on three things: completing the admin backend into a day-to-day operations loop (contact messages, aggregate dashboard, webhook logs), filling in data-access-layer and API test coverage, and extending notifications beyond the in-app center to an email channel.
Highlights
Two-Factor Authentication (TOTP/MFA)
- Full flow: QR-code enrollment at setup → code confirmation → removable later.
- Login challenge page
/auth/mfa: users with a verified TOTP factor are forced through aal2 verification at sign-in. - Backup recovery codes: generation and redemption, covered by unit tests on both ends.
Notifications & Email Worker
- New notification types (deployment / security_alert, etc.); server-side events such as invites, role changes, and successful payments create notifications for other users.
- Email preference matrix: a master switch (
emailNotifications) plus per-type switches. Only the email channel is affected; the in-app notification center always shows everything. - Email worker: an external cron calls
POST /api/cron/digest(authenticated viaCRON_SECRET), which pulls pending notifications, sends them through Resend, and marks them viamarkEmailSent. A user's notifications are merged into a single digest email; failed batches are retried automatically on the next cron run (seedocs/design/email-templates.md). - Sidebar unread badge polling, mark-one/mark-all as read, error state and empty-state guidance.
Contact Message Operations Loop
contact_messagestable (migration 012) + processing state machine (migration 015, one-way transitions).- Admin inbox: search, status filter, pagination; heuristic spam rejection.
- Structured data added to the contact page (SEO).
Admin Enhancements
- Aggregate dashboard now includes contact-message and webhook-event statistics.
- Server-side pagination for the user list, webhook payload viewer, audit metadata details viewer.
Sign-in Security
- Tiered lockout on failed logins (sliding window: 5 attempts / 15 minutes per email).
- Login audit log (success/failure/MFA/redemption/OAuth).
- Resend-confirmation-email entry point when the email is unverified.
Also in this release
- Data retention policy (migration 014): pg_cron guard scheduling + webhook event cleanup function.
- API quality convergence: unified
jsonNoStoreerror format, log trace-id, health DB self-check, checkout idempotency / duplicate-subscription guard, Sentry alert for unknown webhook event types. - ⌘K command palette, breadcrumb navigation, QueryErrorState retry states, unified EmptyState, offline banner, route progress bar, monthly/annual pricing toggle.
- SEO: dynamic blog OG images, RSS feed, PWA manifest, real sitemap lastmod.
Changed
- TanStack Table v9 native migration: legacy bridge removed in favor of explicit features + row-model slots (ADR-009); DataTable fully internationalized (751 translation keys).
- Bundle baseline 2467kB → 2603kB (feature growth, no new dependencies).
- Hard-coded routes consolidated into
ROUTESconstants.
Fixed
- Admin guard added to the webhook events action (prevents privilege bypass).
- Annual-savings amount rounded to fix floating-point precision; breadcrumb namespace missing keys.
- Recovery-code build issues (
use serverexport restrictions, dynamic node:crypto import). - Migration 011 adds a functional index on profiles
lower(email)(Seq Scan found in EXPLAIN review).
Testing
- Full unit-test coverage across 7 repository modules; API routes and actions tests filled in.
- Edge cases: safe-redirect fuzzing, date boundaries, CSV injection variants.
- E2E assertions for a11y and trace-id / CSP nonce.
See CHANGELOG.md in the repo root for the complete list.