Admin App
Internal platform admin console (apps/admin) — a Vite + React + Refine + Ant Design SPA that the FitKit team uses to inspect organizations, users, payments, queues, jobs, costs, and observability data across the platform.
What
A separate frontend deployable that talks to the FitKit API’s /admin/** namespace. Built on:
- Refine for resource scaffolding (list / show / edit).
- Ant Design UI kit.
- Clerk React for auth.
- React Router for routing.
The admin app does not own any business logic — it’s a thin view on top of the API. Every page maps to one or more apps/api/src/admin/controllers/* endpoints guarded by PlatformAdminGuard.
Why
- The FitKit team needs to inspect and intervene on customer data: investigating payment issues, retrying queue jobs, reading audit logs, managing platform billing.
- Coupling these tools to the customer-facing dashboard would inflate the bundle and risk accidental exposure to org admins.
- A separate domain + Clerk org gate keeps surface area small and easy to audit.
Who
- FitKit platform engineers — investigate incidents, debug jobs, run data repairs.
- FitKit support — impersonate users (audit-logged), reset passwords, refund payments.
- FitKit finance — review platform billing transactions, MRR, costs.
Access is gated by privateMetadata.platformRole === 'admin' on the Clerk user (cached 5 min in Redis). No org-side admin can reach this surface.
Persona impact
The admin app has no direct customer-facing impact. It exists to:
- Cut time-to-resolution on support tickets (impersonation, lead/user lookup).
- Reduce blast radius of data repair operations (typed actions, audit trail).
- Surface platform health (queues, observability, costs).
Capabilities
| Page | Purpose |
|---|---|
| Organizations | List + drill into each org, see members, plans, subscriptions, minisite, audit trail. |
| Users | Cross-org user search, profile inspection, password reset, soft-delete. |
| Subscriptions | All platform subscriptions (org-side, not platform-billing); status, plan, next charge. |
| Payments | Transaction-level inspection; refunds with required reason; provider request IDs. |
| Leads | Platform-level waitlist + dashboard leads. |
| Jobs | Import/export/embedding job listing across orgs. |
| Audit Logs | Append-only log of admin + agent actions; filterable by actor, resource. |
| Queues | BullMQ queue depths, retry / drain / pause controls. |
| System | Server metrics, env, Redis / Postgres / R2 health. |
| Costs | Platform-level AI + provider spend trend; per-org breakdown. |
| Billing | Per-org billing inspection — invoices, balances, debt. |
| Platform Billing | FitKit’s own income statement — what each gym pays FitKit. |
| Observability | Agent traces, Sentry pivot, recent error spikes. |
| Actions | One-off operational actions (rebuild cache, reindex embeddings, fix bookings, cancel platform txn). |
| Canonical Movements | Curate the canonical exercise library + enrichment review. |
Related features
- All
admin-*controllers underapps/api/src/admin/. PlatformAdminGuard—apps/api/src/admin/guards/platform-admin.guard.ts.AdminAuditInterceptor— wraps every admin mutation with an audit-log entry.event-tracking— the admin app’s PostHog identify is wired through the API on user load.
Status
Shipped. Used daily. New admin pages land roughly weekly as new operations need to be visualized.
Gaps
- No write workflow versioning — a destructive action that goes wrong is hard to revert without a DB restore.
- Cost dashboard is read-only; budget alerting lives in PostHog dashboards, not in the admin app.
- Refine’s dataProvider is hand-rolled (
createDataProvider); some advanced Refine features (cursor pagination, optimistic mutations) are not wired up.