Home

boring / v2

publicBoring-Software-Inc/v2
Overview Code History Branches Pull requestsIssuesInsights Campfire Docs
main
HomeOverview Code PRsIssues

feat(admin): platform staff portal at /admin

3 months ago

c01c7f1
Authored
grim7/20/2026, 4:44:53 PM
- user.is_platform_admin (drizzle 0010), input:false in better auth —
  a client payload carrying it is refused outright (FIELD_NOT_ALLOWED,
  integration-proven). only write path is bun run grant-admin
- staff gate reads the bit fresh per request, never session claims;
  every denial is a 404 — /admin existence is not disclosed, same
  posture as non-member org urls
- new "staff" class in server-fn-classification; the boundary test
  asserts each admin fn's middleware chain matches
- /admin (counts), /admin/users (status filter, search, bulk approve,
  two-step reject), /admin/orgs (expandable members, role select).
  paginated + clamped, no unbounded selects
- approve writes through promoteUserAccess (the invite-redemption
  path — already stamps reviewedAt/By, already idempotent);
  rejectUserAccess added as its mirror, the first writer of "rejected"
- role-change invariants extracted to assertRoleChangeAllowed, shared
  by the plugin hook and updateMemberRoleForStaff — the portal cannot
  demote a last admin or touch a personal org
- ops + audit gap in DECISIONS.md: revisit before the first
  non-founder staff grant

Parent8accee5

33 files changed
  • DECISIONS.md+30−0
  • apps/web/src/components/admin/access-status-dot.tsx+21−0
  • apps/web/src/components/admin/admin-home-page-skeleton.tsx+29−0
  • apps/web/src/components/admin/admin-home-page.tsx+61−0
  • apps/web/src/components/admin/admin-orgs-page-skeleton.tsx+50−0
  • apps/web/src/components/admin/admin-orgs-page.tsx+252−0
  • apps/web/src/components/admin/admin-users-page-skeleton.tsx+53−0
  • apps/web/src/components/admin/admin-users-page.tsx+307−0
  • apps/web/src/components/admin/format-admin-date.ts+8−0
  • apps/web/src/hooks/use-debounced-value.ts+11−0
  • apps/web/src/lib/admin.functions.ts+141−0
  • apps/web/src/lib/admin.query.ts+74−0
  • apps/web/src/lib/server-fn-boundary.test.ts+15−6
  • apps/web/src/lib/server-fn-classification.ts+12−1
  • apps/web/src/lib/server/staff-guard.ts+45−0
  • apps/web/src/routes/admin.index.tsx+16−0
  • apps/web/src/routes/admin.orgs.tsx+16−0
  • apps/web/src/routes/admin.tsx+19−0
  • apps/web/src/routes/admin.users.tsx+16−0
  • package.json+1−0
  • packages/auth/package.json+2−1
  • packages/auth/src/server.ts+22−16
  • packages/auth/src/staff-gate.integration.test.ts+307−0
  • packages/auth/src/staff-gate.ts+25−0
  • packages/db/drizzle/0010_loud_ares.sql+1−0
  • packages/db/drizzle/meta/0010_snapshot.json+2075−0
  • packages/db/drizzle/meta/_journal.json+7−0
  • packages/db/src/index.ts+9−0
  • packages/db/src/schema/auth.ts+6−0
  • packages/db/src/services/access.ts+28−0
  • packages/db/src/services/organizations.ts+78−0
  • packages/db/src/services/staff.ts+225−0
  • scripts/grant-admin.ts+62−0