All Docs
FeaturesCalmony Sanctions MonitorUpdated March 12, 2026

Person Detail: 404 Handling & Server-Side Rendering

Person Detail: 404 Handling & Server-Side Rendering

As of v0.1.103, the /dashboard/people/[id] route is a fully server-rendered page with robust validation. Invalid, missing, and unauthorised person IDs all return a proper HTTP 404 response rather than a blank or broken UI.

Validation Sequence

When a request hits /dashboard/people/[id], the server performs the following checks in order before any HTML is rendered:

  1. Non-numeric ID check — if the id segment cannot be parsed as an integer (e.g. /people/not-a-number), notFound() is called immediately with no database round-trip.
  2. Session checkauth() is called server-side. If no authenticated session exists, notFound() is returned (belt-and-braces over the existing middleware guard).
  3. Ownership-scoped DB query — the person record is fetched with WHERE id = ? AND userId = ?. Records belonging to other users are treated identically to missing records.
  4. Empty result check — if the query returns no rows, notFound() is called.

All four failure paths trigger Next.js's built-in 404 flow, which renders the existing branded not-found.tsx page and returns an HTTP 404 status code.

ID Enumeration Protection

Because the ownership-scoped query (WHERE id = ? AND userId = ?) returns an empty result for both non-existent IDs and IDs belonging to other users, an authenticated user cannot determine whether a given ID exists. Both cases produce an identical 404 response.

Server-Side Data Pre-fetching

On a successful lookup, person and matches data are fetched server-side and passed as props to the client component (initialPerson, initialMatches, personId). This eliminates the extra client-side fetch that previously occurred on first load — the page is fully populated on the initial HTML response.

After a re-screen action, the client component calls refreshPerson() (a lightweight fetch to /api/people/[id]) to update the displayed state with fresh screening results. This is the only client-side fetch that remains.

Static Prerender Prevention

The page exports:

export const dynamic = "force-dynamic";

This prevents Next.js from attempting to statically prerender the route at build time, which would fail because the page reads from the database and requires an authenticated session.

Error States

URLConditionResponse
/dashboard/people/not-a-numberNon-numeric segmentHTTP 404 + branded not-found page
/dashboard/people/99999Record does not existHTTP 404 + branded not-found page
/dashboard/people/123Record belongs to another userHTTP 404 + branded not-found page
/dashboard/people/123No active sessionHTTP 404 + branded not-found page
/dashboard/people/123Valid, owned record200 + server-rendered detail page