docs: record the 1.1.0 release and add the infrastructure map
Some checks failed
deploy-site / deploy (push) Failing after 40s
Some checks failed
deploy-site / deploy (push) Failing after 40s
Release notes for 1.1.0 were split between an Unreleased section and the version section, so the published notes would have omitted the update-feed and desktop changes. Everything shipping in this version now sits under one `## [1.1.0]` heading. `docs/map/` becomes the entry point for what infrastructure exists per platform and how far each feature is developed, with a documented update protocol so feature work and this map do not drift apart again. The release guide now states that installer binaries live in the update feed rather than the repository.
This commit is contained in:
parent
c2db1b2176
commit
c3ddd36c6f
29 changed files with 3207 additions and 23 deletions
91
docs/map/08-admin-console.md
Normal file
91
docs/map/08-admin-console.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# 08 — Admin Console (Next.js) Map
|
||||
|
||||
> Surface: `apps/admin`
|
||||
> Stack: Next.js 16 App Router + MUI (`@d3ro/ui` theme) + Supabase service role + .NET proxy
|
||||
> Role: back office CRM/ops — users, subscriptions, models, usage, audit, releases, ads
|
||||
|
||||
---
|
||||
|
||||
## 1. Route tree (`src/app/`)
|
||||
|
||||
### Public
|
||||
| Route | Purpose |
|
||||
|---|---|
|
||||
| `/login` | Email/password → `/api/auth/login`; Google OAuth via Supabase → `/auth/callback`; maps error keys |
|
||||
| `/unauthorized` | 403 screen |
|
||||
| `/auth/callback` | OAuth code → session exchange |
|
||||
|
||||
### Protected `(admin)` (guarded by `(admin)/layout.tsx` → `requireManager()`)
|
||||
| Route | Purpose |
|
||||
|---|---|
|
||||
| `/` | Dashboard: backend stats, node health, MRR/ARR/active subscriptions (Supabase), recent errors |
|
||||
| `/pipelines` | AI/voice pipeline telemetry; explicit "unavailable" card when no measured data |
|
||||
| `/models` | LLM model + STT provider manager (presets, CRUD, test) |
|
||||
| `/releases` | Forgejo live release hub (assets, platforms, sizes, downloads, SHA-256) |
|
||||
| `/users` | User directory: search + tier/role filters |
|
||||
| `/users/[id]` | User 360: profile, subscription, 30-day usage, role change (admin+), payment history |
|
||||
| `/subscriptions` | Subscription ops list + filters; license issuer (super_admin) |
|
||||
| `/subscriptions/new` | Grant VIP subscription (admin+) |
|
||||
| `/subscriptions/[id]` | Subscription detail: edit (manager+) / delete (admin+) |
|
||||
| `/ads` | Ad mediation console (10 networks, all fail_closed) + reward stats |
|
||||
| `/support` | **Stub** — explicit "not configured" panel |
|
||||
| `/usage` | Combined LLM + STT usage/cost analytics |
|
||||
| `/audit-log` | Supabase audit log list + target filter + pagination |
|
||||
| `/audit-log/[id]` | Audit detail with before/after diff |
|
||||
|
||||
---
|
||||
|
||||
## 2. API route handlers (`src/app/api/`)
|
||||
|
||||
| Route | Methods | Behavior |
|
||||
|---|---|---|
|
||||
| `/api/auth/login` | POST | Validate body, reject honeypot `trap`, in-memory rate limit/lockout, proxy to `.NET /api/auth/login` (7s timeout, HTTPS in prod), validate token/role/email/expiry, sign HMAC session cookie `d3ro_admin_session` |
|
||||
| `/api/auth/logout` | POST/GET | Clear cookie; GET redirects `/login` |
|
||||
| `/api/admin/backend/[...segments]` | GET/POST/PUT/DELETE | Allow-list proxy to `.NET /api/admin/*`; required role by path; same-origin for non-GET; ≤64KB; UUID idempotency-key for mutations |
|
||||
| `/api/admin/license` | POST | Same-origin + `requireVerifiedBackendSession('super_admin')`; sign Ed25519 key with `ADMIN_LICENSE_PRIVATE_KEY` (`@d3ro/core/utils/crypto-license`); best-effort audit |
|
||||
| `/api/admin/supabase/[operation]` | GET/POST/PATCH/DELETE | `admin-users`, `admin-subscriptions`, `admin-payments` via RPCs; strict allow-lists; Payple live history returns `501` |
|
||||
| `/auth/callback` | GET | Supabase OAuth exchange |
|
||||
|
||||
---
|
||||
|
||||
## 3. Libraries (`src/lib/`)
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `admin-session.ts` | Session types, secret validation (≥32 bytes), strict cookie parse, `adminCookieSecure()` escape hatch |
|
||||
| `security.ts` | server-only HMAC-SHA256 sign/verify, in-memory rate limit/lockout, runtime security validation |
|
||||
| `admin-guard.ts` | RSC guards `requireManager`/`requireAdmin`/`requireSuperAdmin`, role helpers |
|
||||
| `edge-session.ts` | Edge-runtime HMAC verify via WebCrypto (used by `proxy.ts`) |
|
||||
| `backend-session.ts` | `requireApiServerOrigin`, `requireVerifiedBackendSession(minRole)` (verifies cookie + `.NET /api/auth/me`), `fetchAdminBackend` |
|
||||
| `api-server.ts` | server-only data access to .NET backend (stats, users, endpoints, usage reports) |
|
||||
| `backend-admin-client.ts` | client CRUD for model/STT endpoints with auto idempotency keys |
|
||||
| `admin-api.ts` | client `callAdminApi` for Supabase admin operations |
|
||||
| `supabase-admin.ts` | service-role client, actor resolution RPC, product user fetch |
|
||||
| `supabase-browser.ts` / `supabase-server.ts` | client/server Supabase wrappers |
|
||||
| `ad-monetization.ts` | `MEDIATION_ROSTER` (fail_closed) + ad reward stats |
|
||||
| `subscription-metrics.ts` | MRR/ARR/active/tier breakdown |
|
||||
| `audit-sanitize.ts` | recursive redaction of sensitive keys in audit snapshots |
|
||||
| `forgejo-releases.ts` | Forgejo release feed parser (`RELEASE_REPO_URL`) |
|
||||
| `console-theme.ts` | design tokens + MUI style presets |
|
||||
|
||||
Root files: `instrumentation.ts` (startup security validation), `proxy.ts` (edge middleware: public paths, auth redirect, security headers), `robots.ts` (disallow all).
|
||||
|
||||
---
|
||||
|
||||
## 4. Components (`src/components/`)
|
||||
|
||||
`admin-sidebar` (nav island: Core Platform / Customer & Revenue / Intelligence & Security), `unavailable-admin-panel` (reusable "NOT CONNECTED", no sample data), `audit-diff-viewer`, `payment-history`, `subscription-form`, `role-change-dialog` + `role-change-button`, `memo-dialog`, `license-issuer-button` + `license-issuer-dialog`, `checksum-copy`, charts (`dau-chart`, `feature-usage-chart`, `top-users-chart`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Admin status summary
|
||||
|
||||
- Dashboard, models, releases, users, subscriptions, usage, audit log, ads: **implemented** against real backend/Supabase data.
|
||||
- Security: HMAC signed sessions, RSC + edge guards, rate limit/lockout, honeypot, strict origin/allow-list, no-store, robots disallow, audit redaction. Red-team scenarios were exercised (see `memory/project_status.md`).
|
||||
- Explicit fail-closed / not-configured states (by design, not bugs):
|
||||
- `/support` stub — no ticket/SLA/diagnostics contract.
|
||||
- `/ads` — all 10 networks `fail_closed`; no live bids.
|
||||
- `admin-payments` Payple live history → `501`.
|
||||
- `UnavailableAdminPanel` whenever Supabase env absent; writes disabled, no sample metrics.
|
||||
- `/pipelines` and dashboard node/error sections render only measured data.
|
||||
- Deploy: `Dockerfile.admin` / `apps/admin/Dockerfile` → GHCR + NAS compose; GitLab admin NAS deploy job disabled.
|
||||
Loading…
Add table
Add a link
Reference in a new issue