From 4aee2cb44523cce52243e89fdcc994723ab9ef7a Mon Sep 17 00:00:00 2001 From: Christopher Sellers <1@christophersellers.com> Date: Fri, 23 Oct 2026 22:21:51 -0700 Subject: [PATCH] fix(fsma-204): repoint CTE 'See it in action' CTA to /ingest; drop dead /sandbox leftovers - fsma-204/[cte]: use sandboxCta() (Upload your CSV -> /ingest), drop sandbox wording - routes.json / ROUTE_CROSSCHECK.md: remove retired /sandbox and /sandbox/results/[id] - marketing-analytics-routes: drop /sandbox/results sensitive prefix (+ test asserts) - eslint.config.mjs: drop comment referencing deleted SharedSandboxResult.tsx Signed-off-by: Christopher Sellers <1@christophersellers.com> --- frontend/eslint.config.mjs | 5 ++--- .../lib/marketing-analytics-routes.test.ts | 4 +--- frontend/src/app/fsma-204/[cte]/page.tsx | 14 +++++++------- frontend/src/lib/marketing-analytics-routes.ts | 2 +- frontend/tests/visual/ROUTE_CROSSCHECK.md | 4 ++-- frontend/tests/visual/routes.json | 2 +- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/frontend/eslint.config.mjs b/frontend/eslint.config.mjs index 8c283825c..0cda2a52e 100644 --- a/frontend/eslint.config.mjs +++ b/frontend/eslint.config.mjs @@ -40,9 +40,8 @@ export default [ 'react-hooks/immutability': 'error', 'react-hooks/refs': 'error', - // Pre-existing tags in src/app/sandbox/results/[id]/SharedSandboxResult.tsx - // pointing at /#sandbox. Downgraded to warn to unblock CI; a - // separate PR should migrate to next/link. + // Downgraded to warn to unblock CI; a separate PR should + // migrate any remaining internal tags to next/link. '@next/next/no-html-link-for-pages': 'warn', }, }, diff --git a/frontend/src/__tests__/lib/marketing-analytics-routes.test.ts b/frontend/src/__tests__/lib/marketing-analytics-routes.test.ts index e6849aff0..ff83cea14 100644 --- a/frontend/src/__tests__/lib/marketing-analytics-routes.test.ts +++ b/frontend/src/__tests__/lib/marketing-analytics-routes.test.ts @@ -36,11 +36,9 @@ describe('marketing pageview routes', () => { expect(shouldTrackMarketingPageview('/tools/person%40example.com')).toBe(false); }); - it('omits public result and portal paths whose segments identify a user or record', () => { + it('omits portal paths whose segments identify a user or record', () => { document.cookie = 're_cookie_consent=accepted; path=/'; - expect(safeMarketingPath('/sandbox/results/result-123')).toBeNull(); expect(safeMarketingPath('/portal/portal-123')).toBeNull(); - expect(shouldTrackMarketingPageview('/sandbox/results/result-123')).toBe(false); expect(shouldTrackMarketingPageview('/portal/portal-123')).toBe(false); }); diff --git a/frontend/src/app/fsma-204/[cte]/page.tsx b/frontend/src/app/fsma-204/[cte]/page.tsx index b978c6ad8..a1a886aea 100644 --- a/frontend/src/app/fsma-204/[cte]/page.tsx +++ b/frontend/src/app/fsma-204/[cte]/page.tsx @@ -18,6 +18,7 @@ import { import { Container } from "@/components/layout/container"; import { PageHeader } from "@/components/layout/page-header"; import { Section } from "@/components/layout/section"; +import { sandboxCta } from "@/lib/sandbox-cta"; import { Button } from "@/components/ui/button"; import { Callout } from "@/components/ui/callout"; import { Card } from "@/components/ui/card"; @@ -318,6 +319,7 @@ export default async function CTELandingPage({ const { cte: cteSlug } = await params; const data = CTE_DATA[cteSlug]; if (!data) notFound(); + const cta = sandboxCta(); const Icon = CTE_ICONS[cteSlug] ?? ClipboardList; @@ -423,8 +425,8 @@ export default async function CTELandingPage({ title="How RegEngine Helps" description={ <> - Upload your {data.name.toLowerCase()} data to the sandbox and - RegEngine surfaces these issues before they become audit findings during a §1.1455 records request. + Upload your {data.name.toLowerCase()} data and RegEngine + surfaces these issues before they become audit findings during a §1.1455 records request. } > @@ -453,14 +455,12 @@ export default async function CTELandingPage({ See it in action.

- Upload a sample {data.name.toLowerCase()} file to the RegEngine - sandbox and get an instant validation report. Free, no signup - required. + {cta.blurb}

diff --git a/frontend/src/lib/marketing-analytics-routes.ts b/frontend/src/lib/marketing-analytics-routes.ts index 22232678f..6712c5be4 100644 --- a/frontend/src/lib/marketing-analytics-routes.ts +++ b/frontend/src/lib/marketing-analytics-routes.ts @@ -10,7 +10,7 @@ export const MARKETING_APP_ROUTE_PREFIXES = [ ] as const; const INTERNAL_STORAGE_KEY = 're_internal'; -const SENSITIVE_ROUTE_PREFIXES = ['/sandbox/results', '/portal'] as const; +const SENSITIVE_ROUTE_PREFIXES = ['/portal'] as const; const PUBLIC_MARKETING_SECTIONS = new Set([ '/about', '/alpha', '/blog', '/buyer-programs', '/case-studies', '/compare', '/contact', '/demo', '/design-system', '/developers', diff --git a/frontend/tests/visual/ROUTE_CROSSCHECK.md b/frontend/tests/visual/ROUTE_CROSSCHECK.md index c4470306e..4c1ca313f 100644 --- a/frontend/tests/visual/ROUTE_CROSSCHECK.md +++ b/frontend/tests/visual/ROUTE_CROSSCHECK.md @@ -28,8 +28,8 @@ the source list. - `public`: 78 (designer crawl minus the 3 deliberate exclusions; was 82 before reconciliation — see below) - `authOnly`: 58 -- `skippedDynamic`: 5 (`/fsma-204/[cte]`, `/ingest/results/[id]`, `/portal/[portalId]`, `/requests/[id]`, `/sandbox/results/[id]`) -- `expectRedirectOr404`: 14 (was 10 before reconciliation) +- `skippedDynamic`: 4 (`/fsma-204/[cte]`, `/ingest/results/[id]`, `/portal/[portalId]`, `/requests/[id]`) +- `expectRedirectOr404`: 13 (was 10 before reconciliation; `/sandbox` removed after the route was retired in #3557) - excluded entirely: `/auth/sso/mock` (mock SSO fixture; reason in `excludedReason`, visited by no spec) Per-route reasons for every non-public route live in the `excludedReason` map diff --git a/frontend/tests/visual/routes.json b/frontend/tests/visual/routes.json index fa7036b06..7b16d359c 100644 --- a/frontend/tests/visual/routes.json +++ b/frontend/tests/visual/routes.json @@ -1 +1 @@ -{"_generated":"2026-10-23 from /tmp/re-all-routes.txt (155 non-empty lines) crosschecked against frontend/src/app/**/page.{tsx,jsx}; reconciled 2026-10-23 with the designer crawl (81 routes 200-no-redirect on production): 4 routes moved public->expectRedirectOr404 (/design-system, /tools/anomaly-simulator, /trust-center, /verticals/food-safety)","_note":"Single replaceable route data file for the visual suite. Public vs auth determined by frontend/src/proxy.ts requireAppAuth + AUTHENTICATED_APP_ROUTE_PREFIXES in frontend/src/lib/app-routes.ts + GATED_DEV_ROUTES (/developer/portal) + next.config.js redirects(). Signed-out behavior only.","authOnly":["/admin","/admin/api-console","/api-keys","/audit","/compliance/labels","/compliance/profile","/compliance/snapshots","/compliance/status","/compliance/traceability-plan","/controls","/dashboard","/dashboard/agent-reviews","/dashboard/alerts","/dashboard/audit-log","/dashboard/compliance","/dashboard/export-jobs","/dashboard/heartbeat","/dashboard/inflow-lab","/dashboard/integrations","/dashboard/issues","/dashboard/notifications","/dashboard/products","/dashboard/qa-health","/dashboard/recall-drills","/dashboard/recall-report","/dashboard/recall-response","/dashboard/receiving","/dashboard/scan","/dashboard/settings","/dashboard/suppliers","/dashboard/team","/developer/portal","/developer/portal/keys","/exceptions","/fsma","/fsma/assessment","/fsma/field-capture","/fsma/integration","/identity","/ingest","/ingest/curation","/onboarding","/onboarding/bulk-upload","/onboarding/setup","/onboarding/setup/facility","/onboarding/setup/ftl-check","/onboarding/setup/welcome","/records","/remediation","/requests","/review","/rules","/settings/notifications","/settings/profile","/settings/security","/settings/support","/sysadmin","/trace"],"baseURLEnv":"VISUAL_BASE_URL","excludedReason":{"/admin":"auth-gated: /admin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/admin/api-console":"auth-gated: /admin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/alpha":"redirect(): src/app/alpha/page.tsx redirects to /contact; asserted in expectRedirectOr404","/api-keys":"auth-gated transitively: bare redirect() to gated /developer/portal/keys (see GATED_DEV_ROUTES comment in proxy.ts)","/audit":"auth-gated: /audit prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/auth/sso/mock":"excluded entirely: mock SSO fixture page (CHROMELESS_EXACT_ROUTES); must never be screenshotted or visited by monitoring","/compliance":"redirect source: next.config.js 308 /compliance -> /dashboard/compliance; also auth-gated (/compliance prefix); asserted in expectRedirectOr404","/compliance/labels":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/profile":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/snapshots":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/status":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/traceability-plan":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/controls":"auth-gated: /controls prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/agent-reviews":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/alerts":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/audit-log":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/compliance":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/export-jobs":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/heartbeat":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/inflow-lab":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/integrations":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/issues":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/notifications":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/products":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/qa-health":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-drills":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-report":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-response":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/receiving":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/scan":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/settings":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/suppliers":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/team":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/demo":"demo surface: asserted in expectRedirectOr404 (no baseline). OBSERVED 2026-10-23: src/app/demo/page.tsx currently renders 200 with synthetic data and is linked from /sandbox, so this assertion flags until the route is retired or reclassified to public","/design-system":"404 on production: src/app/design-system/page.tsx calls notFound() when NODE_ENV=production (Internal, development only); absent from the designer 200-no-redirect crawl; asserted in expectRedirectOr404","/developer/portal":"auth-gated: GATED_DEV_ROUTES in proxy.ts; signed-out proxy redirects to /login","/developer/portal/keys":"auth-gated: GATED_DEV_ROUTES in proxy.ts; signed-out proxy redirects to /login","/exceptions":"auth-gated: /exceptions prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES (exact + slash match only; does NOT cover /fsma-204); signed-out proxy redirects to /login","/fsma-204/[cte]":"dynamic [cte] param: no fixed URL to baseline; needs a param allowlist before it can be covered","/fsma/assessment":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma/field-capture":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma/integration":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/identity":"auth-gated: /identity prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest":"auth-gated: /ingest prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest/curation":"auth-gated: /ingest prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest/results/[id]":"dynamic [id] param: no fixed URL to baseline; also auth-gated (/ingest prefix)","/onboarding":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/bulk-upload":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/facility":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/ftl-check":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/welcome":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/portal/[portalId]":"dynamic [portalId] param: no fixed URL to baseline","/records":"auth-gated: /records prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/remediation":"auth-gated: /remediation prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/requests":"auth-gated: /requests prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/requests/[id]":"dynamic [id] param: no fixed URL to baseline; also auth-gated (/requests prefix)","/retailer-readiness":"redirect source: next.config.js 308 /retailer-readiness -> /buyer-programs; page.tsx exists but the redirect wins; asserted in expectRedirectOr404","/review":"auth-gated: /review prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/rules":"auth-gated: /rules prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/sandbox":"demo surface: asserted in expectRedirectOr404 (no baseline). OBSERVED 2026-10-23: flag-gated by isSandboxEnabled() (@/lib/sandbox-cta) but renders 200 in both states (sandbox UI vs disabled notice), so this assertion flags until the route is retired or reclassified to public","/sandbox/results/[id]":"dynamic [id] param: no fixed URL to baseline","/settings":"redirect source: next.config.js 308 /settings -> /dashboard/settings; also auth-gated (/settings prefix); asserted in expectRedirectOr404","/settings/notifications":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/profile":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/security":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/support":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/users":"redirect source: next.config.js 308 /settings/users -> /dashboard/settings/users; has NO page.tsx (see ROUTE_CROSSCHECK.md); also auth-gated; asserted in expectRedirectOr404","/sysadmin":"auth-gated: /sysadmin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES (+ sysadmin-only check); signed-out proxy redirects to /login","/tools/anomaly-simulator":"redirect(): src/app/tools/anomaly-simulator/page.tsx permanentRedirects to /tools/drill-simulator (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404","/tools/readiness-assessment":"redirect source: next.config.js 308 /tools/readiness-assessment -> /tools/self-reported-checklist; asserted in expectRedirectOr404","/tools/recall-readiness":"redirect source: next.config.js 308 /tools/recall-readiness -> /tools/records-request-checklist; asserted in expectRedirectOr404","/tools/retailer-readiness":"redirect source: page.tsx redirects to /retailer-readiness, which 308s to /buyer-programs; asserted in expectRedirectOr404","/trace":"auth-gated: /trace prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/trust-center":"redirect(): src/app/trust-center/page.tsx redirects to /trust (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404","/verticals/food-safety":"redirect(): src/app/verticals/food-safety/page.tsx redirects to /fsma-204 (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404"},"expectRedirectOr404":["/demo","/sandbox","/alpha","/retailer-readiness","/tools/recall-readiness","/tools/readiness-assessment","/tools/retailer-readiness","/settings","/settings/users","/compliance","/design-system","/tools/anomaly-simulator","/trust-center","/verticals/food-safety"],"priority":["/","/pricing","/integrations","/developers","/trust","/why-regengine","/proof","/tools/scan","/login","/signup"],"public":["/","/about","/accept-invite","/auth/verify","/blog","/blog/24-hour-rule","/blog/fda-food-traceability-requirements","/blog/food-traceability-software","/blog/fsma-204-compliance-checklist-2026","/blog/fsma-204-compliance-guide","/blog/fsma-204-cte-kde-guide","/blog/fsma-204-mid-market-guide","/blog/fsma-204-traceability-lot-codes","/blog/regengine-vs-spreadsheets-traceability","/buyer-programs","/case-studies","/compare/foodlogiq","/compare/repositrak","/compare/tracegains","/contact","/developers","/developers/compliance-verticals","/docs","/docs/api","/docs/authentication","/docs/changelog","/docs/connectors/inflow-lab","/docs/errors","/docs/fsma-204","/docs/quickstart","/docs/rate-limits","/docs/sdks","/docs/walkthrough","/docs/webhooks","/dpa","/fsma-204","/integrations","/legal/vulnerability-disclosure","/login","/pricing","/privacy","/product","/proof","/proof/recall-drill","/proof/transformation","/security","/signup","/status","/supplier-compliance","/terms","/tools","/tools/ask","/tools/cte-mapper","/tools/data-import","/tools/drill-simulator","/tools/export","/tools/fsma-unified","/tools/ftl-checker","/tools/inflow-lab","/tools/inflow-lab-dashboard-preview","/tools/kde-checker","/tools/knowledge-graph","/tools/label-scanner","/tools/notice-validator","/tools/obligation-scanner","/tools/records-request-checklist","/tools/roi-calculator","/tools/scan","/tools/self-reported-checklist","/tools/sop-generator","/tools/tlc-validator","/trust","/trust/architecture","/trust/retention","/trust/support","/verify","/walkthrough","/why-regengine"],"skippedDynamic":["/fsma-204/[cte]","/ingest/results/[id]","/portal/[portalId]","/requests/[id]","/sandbox/results/[id]"]} \ No newline at end of file +{"_generated":"2026-10-23 from /tmp/re-all-routes.txt (155 non-empty lines) crosschecked against frontend/src/app/**/page.{tsx,jsx}; reconciled 2026-10-23 with the designer crawl (81 routes 200-no-redirect on production): 4 routes moved public->expectRedirectOr404 (/design-system, /tools/anomaly-simulator, /trust-center, /verticals/food-safety)","_note":"Single replaceable route data file for the visual suite. Public vs auth determined by frontend/src/proxy.ts requireAppAuth + AUTHENTICATED_APP_ROUTE_PREFIXES in frontend/src/lib/app-routes.ts + GATED_DEV_ROUTES (/developer/portal) + next.config.js redirects(). Signed-out behavior only.","authOnly":["/admin","/admin/api-console","/api-keys","/audit","/compliance/labels","/compliance/profile","/compliance/snapshots","/compliance/status","/compliance/traceability-plan","/controls","/dashboard","/dashboard/agent-reviews","/dashboard/alerts","/dashboard/audit-log","/dashboard/compliance","/dashboard/export-jobs","/dashboard/heartbeat","/dashboard/inflow-lab","/dashboard/integrations","/dashboard/issues","/dashboard/notifications","/dashboard/products","/dashboard/qa-health","/dashboard/recall-drills","/dashboard/recall-report","/dashboard/recall-response","/dashboard/receiving","/dashboard/scan","/dashboard/settings","/dashboard/suppliers","/dashboard/team","/developer/portal","/developer/portal/keys","/exceptions","/fsma","/fsma/assessment","/fsma/field-capture","/fsma/integration","/identity","/ingest","/ingest/curation","/onboarding","/onboarding/bulk-upload","/onboarding/setup","/onboarding/setup/facility","/onboarding/setup/ftl-check","/onboarding/setup/welcome","/records","/remediation","/requests","/review","/rules","/settings/notifications","/settings/profile","/settings/security","/settings/support","/sysadmin","/trace"],"baseURLEnv":"VISUAL_BASE_URL","excludedReason":{"/admin":"auth-gated: /admin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/admin/api-console":"auth-gated: /admin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/alpha":"redirect(): src/app/alpha/page.tsx redirects to /contact; asserted in expectRedirectOr404","/api-keys":"auth-gated transitively: bare redirect() to gated /developer/portal/keys (see GATED_DEV_ROUTES comment in proxy.ts)","/audit":"auth-gated: /audit prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/auth/sso/mock":"excluded entirely: mock SSO fixture page (CHROMELESS_EXACT_ROUTES); must never be screenshotted or visited by monitoring","/compliance":"redirect source: next.config.js 308 /compliance -> /dashboard/compliance; also auth-gated (/compliance prefix); asserted in expectRedirectOr404","/compliance/labels":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/profile":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/snapshots":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/status":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/compliance/traceability-plan":"auth-gated: /compliance prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/controls":"auth-gated: /controls prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/agent-reviews":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/alerts":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/audit-log":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/compliance":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/export-jobs":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/heartbeat":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/inflow-lab":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/integrations":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/issues":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/notifications":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/products":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/qa-health":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-drills":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-report":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/recall-response":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/receiving":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/scan":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/settings":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/suppliers":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/dashboard/team":"auth-gated: /dashboard prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/demo":"demo surface: asserted in expectRedirectOr404 (no baseline). OBSERVED 2026-10-23: src/app/demo/page.tsx currently renders 200 with synthetic data, so this assertion flags until the route is retired or reclassified to public","/design-system":"404 on production: src/app/design-system/page.tsx calls notFound() when NODE_ENV=production (Internal, development only); absent from the designer 200-no-redirect crawl; asserted in expectRedirectOr404","/developer/portal":"auth-gated: GATED_DEV_ROUTES in proxy.ts; signed-out proxy redirects to /login","/developer/portal/keys":"auth-gated: GATED_DEV_ROUTES in proxy.ts; signed-out proxy redirects to /login","/exceptions":"auth-gated: /exceptions prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES (exact + slash match only; does NOT cover /fsma-204); signed-out proxy redirects to /login","/fsma-204/[cte]":"dynamic [cte] param: no fixed URL to baseline; needs a param allowlist before it can be covered","/fsma/assessment":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma/field-capture":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/fsma/integration":"auth-gated: /fsma prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/identity":"auth-gated: /identity prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest":"auth-gated: /ingest prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest/curation":"auth-gated: /ingest prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/ingest/results/[id]":"dynamic [id] param: no fixed URL to baseline; also auth-gated (/ingest prefix)","/onboarding":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/bulk-upload":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/facility":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/ftl-check":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/onboarding/setup/welcome":"auth-gated: /onboarding prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/portal/[portalId]":"dynamic [portalId] param: no fixed URL to baseline","/records":"auth-gated: /records prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/remediation":"auth-gated: /remediation prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/requests":"auth-gated: /requests prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/requests/[id]":"dynamic [id] param: no fixed URL to baseline; also auth-gated (/requests prefix)","/retailer-readiness":"redirect source: next.config.js 308 /retailer-readiness -> /buyer-programs; page.tsx exists but the redirect wins; asserted in expectRedirectOr404","/review":"auth-gated: /review prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/rules":"auth-gated: /rules prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings":"redirect source: next.config.js 308 /settings -> /dashboard/settings; also auth-gated (/settings prefix); asserted in expectRedirectOr404","/settings/notifications":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/profile":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/security":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/support":"auth-gated: /settings prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/settings/users":"redirect source: next.config.js 308 /settings/users -> /dashboard/settings/users; has NO page.tsx (see ROUTE_CROSSCHECK.md); also auth-gated; asserted in expectRedirectOr404","/sysadmin":"auth-gated: /sysadmin prefix in AUTHENTICATED_APP_ROUTE_PREFIXES (+ sysadmin-only check); signed-out proxy redirects to /login","/tools/anomaly-simulator":"redirect(): src/app/tools/anomaly-simulator/page.tsx permanentRedirects to /tools/drill-simulator (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404","/tools/readiness-assessment":"redirect source: next.config.js 308 /tools/readiness-assessment -> /tools/self-reported-checklist; asserted in expectRedirectOr404","/tools/recall-readiness":"redirect source: next.config.js 308 /tools/recall-readiness -> /tools/records-request-checklist; asserted in expectRedirectOr404","/tools/retailer-readiness":"redirect source: page.tsx redirects to /retailer-readiness, which 308s to /buyer-programs; asserted in expectRedirectOr404","/trace":"auth-gated: /trace prefix in AUTHENTICATED_APP_ROUTE_PREFIXES; signed-out proxy redirects to /login","/trust-center":"redirect(): src/app/trust-center/page.tsx redirects to /trust (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404","/verticals/food-safety":"redirect(): src/app/verticals/food-safety/page.tsx redirects to /fsma-204 (in public); excluded from the designer 200-no-redirect crawl as redirecting; asserted in expectRedirectOr404"},"expectRedirectOr404":["/demo","/alpha","/retailer-readiness","/tools/recall-readiness","/tools/readiness-assessment","/tools/retailer-readiness","/settings","/settings/users","/compliance","/design-system","/tools/anomaly-simulator","/trust-center","/verticals/food-safety"],"priority":["/","/pricing","/integrations","/developers","/trust","/why-regengine","/proof","/tools/scan","/login","/signup"],"public":["/","/about","/accept-invite","/auth/verify","/blog","/blog/24-hour-rule","/blog/fda-food-traceability-requirements","/blog/food-traceability-software","/blog/fsma-204-compliance-checklist-2026","/blog/fsma-204-compliance-guide","/blog/fsma-204-cte-kde-guide","/blog/fsma-204-mid-market-guide","/blog/fsma-204-traceability-lot-codes","/blog/regengine-vs-spreadsheets-traceability","/buyer-programs","/case-studies","/compare/foodlogiq","/compare/repositrak","/compare/tracegains","/contact","/developers","/developers/compliance-verticals","/docs","/docs/api","/docs/authentication","/docs/changelog","/docs/connectors/inflow-lab","/docs/errors","/docs/fsma-204","/docs/quickstart","/docs/rate-limits","/docs/sdks","/docs/walkthrough","/docs/webhooks","/dpa","/fsma-204","/integrations","/legal/vulnerability-disclosure","/login","/pricing","/privacy","/product","/proof","/proof/recall-drill","/proof/transformation","/security","/signup","/status","/supplier-compliance","/terms","/tools","/tools/ask","/tools/cte-mapper","/tools/data-import","/tools/drill-simulator","/tools/export","/tools/fsma-unified","/tools/ftl-checker","/tools/inflow-lab","/tools/inflow-lab-dashboard-preview","/tools/kde-checker","/tools/knowledge-graph","/tools/label-scanner","/tools/notice-validator","/tools/obligation-scanner","/tools/records-request-checklist","/tools/roi-calculator","/tools/scan","/tools/self-reported-checklist","/tools/sop-generator","/tools/tlc-validator","/trust","/trust/architecture","/trust/retention","/trust/support","/verify","/walkthrough","/why-regengine"],"skippedDynamic":["/fsma-204/[cte]","/ingest/results/[id]","/portal/[portalId]","/requests/[id]"]}