feat: task 1.4 runtime config endpoint
Three-file config module under src/config/: - schema.ts: RuntimeConfigSchema (directusUrl, liveWsUrl, businessWsUrl, optional googleMapsKey, env enum). Custom UrlOrAbsolutePath validator accepts http(s)/ws(s) URLs plus paths starting with /. - load.ts: loadConfig() fetches /config.json with cache: 'no-store', safeParse, throws ConfigValidationError on schema failure. - context.ts: RuntimeConfigContext + useRuntimeConfig() hook (no JSX). - provider.tsx: RuntimeConfigProvider — loading / ready / error states. Single retry after 500ms on network failure; renders zod issues on validation failure for debuggability. public/config.json: committed dev defaults (relative paths matching the Vite proxy from 1.3). src/main.tsx wraps App in <RuntimeConfigProvider>. README gains a Runtime config section with the schema table. Deviation: spec sketched provider+hook in one context.tsx. Split into context.ts (hook only) and provider.tsx (component only) to satisfy react-refresh/only-export-components without adding an eslint override.
This commit is contained in:
@@ -57,6 +57,22 @@ Override per-developer by copying `.env.example` to `.env.local` and editing —
|
||||
|
||||
If the dev port `5173` collides with another Vite app, run with `VITE_PORT=5174 pnpm dev` (or pin a different port in `vite.config.ts`).
|
||||
|
||||
## Runtime config
|
||||
|
||||
`/config.json` is fetched at app boot, validated with zod, and held in a React context (`useRuntimeConfig()` hook). One image, multiple environments — the deploy stack overrides the file via a Docker volume mount; the SPA never rebuilds for an env-only change.
|
||||
|
||||
| Field | Type | Notes |
|
||||
| --------------- | -------- | ---------------------------------------------------------------------------- |
|
||||
| `directusUrl` | URL/path | Directus REST + GraphQL base. Same-origin path or absolute URL. |
|
||||
| `liveWsUrl` | URL/path | Processor live-position WebSocket URL. |
|
||||
| `businessWsUrl` | URL/path | Directus business-plane WebSocket URL. |
|
||||
| `googleMapsKey` | string? | Optional. If absent, Google tile sources are hidden in the UI. |
|
||||
| `env` | enum | `dev` / `stage` / `prod` — used in log labels and feature-flag conditionals. |
|
||||
|
||||
URLs may be absolute (`http(s)://`, `ws(s)://`) or absolute paths starting with `/`. Relative paths work because the SPA is always same-origin to its backends. The committed `public/config.json` uses path-only defaults that match the dev proxy.
|
||||
|
||||
In stage/prod the deploy stack mounts an override file at `/usr/share/nginx/html/config.json`; see `trm/deploy/README.md` (lands in Phase 1.10).
|
||||
|
||||
## CI
|
||||
|
||||
`.gitea/workflows/build.yml` (lands in Phase 1.9) runs the four gates — typecheck, lint, format:check, build — and publishes a Docker image on push to `main`.
|
||||
|
||||
Reference in New Issue
Block a user