# Phoenix Portal — API Railing Wiring **Purpose:** How the Phoenix Portal (UX/UI) calls the Phoenix API Railing for infrastructure, VMs, and health. **Related:** Phoenix API Railing Spec (proxmox repo: `docs/02-architecture/PHOENIX_API_RAILING_SPEC.md`) --- ## 1. Base URL Portal should call the **Phoenix API** (GraphQL + REST). When running locally: `http://localhost:4000`. In production: `https://api.phoenix.sankofa.nexus` (or the configured API URL). All REST railing routes are under `/api/v1/`. --- ## 2. Infrastructure Overview (Portal) | Portal area | REST endpoint | Notes | |-------------|---------------|--------| | Cluster nodes | `GET /api/v1/infra/nodes` | Returns `{ nodes: [...] }`; each node has `node`, `status`, `cpu`, `mem`, etc. | | Storage pools | `GET /api/v1/infra/storage` | Returns `{ storage: [...] }`. | **Auth:** Use the same session/token as for GraphQL (Keycloak OIDC). The Phoenix API forwards these to the railing (phoenix-deploy-api or internal) when `PHOENIX_RAILING_URL` is set. --- ## 3. VM/CT List and Actions (Portal) | Portal area | REST endpoint | Notes | |-------------|---------------|--------| | List VMs/CTs | `GET /api/v1/ve/vms?node=` | Optional `node` query to filter by Proxmox node. | | VM/CT status | `GET /api/v1/ve/vms/:node/:vmid/status?type=lxc|qemu` | `type=lxc` for containers. | | Start | `POST /api/v1/ve/vms/:node/:vmid/start?type=lxc|qemu` | | | Stop | `POST /api/v1/ve/vms/:node/:vmid/stop?type=lxc|qemu` | | | Reboot | `POST /api/v1/ve/vms/:node/:vmid/reboot?type=lxc|qemu` | | **Auth:** Required. Gate destructive actions (start/stop/reboot) by role in the API; Portal should only show actions when the user has permission. --- ## 4. Health / Dashboards (Portal) | Portal area | REST endpoint | Notes | |-------------|---------------|--------| | Health summary | `GET /api/v1/health/summary` | Returns `{ status, hosts, alerts, updated_at }`. | | Metrics (PromQL) | `GET /api/v1/health/metrics?query=` | Proxy to Prometheus; use for custom dashboards. | | Active alerts | `GET /api/v1/health/alerts` | Returns `{ alerts: [...] }`. | --- ## 5. Tenant-Scoped (Client API) For **tenant** users (API key or JWT with tenant scope): | Endpoint | Description | |----------|-------------| | `GET /api/v1/tenants/me/resources` | Resources for the current tenant (from `tenantContext`). | | `GET /api/v1/tenants/me/health` | Health summary (proxied to railing when configured). | **Auth:** Require `Authorization: Bearer ` with tenant claim or API key with tenant scope. --- ## 6. Keycloak Integration Portal authenticates via Keycloak (OIDC). Backend (Portal server or BFF) should obtain a token and call the Phoenix API with `Authorization: Bearer `. The Phoenix API validates the token and sets `tenantContext` from the token claims; railing proxy and tenant me routes use that context. --- ## 7. Implementation Checklist - [ ] **3.1** Portal: Infrastructure overview page — fetch `GET /api/v1/infra/nodes` and `GET /api/v1/infra/storage`, display hosts and storage. - [ ] **3.2** Portal: VM/CT list — fetch `GET /api/v1/ve/vms`, display table; buttons for start/stop/reboot call the POST endpoints. - [ ] **3.3** Portal: Health/dashboards — fetch `GET /api/v1/health/summary` and optionally `GET /api/v1/health/alerts`; render status and alerts. - [ ] **3.4** Keycloak: Ensure Portal backend or BFF uses server-side token for API calls; token includes tenant when applicable.