docs(phase2b): document admin and platform-data architecture
New docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md covers the Platform API split, Postgres schema and migration guarantees/rollback, the session cookie architecture (including the whoami-routing-bug fix), the admin portal, the API/security boundary, known limitations, and Phase 3+ future work. Updates ENGINEERING_SOP.md §8, LAB_ARCHITECTURE.md, README.md, and platform/README.md to reflect Platform API as the sole Provisioner caller and Postgres as authoritative for identity/progress as of Phase 2B.
This commit is contained in:
+29
-19
@@ -6,42 +6,52 @@ Start here, then go to the component you need:
|
||||
- `provisioner/` — Postgres-backed environment registry and lifecycle. Design:
|
||||
`docs/LAB_ARCHITECTURE.md`, `docs/PHASE1_PLATFORM_FOUNDATION.md`. Operational reference:
|
||||
`provisioner/README.md`.
|
||||
- `api/` — the lightweight Platform API: students, cohorts, enrollments, curriculum, progress,
|
||||
scenario attempts, student/admin sessions, and the instructor/admin control plane. No k3s, no
|
||||
`--privileged` — this replaced Phase 2A's "identity" instance, which was a full Lab image
|
||||
booting an unused k3s cluster just to serve these APIs. Design:
|
||||
`docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md`. Operational reference: `api/README.md`.
|
||||
- `gateway/` — the only student-facing path to a Lab (HTTP + WebSocket proxy, environment-aware
|
||||
routing, student identity glue). Design: `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md`.
|
||||
routing derived from a server-controlled session — not a client-suppliable header/param).
|
||||
Design: `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md` (routing), `docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md` §3 (session ownership).
|
||||
- `egress-proxy/` — shared allowlisting proxy every Lab's outbound traffic passes through.
|
||||
- `docker-compose.dev.yml` — the full stack (Postgres, egress proxy, Provisioner, a persistent
|
||||
"identity" instance, Gateway) on one machine. This is the Phase 1/2A **local dev exception**
|
||||
— production is the two-VM Proxmox split described in `docs/LAB_ARCHITECTURE.md` §1.
|
||||
- `docker-compose.dev.yml` — the full stack (Postgres, egress proxy, Provisioner, Platform API,
|
||||
Gateway) on one machine. This is the Phase 1/2A/2B **local dev exception** — production is
|
||||
the two-VM Proxmox split described in `docs/LAB_ARCHITECTURE.md` §1.
|
||||
|
||||
## Running the full stack locally
|
||||
|
||||
```bash
|
||||
cd platform
|
||||
echo "PROVISIONER_SHARED_SECRET=$(openssl rand -hex 32)" > .env
|
||||
echo "ADMIN_PASSWORD=$(openssl rand -hex 12)" >> .env
|
||||
docker compose -f docker-compose.dev.yml build
|
||||
docker compose -f docker-compose.dev.yml up -d
|
||||
```
|
||||
|
||||
Wait for `identity` to boot (it runs a real k3s cluster, same as any Lab — check with
|
||||
`curl http://localhost:7554/api/health`), then the whole platform is reachable at
|
||||
`http://localhost:4200` (the Gateway) — that's the one origin a student's browser would use.
|
||||
No k3s boot to wait for at this layer anymore (Platform API starts instantly) — the whole
|
||||
platform is reachable at `http://localhost:4200` (the Gateway) right away: students at `/`,
|
||||
instructors at `/admin`.
|
||||
|
||||
## Tests
|
||||
|
||||
- `provisioner/test/run.js` — fast, isolated Provisioner tests (network/container/firewall
|
||||
mechanics, no Gateway/identity involved). Run against `provisioner/docker-compose.dev.yml`.
|
||||
- `test/e2e-phase2a.js` — slow, full-stack tests against the compose file above: roster →
|
||||
login → curriculum → launch → Gateway routing → cross-student rejection → progress relay →
|
||||
reset. Real k3s boots, budget several minutes. Run whenever the Gateway, Provisioner API
|
||||
surface, or the identity backend's progress/roster/curriculum routes change.
|
||||
mechanics, no Gateway/Platform API involved). Run against `provisioner/docker-compose.dev.yml`.
|
||||
- `test/e2e-phase2a.js` — student-flow regression through real session cookies: roster → login
|
||||
→ curriculum → launch → Gateway routing → cross-student rejection → progress relay → reset.
|
||||
- `test/e2e-phase2b.js` — the classroom acceptance workflow: instructor creates a cohort, adds
|
||||
students, assigns curriculum, Prepare Labs (concurrent), students complete different
|
||||
scenarios, instructor resets one, instructor destroys all cohort Labs after class — progress
|
||||
survives every step. Needs `ADMIN_PASSWORD` set (see `platform/.env`).
|
||||
|
||||
Neither substitutes for the manual real-Lab-image checks (node-pty, terminal WebSocket,
|
||||
`kubectl`, scenario validation) in `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md` §8 — those need a
|
||||
browser-equivalent client and aren't automated here.
|
||||
Both e2e suites are slow (real k3s boots) and need the full stack up. Neither substitutes for
|
||||
the manual real-Lab-image checks (node-pty, terminal WebSocket, `kubectl`, scenario validation)
|
||||
in `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md` §8 — those need a browser-equivalent client and
|
||||
aren't automated here.
|
||||
|
||||
## Known limitations
|
||||
|
||||
See `provisioner/README.md` (Phase 1) and `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md` §9
|
||||
(Phase 2A) for the full, honest lists — including the `identity` service's `network_mode:
|
||||
bridge` requirement and its unused-k3s resource cost, both flagged as real, not swept under
|
||||
the rug.
|
||||
See `provisioner/README.md` (Phase 1), `docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md` §9 (Phase
|
||||
2A), and `docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md` §13 (Phase 2B) for the full, honest lists —
|
||||
including in-memory sessions, the single shared admin credential, and exam mode's live
|
||||
bookkeeping staying Lab-local.
|
||||
|
||||
Reference in New Issue
Block a user