Create PORTAL_MIGRATION.md - Authoritative migration guide from APIv1/Pterodactyl to APIv2 with phases, checklist, anti-drift
This commit is contained in:
parent
dd123a0613
commit
bb63de3e48
158
PORTAL_MIGRATION.md
Normal file
158
PORTAL_MIGRATION.md
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
# 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
|
||||||
Loading…
Reference in New Issue
Block a user