diff --git a/docs/launch-readiness.md b/docs/launch-readiness.md index d75aa489..f1a79eff 100644 --- a/docs/launch-readiness.md +++ b/docs/launch-readiness.md @@ -50,6 +50,16 @@ Phases (status snapshot 2026-05-27): PDF; server-side PDF endpoint for branded output. _See gaps below._ 3. ❌ Marketing report — NOT BUILT. Pending Init 1b cutover. + **Beta gate (2026-06-02):** the `marketing` kind in + `reports/[kind]/page.tsx` now returns `notFound()` (via + `UNAVAILABLE_NEW_KINDS`) instead of the "in development" placeholder, + so the beta reports surface reads as complete — the landing page only + advertises Sales / Operational / Financial / Custom, and the + hand-typed `/reports/marketing` URL 404s. **Remove the + `UNAVAILABLE_NEW_KINDS` entry when this report ships.** Decision: keep + the reports page live for beta rather than hiding it behind a module + toggle — 3 of 4 reports are fully built + verified (export, templates, + scheduling) and strictly beat the dashboard-only fallback. 4. ✅ Financial report — **SHIPPED in b690fb8d.** Built on the canonical payments + expenses tables (invoices module stays OFF); the invoice-centric spec was reframed onto the payments model diff --git a/src/app/(dashboard)/[portSlug]/reports/[kind]/page.tsx b/src/app/(dashboard)/[portSlug]/reports/[kind]/page.tsx index 5588a6c7..85baa125 100644 --- a/src/app/(dashboard)/[portSlug]/reports/[kind]/page.tsx +++ b/src/app/(dashboard)/[portSlug]/reports/[kind]/page.tsx @@ -27,6 +27,18 @@ const NEW_KINDS = ['sales', 'financial', 'marketing', 'operational', 'custom'] a type LegacyKind = (typeof LEGACY_KINDS)[number]; type NewKind = (typeof NEW_KINDS)[number]; +/** + * NEW_KINDS that have a card on the /reports landing page each own a + * dedicated route (reports/sales, reports/operational, reports/financial, + * reports/custom) which shadows this dynamic segment. The only NEW_KIND that + * still resolves here is `marketing`, whose builder is blocked on the website + * cutover (launch-readiness Initiative 1b) and currently renders only an "in + * development" placeholder. Gate it to a 404 for beta so it can't be reached + * via a hand-typed URL or a stale saved template. Remove the entry when the + * Marketing report ships. + */ +const UNAVAILABLE_NEW_KINDS: readonly NewKind[] = ['marketing']; + interface PageProps { params: Promise<{ portSlug: string; kind: string }>; searchParams: Promise<{ from?: string; to?: string }>; @@ -74,6 +86,11 @@ export default async function ReportBuilderPage({ params, searchParams }: PagePr const isNew = (NEW_KINDS as readonly string[]).includes(kind); if (!isLegacy && !isNew) notFound(); + // Unbuilt report kinds (currently just Marketing) 404 rather than show the + // "in development" placeholder — keeps the beta reports surface looking + // complete. See UNAVAILABLE_NEW_KINDS above. + if ((UNAVAILABLE_NEW_KINDS as readonly string[]).includes(kind)) notFound(); + if (isLegacy) { const typedKind = kind as LegacyKind; const labels = LEGACY_LABELS[typedKind];