feat(reports): gate unbuilt Marketing report to 404 for beta
Sales/Operational/Financial are built + verified; Marketing is blocked on the website cutover (launch-readiness Init 1b), not on code. Rather than hide the whole reports surface behind a module toggle, keep it live for beta and 404 the one unbuilt kind so a hand-typed /reports/marketing URL can't reach the "in development" placeholder. The landing page already advertises only the three live reports + Custom. Remove the UNAVAILABLE_NEW_KINDS entry when the Marketing report ships. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user