# 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 ` * Portal must treat APIv2 as source of truth --- ## Phase 2 — Portal Login Migration (REQUIRED) ### Required Changes * Login form must submit: ```json { "identifier": "", "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