Users & Roles
- Search / view members: profile, login history, test attempts, activity.
- Suspend / delete (GDPR) and impersonate for support (audited).
- Roles:
superadmin,admin,analyst(aggregate-only, no PII drill-down). - Retake control: reset a user's retake lock, or toggle rapid-retake for devops/testing accounts.
Auth model (Phase 1)
Sign-in is OAuth-only (Google + Facebook at launch; Apple later). We store the
provider identity in oauth_identities, never a password. A person with the same
verified email across providers is linked to one users row; unverified emails
are never auto-linked (prevents account takeover). Sessions live in KV with a mirror
row in sessions, and every login is recorded in login_events.
Seeding the first superadmin
There is no public "make me admin" endpoint. After the founder has signed in
once (so their users row exists), grant the role by hand:
wrangler d1 execute openaptitude_db --remote --file db/seeds/0001_superadmin.sql
The script is idempotent (the unique (user_id, role) index makes re-runs safe).
Edit the email in the SQL file before running it for a different owner. Grant
additional roles the same way; roles are enforced by requireRole() and, for the
admin portal, by Cloudflare Access (Phase 4).