docs: capture operator portal plan from grilling session

OPERATOR-PLAN.md records the decisions from the design review:
- Scope: C-visual (full UI fidelity, mock data for most screens) but real
  CRUD for tenants and partners from day one
- Lives at apps/operator/ as a separate Nuxt app, separate domain, separate
  Authentik OAuth client (dezky-operator), aud-claim distinguishes operator
  vs portal tokens
- Backend stays as a single NestJS service; rename
  services/provisioning -> services/platform-api as a prep commit
- Partner schema designed: slug/name/domain/status/marginPct/contactInfo;
  Tenant gains optional partnerId; counts and MRR are computed at query time
- Impersonation: visual stub now (modal + banner, no-op toast); real OAuth
  Token Exchange flow recorded as the first follow-up task

Also lists follow-up tasks (real audit log, feature flag backend, incident
management, partner portal) and out-of-scope items so the next grilling
session has a starting point.

Pointer added in NEXT-STEPS.md under a new 'Operator portal' track.
This commit is contained in:
Ronni Baslund
2026-05-24 00:26:21 +02:00
parent 467e6a7ab5
commit 92c5056a1d
2 changed files with 253 additions and 0 deletions
+12
View File
@@ -141,6 +141,18 @@ await authentikClient.coreUsersCreate({
})
```
## Operator portal — out-of-band track
`operator.dezky.local` (internal admin portal — separate Nuxt app, separate
Authentik OAuth client, real CRUD for tenants + partners). Plan and decisions
captured in [`OPERATOR-PLAN.md`](./OPERATOR-PLAN.md).
Touches platform-api substantially:
- Service rename `services/provisioning``services/platform-api` (prep)
- New `Partner` schema + CRUD endpoints
- Tenant lifecycle actions (suspend/resume/plan change)
- Audience-aware JwtAuthGuard for operator-only mutations
## Phase 5: Custom webmail (week 3-4)
Goal: Branded webmail client using Stalwart's JMAP API.