chore(operator): O.9 verification + roll follow-ups into NEXT-STEPS

- Add _verify-token.get.ts to both operator and portal — decodes the
  access token stored in the nuxt-oidc-auth session and echoes iss/aud/
  sub/groups. Used to confirm operator tokens carry aud=dezky-operator
  and portal tokens carry aud=dezky-portal. Listed in NEXT-STEPS.md as
  throwaway, to be removed when proper verification surfaces exist.
- OPERATOR-PLAN.md O.9 marked done with the actual claims captured + the
  Mongo-side verification of attach + suspend flows.
- NEXT-STEPS.md: replaced the "Operator portal — out-of-band track"
  section with a "shipped + follow-ups" version. The 9-item follow-up
  list (impersonation, audit, flags, incidents, support, partner
  portal, env switcher, on-call, workspace impersonation) is now the
  authoritative roadmap, not buried inside OPERATOR-PLAN.md.
This commit is contained in:
Ronni Baslund
2026-05-24 08:47:56 +02:00
parent c71e782dc0
commit 19e1a4fca3
4 changed files with 148 additions and 22 deletions
+48 -9
View File
@@ -141,17 +141,56 @@ await authentikClient.coreUsersCreate({
})
```
## Operator portal — out-of-band track
## Operator portal — out-of-band track — shipped (O.0O.9)
`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).
`operator.dezky.local` is live as a separate Nuxt app with its own
`dezky-operator` Authentik OAuth client. Full plan and execution log 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
What landed:
- `services/provisioning` renamed to `services/platform-api`
- Audience-aware JwtAuthGuard accepts both `dezky-portal` and `dezky-operator`
- `Partner` schema + CRUD endpoints, `Tenant.partnerId` ref
- Tenant lifecycle (suspend / resume) gated by OperatorGuard
- Operator UI: Overview (real KPIs), Tenants (7-tab detail w/ Danger),
Partners (attach/detach), Users, Operator team. Visual-only Infrastructure,
Feature flags, Audit. Placeholders for Support/Billing/Reports/Settings.
- Interactions: ⌘K command palette, impersonation stub (modal + banner),
incident modal, tweaks panel (theme/density/env)
### Follow-ups before operator hits production
In rough priority order — bulk lifted from OPERATOR-PLAN.md:
- [ ] **Real impersonation flow** — OAuth Token Exchange (RFC 8693),
`act` claim on customer portal, audit on entry+exit, banner with
origin operator identity
- [ ] **Real audit log collection**`platform_audit` Mongo collection,
written by platform-api on every privileged action; stream from there
instead of `data/fixtures.ts`
- [ ] **Feature flag backend**`Flag` schema + per-tenant rollout state
+ a tiny flag-eval client every service imports
- [ ] **Incident management backend**`Incident` schema + paging
(PagerDuty / OpsGenie / custom). Until then, IncidentModal is mock.
- [ ] **Support ticket queue**`SupportTicket` schema + email-in
ingestion from a dedicated mailbox via Stalwart
- [ ] **Self-serve Partner portal at `partner.dezky.local`** — own Nuxt
app, own OAuth client, scoped to a partner's own customers
- [ ] **Real environment switcher** — currently cosmetic; would need
separate API endpoints per env, separate Authentik tenants
- [ ] **Real on-call indicator** — integration with the paging system from
the incident backend
- [ ] **Operator workspace impersonation in OCIS/Stalwart** — operator
tooling reaches into the customer's files + mail for support, with
the same audit trail
- [ ] **MRR aggregation on Partner** when Subscription gains real pricing
- [ ] **MFA-required Authentik policy** on the `dezky-operator` provider
(deferred from O.1)
- [ ] **Delete throwaway endpoints** added during verification:
`apps/operator/server/api/_verify-token.get.ts`,
`apps/portal/server/api/_verify-token.get.ts`,
`apps/operator/server/api/operator-smoke-test.post.ts`,
`apps/portal/server/api/partners/index.post.ts`
## Phase 5: Custom webmail (week 3-4)