# API layer ## Server shape - Aurora uses Bun's native `serve()` API in `api/src/server.ts`. - Route modules are aggregated in `api/src/routes/index.ts`. - A route module returns `null` when it does not match so the dispatcher can continue. - After route handling, the server tries `panel/dist` for SPA/static files. ## Authentication and authorization - OAuth routes live in `api/src/routes/auth.routes.ts`. - Sessions are stored in memory and keyed by the `aurora_session` cookie. - Session TTL is 7 days. - Login succeeds only for users already present in the `users` table. - Role is `admin` if the Discord ID is in `ADMIN_USER_IDS`, otherwise `player`. - Redirects after login are intentionally restricted to localhost or relative paths. Current access rules from `api/src/routes/index.ts`: - public: `/auth/*`, `/api/health` - player allow-list: `/api/stats`, `/api/health`, `/api/me` - everything else under `/api/*`: admin-only `/api/me/inventory` is handled by `users.routes.ts` and still depends on a valid session. ## Response conventions - `jsonResponse()` serializes `bigint` values as strings. - `errorResponse()` returns `{ error, details? }`. - `parseBody()` and `parseQuery()` validate with Zod and return a `Response` on failure. - The API does not use a framework-level middleware stack; each route handles its own parsing and branching. ## WebSocket - Endpoint: `/ws` - Requires an authenticated session - Dashboard channel: `dashboard` - Lobby channel: `lobby` - Room-specific messaging is handled inside `GameServer` - Dashboard broadcasts `STATS_UPDATE` every 5 seconds while clients are connected - `NEW_EVENT` broadcasts are wired from `shared/lib/events` Hard limits: - max connections: 200 - max payload: 16 KB - idle timeout: 60 seconds ## Static files - Built panel assets are served from `panel/dist` - `/assets/*` serves files from `bot/assets/graphics` - `/api/*`, `/auth/*`, `/ws`, and `/assets/*` bypass the SPA fallback ## Route notes - `items.routes.ts` supports both JSON and multipart form data for item creation. - `settings.routes.ts` writes DB-backed game settings and emits the reload-commands event. - `guild-settings.routes.ts` invalidates the guild config cache after writes. - `lootdrops.routes.ts` delegates spawning/deletion to bot-side handlers because Discord message creation happens there. ## Gotchas - Sessions and some caches are in-memory only and are lost on restart. - The server registers game plugins at startup; duplicate registration throws. - BigInt-safe JSON matters for nearly every domain route. - The panel's auth flow depends on `PANEL_BASE_URL` matching the OAuth callback origin.