How the audit works
1. The tracker fires
A client component in the root layout watches the App Router pathname and query string. It fires once on initial load and again on every client-side route change.
2. The browser reports what it knows
Viewport and screen size, timezone, platform, device memory, CPU cores, and the Network Information API — whatever the browser exposes. Missing fields are sent as null rather than dropping the event.
3. The server enriches and validates
POST /api/audit validates the payload with Zod, then adds what only the server can see: client IP, user agent, accept-language, and the Vercel edge geo headers. A user-agent heuristic flags likely bots.
4. It lands in Postgres
One row per page load, written to Neon through Prisma. Query it on the admin page or straight from SQL.
Navigating between this page and the home page is itself a client-side route change — so it produces its own audit event.