zlh-grind/PORTAL_MIGRATION.md

159 lines
3.2 KiB
Markdown

# Portal Migration — APIv1/Pterodactyl → APIv2
## Purpose
This document defines the required migration steps for moving the ZeroLagHub portal from APIv1 / Pterodactyl assumptions to APIv2.
It exists to:
* Prevent silent regressions
* Provide a shared checklist for Codex, Claude, and humans
* Make architectural intent explicit
This file is authoritative.
---
## Migration Scope
### In Scope
* Authentication
* Instance listing & detail views
* Removal of legacy abstractions
* Alignment with APIv2 contracts
### Out of Scope (for now)
* Billing
* RBAC / roles
* Refresh tokens
* xterm / console auth (tracked separately)
---
## Phase 1 — Authentication Alignment ✅ (API-side complete)
### APIv2 Status
* JWT-based auth implemented
* `POST /api/auth/login`
* `GET /api/auth/me`
* Stateless, header-based auth
* No CSRF
* No cookies
### Portal Requirements
* Portal must not attempt credential validation
* Portal must not implement CSRF
* Portal must send `Authorization: Bearer <token>`
* Portal must treat APIv2 as source of truth
---
## Phase 2 — Portal Login Migration (REQUIRED)
### Required Changes
* Login form must submit:
```json
{
"identifier": "<email or username>",
"password": "<password>"
}
```
* Token must be stored in `sessionStorage`
* Token must be attached to all API requests
### Forbidden Patterns
* Cookies for auth
* CSRF tokens
* Legacy `/api/v1/*` calls
* Pterodactyl login flows
---
## Phase 3 — Instances Migration ✅ (API-side verified)
### APIv2 Contract
* `GET /api/instances` returns:
```json
{
"ok": true,
"rows": [ ... ]
}
```
### Portal Expectations
* Portal dashboard must:
* Handle empty arrays gracefully
* Not assume instances always exist
* Render based on API response only
### Explicit Rule
If the portal cannot render with an empty `rows` array, the portal is incorrect.
---
## Phase 4 — Route Protection (UPCOMING)
### Planned Behavior
* Read routes will require auth:
* `GET /api/instances`
* `GET /api/instances/:vmid`
* Write routes may remain internal initially
### Portal Implications
* Portal must handle `401 Unauthorized`
* Portal must redirect to login on auth failure
* No retry loops using legacy logic
---
## Phase 5 — Legacy Removal (MANDATORY)
### Must Be Removed From Portal
* APIv1 client code
* Pterodactyl references
* CSRF utilities
* Cookie-based session logic
* Any fallback to "old behavior"
### Review Rule
If a portal file references Pterodactyl or APIv1, it must be deleted or rewritten.
---
## Verification Checklist (Use Before Merge)
* [ ] Portal login uses `/api/auth/login`
* [ ] Token stored only client-side
* [ ] All API calls include Authorization header
* [ ] Dashboard loads with zero instances
* [ ] No CSRF or cookies present
* [ ] No APIv1 endpoints referenced
---
## Anti-Drift Statement
Any deviation from this document must:
1. Be explicitly discussed
2. Be documented in `SESSION_LOG.md`
3. Update `CONSTRAINTS.md` and/or `ANTI_DRIFT.md`
Silent changes are not allowed.
---
## Ownership
* **Portal Team**: Implementation
* **APIv2**: Contract stability
* **zlh-grind**: Enforcement and truth anchor
---
## Status
* **Created**: 2025-12-28
* **State**: Active
* **Next Update**: After route-level auth enforcement