# 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=<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=<encoded PromQL>` | 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 <token>` 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 <access_token>`. 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.
