PLATFORM ADMIN
Allowlist
platform_admins D1 table (migration 0018), email PK. Seeded with jixjansen@gmail.com + devonthediamond@gmail.com.
If you’re on the list, the ADMIN entry appears in the hamburger drawer.
The /admin page
Three sections:
- Mint a school admin invite — optional name / email / country hints. Returns a 6-character single-use code. Click-to-copy.
- Pending invites — every unredeemed code. Re-send to recipients, audit floating codes.
- Registered schools — every school that’s redeemed an invite. Shows school code + created date + disable/re-enable.
Disable a school
- Sets
disabled_aton the row. - Members keep their accounts but lose school dashboard access.
- Reversible — tap re-enable.
Add a new platform admin
No UI yet — manual SQL via wrangler:
cd worker
pnpm exec wrangler d1 execute dartboardmaths-db --remote \
--command="INSERT INTO platform_admins (email) VALUES \
('new@example.com');"Emails must be lowercase (Better Auth normalises).
Observability
Every admin action logs structured JSON via lib/log.ts:
admin.invite_mintedadmin.school_disabledadmin.school_enabledschool.created(when an invite is redeemed)
Search the CF dashboard with event:admin.* to audit.
Things you should never do
- Don’t drop columns. Schemas are additive — destructive migrations break running deploys.
- Don’t hand-craft codes with 0/O/1/I/L glyphs. The generator excludes them.
- Don’t SQL-delete a school. Orphans every class / assignment / message. Use disable.
