# XFEServerManager Web UI

Responsive React/TypeScript dashboard embedded in each Forge server JAR. The production build uses relative asset URLs and does not require Node.js at server runtime.

## Commands

```text
npm install
npm run dev
npm test
npm run build
```

During development, Vite proxies `/api` to `http://127.0.0.1:8765`. A production server may set `window.__XFESM_API_BASE__` before the entry script; otherwise the client uses `/api/v1`.

## API contract used by the UI

The client accepts either a bare JSON value or `{ "data": ... }`. Collection routes may return a bare array or `{ "items": [], "nextCursor": "...", "total": 0 }`.

- `GET /api/v1/status`, `/auth/session`, `/features`, `/settings`
- `POST /api/v1/auth/login`, `/auth/logout`, `/console/commands`
- `GET /api/v1/players`, `/policies`, `/audit`
- `POST /api/v1/players/{uuid}/actions`, `/policies/simulate`, `/policies/{id}/publish`
- `GET|POST /api/v1/moderation/cases`, `GET /api/v1/claims`
- `GET /api/v1/world/changes`, `POST /api/v1/rollbacks/preview`, `/rollbacks`
- `GET /api/v1/events` as SSE, with optional typed events: `server-status`, `player-changed`, `policy-published`, `audit`, `operation`, `moderation`, `claim`, and `world-change`

Mutations send `X-XFESM-Request-ID`, `Idempotency-Key`, and the session-provided `X-CSRF-Token`. Requests always use same-origin credentials. Network failure is rendered as an explicit offline state; the application never substitutes demo metrics or players.
