# Portal - Current State This file records what is believed to be implemented now in `zpack-portal`. ## Runtime / tooling baseline - Portal is aligned to the Node 24 runtime line used by the API repo. - Current `package.json` pins `engines.node` to the Node 24 line. - Portal uses Next 16, React 18, TypeScript, Tailwind, Axios, and WebSocket console. - Lint/build have been reported passing after the recent async create/support/billing validation work, with only existing unrelated warnings where noted. ## Public marketing / SEO site - Public marketing follows a hybrid SaaS structure: - homepage acts as conversion flow - separate pages support deeper product/SEO intent - Homepage and public copy position ZeroLagHub as browser dev environments plus managed server hosting, not Minecraft-only hosting. - Pricing is positioned as Starter / Pro / Performance workload tiers. - SEO/intent pages exist for Minecraft hosting, modded Minecraft hosting, and browser dev environments. - LXC/system-container differentiator is represented carefully without unsupported Minecraft performance claims. - Mobile responsiveness has had a targeted pass; complex console/file/backup panels are basic-mobile-usable rather than full mobile-native experiences. ## Server create / async provisioning UI - Portal treats `POST /api/instances` returning `202 Accepted` as successful accepted creation. - Create requests send a per-click `Idempotency-Key`. - Portal stores `operationId`, `requestId`, `statusUrl`, status, phase, and eventual `serverId` in pending creation records. - `/servers` polls the operation `statusUrl` while keeping existing server-list polling. - Pending creation UI appears as an inline server card under the correct `GAME` or `DEV` section. - Pending card states include `Request sent`, `Queued`, `Running: `, `Waiting for server record`, `Ready`, and failed phase/error states. - When `serverId` appears or the operation completes, Portal refreshes the server list and replaces the placeholder with the real server card. - This visually validated the previous multi-create/modal-overlap issue; async inline cards are now the launch model. ## Readiness / operation UI - Portal consumes API-normalized state. - Portal understands readiness and operation fields such as `ready`, `operationInProgress`, `operationType`, `maintenance`, `operationStartedAt`, and `operationMessage`. - Targeted `409` and `503` UX messaging exists for operation conflicts and not-ready states. - Server card and game console readiness labels map ready, stopped, starting, stopping, restarting, maintenance, provisioning/network-pending, plan-limit, billing states, and true error states to explicit user-facing labels. - `connectable === false` no longer automatically maps to `Needs attention`. - Game server readiness and dev container readiness are separated in the server list. - Host/container lifecycle status is surfaced from the LXC host layer, including active host-operation polling. - Server list refresh waits for per-server status enrichment before committing merged state, preventing transient readiness/IDE badge flips. ## Billing / announcements - Billing state/customer messaging is handled through the announcements system for launch. - Portal billing suspension announcement was visually validated. - Authenticated `/api/announcements` can surface billing suspension/status messaging for the affected user. - Dedicated billing UI panels remain a later enhancement unless announcements prove insufficient. - Portal must still handle stable billing error codes from API actions, including `BILLING_SUSPENDED`, `BILLING_BACKUP_BLOCKED`, `BILLING_PAYMENT_REQUIRED`, and related retained/past-due states. ## Support - The authenticated support surface posts to `/api/support/create`. - Portal support form submit was validated live after the API support route was added. - Portal shows success state after valid support ticket submit. - Customer acknowledgement email and Discord `#support` alert were validated outside Portal. - Support admin ticket view, support triage diagnostics, attachments, inbound reply parsing, and self-hosted helpdesk integration are post-launch enhancements. ## Backup UI - Game backup UI exists for list, create, restore, and delete. - Portal uses API routes, not direct agent calls. - Backup metadata is normalized and displayed when API includes metadata fields. - Backup/restore actions provide user feedback and progress/elapsed time during active operations. - Restore start is async at the API layer and Portal should treat accepted restore as success then poll status. - Live backup-route validation with a current game backup fixture remains a launch validation follow-up. ## Console / action gating - Console command transport uses POST JSON through API. - Previous blanket `ready === false` gating bug for game actions was fixed. - Start is not blocked merely because a stopped server is not ready. - Backup actions are not blocked purely by `ready === false`; backend validity decides. - Terminal reliability hardening remains open: WebSocket connect timeout, error cleanup, streaming state reset, and recoverable `Connecting...` button state. ## Hosted IDE - Console and server-list `Open IDE` actions request `/api/dev/{serverId}/ide-token`. - Portal opens the hosted URL returned by API, falling back to configured API base for relative URLs. - DEV cards show compact IDE indicators and inline Open/Start/Restart/Stop controls. - code-server service actions call `/api/dev/{serverId}/codeserver/start`, `/restart`, and `/stop`. - Hosted IDE access was validated during recent dev provisioning tests. ## API client layer - Portal uses API-mediated transport rather than direct agent calls. - The old Portal-internal `/api/agent/{serverId}/{action}` bridge has been removed from the frontend repo. - Server deletion has migrated to `DELETE /api/servers/{id}` through the normal user JWT API client. - Portal does not add or expose `INTERNAL_API_TOKEN` in browser code. - Delete UX maps API responses explicitly: accepted/already-in-progress, login required, not owned/missing, stop-host-before-deleting, and teardown failure. - Browser-side API helpers for admin/internal-sensitive surfaces must remain audited and not accidentally reachable from normal user UI. ## Dashboard / IA - Dashboard spotlight server card uses API-backed server data instead of placeholder entries. - Spotlight card routes users into supported `/servers` surface. - Spotlight card recognizes DEV containers and mirrors server-list badges, including IDE indicator, readiness badge, and host status. - Hub navigation includes Billing, Profile, and Support. - Hub shell covers authenticated account/control-surface pages including billing, profile, and support. ## Still true - Portal should track API auth / JWT behavior closely because API-side token hardening can require Portal compatibility verification. - Portal cleanup should remain behavior-preserving; build/lint green status is part of the current baseline. - Mobile responsiveness is no longer a from-zero open item, but it still needs periodic device/browser validation as UI surfaces change. - Browser-visible code must not gain admin/internal shared secrets; admin/internal routes should stay API/server-side concerns unless a deliberate admin UI is built.