Observability and Debug Mode
Debug mode architecture, environment variables, mock auth/storage, and how the frontend logs client-side errors and exposes health check endpoints.
The frontend has two observability mechanisms: a debug mode for local development and simple console-based error reporting for production. There is no structured logging service, OpenTelemetry setup, or Sentry integration.
Debug Mode
NEXT_PUBLIC_DEBUG_MODE=true is a build-time environment variable that transforms the application into a fully offline, mock-backed development environment.
What debug mode does
| Component | Normal behavior | Debug mode behavior |
|---|---|---|
Middleware middleware.ts | Redirects unauthenticated requests to login | Allows every request immediately |
Auth helper auth() | Creates SSR Supabase client, calls getUser() | Returns a mock admin user immediately |
Client context useAuth() | Calls supabase.auth.getUser(), fetches /api/auth/me | Returns the mock user as authenticated, isAdmin: true |
Client factory lib/supabase.ts | Initializes Supabase client with URL + anon key | Returns a mock proxy that throws on any DB query |
| Stripe Elements checkout page | Renders real card input | Renders a mock form |
create-intent API | Calls Stripe API | Returns mock clientSecret |
| Payment completion | Waits for Stripe webhook | Directly simulates library assignment |
Admin check useAuth() | Queries user_roles | Returns admin role for mock user |
The mock user returned by debug mode is:
{
id: 'mock-user-id',
email: 'debug@debug.com',
displayName: 'Debug User',
role: 'admin',
status: 'active',
}When debug mode is useful
- Developing auth pages without a Supabase project
- Testing the admin panel without seeding data
- Working on payment UI without a Stripe account
- Running the frontend in environments where Supabase is unavailable
Environment Variables
The frontend reads the following environment variables at build time or runtime (Next.js convention: NEXT_PUBLIC_* is inlined at build time, non-public vars are server-only):
| Variable | Purpose | Required |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL | Yes |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase anon/public key | Yes |
SUPABASE_SERVICE_ROLE_KEY | Service-role key for admin client | No (falls back to anon key in dev) |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Stripe publishable key | Yes (for payments) |
STRIPE_SECRET_KEY | Stripe secret key | Yes (for payments) |
STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret | Yes (for webhooks) |
NEXT_PUBLIC_DEBUG_MODE | Enables debug mode | No |
NEXT_PUBLIC_APP_URL | Public app URL for Stripe redirects and link generation | No |
NEXT_PUBLIC_MAX_FILE_SIZE | Max book upload file size in bytes | No |
NEXT_PUBLIC_MAX_COVER_SIZE | Max cover image file size in bytes | No |
Runtime Error Logging
The frontend uses console.error() for runtime error logging. There is no centralized error handler:
- API routes catch errors and return
500 { error: message }responses. - Client components catch promise rejections and show toast notifications via
sonner. - Server components throw errors that Next.js surfaces in the terminal or Vercel logs.
Health Check
GET /api/media/health is the only health check endpoint. It tests that the Supabase Storage client can list buckets. Used by the admin panel's system monitor.
There is no health check for the Python backend connection - the chat API route simply fails with a network error if the backend is unreachable.
What is Missing
- No structured logging service (no Winston, Pino, or
console.logwrappers). - No OpenTelemetry instrumentation.
- No client-side error tracking (no Sentry, no LogRocket).
- No performance monitoring.
- No uptime monitoring endpoint beyond the storage health check.
- No audit trail for admin actions.
These are intentional omissions for the initial build - the application relies on Vercel's platform logging for production observability.
Admin Panel
Admin layout, server-side auth guard, stats dashboard, content moderation (books, comments, reports), user management, and system notification CRUD.
Out of Scope and Stale Code
Dead code paths, stale migrations, stubs, and unused dependencies that are present in the codebase but not part of the active architecture.