Platform Administration
The SUPER_ADMIN console for running POSVelo as a multi-tenant service
These are provider tools, not tenant tools. They belong to
the platform owner running POSVelo as a SaaS — the SUPER_ADMIN role. A regular
business ADMIN never sees them. Everything here lives under
/api/v1/super-admin/* and the /admin screens, and is
gated by a verified platform SUPER_ADMIN check.
The Console at a Glance
| Screen | Route | What you do there |
|---|---|---|
| Tenants | /admin/tenants | List, search, create, suspend / reactivate businesses |
| Tenant detail | /admin/tenants/[id] | One tenant's profile, subscription, and usage vs. limits; impersonate |
| Create tenant | /admin/tenants/new | Onboard a business directly with a chosen plan and status |
| Billing | /admin/billing | Platform MRR, subscription counts, and the plan catalog editor |
| System | /admin/system | Maintenance mode + cross-tenant broadcast composer |
| Audit | /admin/audit | Platform-wide audit log viewer (every tenant) |
Onboarding & Suspension
A SUPER_ADMIN can create a tenant directly — the same transaction the self-serve signup uses (tenant + main store + ADMIN user + invoice sequences), but with the plan and status set up front for sales-assisted onboarding.
| Method | Endpoint | Notes |
|---|---|---|
| POST | /api/v1/super-admin/tenants | Create a tenant; omit the admin password to auto-generate a one-time temp password returned once |
| GET | /api/v1/tenants/:id/usage | Current plan + per-resource usage vs. limit (backs the usage view) |
Suspending a tenant takes effect on their very next request —
a still-valid access token is rejected with 401 immediately,
rather than continuing to work until it expires. The status is cached for ~30
seconds and invalidated the moment you change it, so a suspend (or reactivate)
propagates within seconds across instances.
Impersonation
When a tenant reports a problem you cannot reproduce, you can step into their shoes — safely, and with a paper trail. Impersonation mints a separate token scoped to that tenant's oldest active ADMIN.
| Method | Endpoint | Behavior |
|---|---|---|
| POST | /api/v1/super-admin/tenants/:tenantId/impersonate | Requires a reason (min 10 chars); returns a token that expires in a fixed 15 minutes |
| POST | /api/v1/auth/impersonate/end | Ends the session (an audit close-out) — available to the impersonation token itself |
The token lasts a fixed 15 minutes regardless of the normal access-token
expiry, and has no refresh token, so it cannot be silently
renewed. The platform tenant itself cannot be impersonated, nor can a tenant
with no active ADMIN. Both starting and ending are audited
(TENANT_IMPERSONATION_STARTED / _ENDED), and GET /auth/me
surfaces an impersonation claim so the app can show the “you are
impersonating” banner.
Plan Catalog
The plan catalog and its Stripe sync are managed here too, from
/admin/billing. Because plans, pricing, and limit enforcement are a
billing concern, the full reference — including how price edits re-create Stripe
Prices — lives on the billing page.
Creating plans, editing prices, and the limit-enforcement rules are covered in Subscriptions & Billing. The platform console is simply where a SUPER_ADMIN performs them.
Platform-Wide Audit
Every audited action across every tenant is readable in one place. A tenant ADMIN sees only their own audit trail; a SUPER_ADMIN sees all of them.
| Method | Endpoint | Scope |
|---|---|---|
| GET | /api/v1/audit | One tenant's audit logs (ADMIN, report:read) |
| GET | /api/v1/audit/all | Every tenant — filter by tenantId, action, entityType, entityId, date range (SUPER_ADMIN) |
Maintenance Mode
Maintenance mode lets you take the API offline for a window — e.g. during a migration — while keeping the doors you need to flip it back off.
Enable it
PATCH /api/v1/super-admin/system/maintenance with a message.
Read the current state any time with GET on the same path.
What still works while it's on
The gate allowlists health checks, auth, the entire
super-admin surface, and Stripe webhooks —
so you can still sign in, flip it back off, and keep billing flowing.
Everything else returns 503.
Disable it
Setting it off resets the message and the enabled-by / enabled-at metadata. The state is cached ~30s, so multi-instance deployments converge within that window of a toggle.
The toggle is an API call, not a redeploy — it is stored in the
platform tenant's settings JSON. That is why auth and the
super-admin routes stay open: an operator must always be able to authenticate
and reach this endpoint to turn it back off.
Cross-Tenant Broadcast
Send a single in-app notification to users across every tenant — for a planned maintenance notice, a new feature, or a policy change.
The broadcast resolves every active user across every tenant that matches an optional plan / status filter (the platform tenant is always excluded), groups recipients by their own tenant, and writes + publishes through the same notification pipeline as a normal per-tenant broadcast — so each recipient gets it on their live bell exactly like any other notification. The action is audited with the resulting tenant and user counts. See Real-Time Notifications for the delivery mechanism.
Endpoint Summary
| Capability | Endpoint |
|---|---|
| Create tenant | POST /api/v1/super-admin/tenants |
| Tenant usage vs. limits | GET /api/v1/tenants/:id/usage |
| Impersonate / end | POST …/tenants/:id/impersonate · POST /api/v1/auth/impersonate/end |
| Billing overview (MRR) | GET /api/v1/super-admin/billing/overview |
| Tenant subscription | GET /api/v1/super-admin/tenants/:tenantId/subscription |
| Plan catalog CRUD | GET/POST/PATCH /api/v1/super-admin/billing/plans |
| Platform audit | GET /api/v1/audit/all |
| Maintenance mode | GET/PATCH /api/v1/super-admin/system/maintenance |
| Broadcast | POST /api/v1/super-admin/system/broadcast |