One authenticated dashboard for every operator workflow
Every page outside /login, /blog, and /auth/callback requires a Supabase session whose email exists in the admin_users table before it renders.
Access model#
The admin check runs in src/middleware.ts on every matched page request: it resolves a Supabase session and requires the email in admin_users. A signed-in non-admin is signed back out. Access is operator-only: authorization is an explicit row in admin_users, with no signup path and no role model beyond admin. API routes are excluded from that middleware and each authorizes itself — an admin session, a shared secret, or nothing at all for the two public read surfaces.
The one unauthenticated liveness probe is GET /api/health, which returns {"status":"ok"} and nothing else.
Operator workspaces#
- Content generation: image, video, audio, meme, lipsync, and LoRA pipelines.
- Asset and character library for reusable generation inputs.
- Social account automation, CRM, and outreach.
- Paid ads plus trends and competitor research.
- Blog admin: drafts, publishing, and landing-page revalidation.
- Onboarding Studio at /onboarding for journey drafting, publication, activation, and rollback.
- Diagnostics at /diagnostics and service balances at /balances.
Observability and cost#
/diagnostics aggregates action logs, failures, and per-service costs over a window. Failure responses carry x-wisent-failure and x-wisent-failure-impact so a client can distinguish broken from absent.
The 41 cron schedules are the largest unattended cost source — several run every 3 to 30 minutes and trigger generation, scraping, and outreach. Service balances are polled and surfaced on /balances, and a balance below 5 raises a pending_actions row.