- ALLOWED_ORIGINS and NODE_ENV now read via $env/dynamic/private so Vite dev
server picks them up correctly from .env
- .env.example: document ALLOWED_ORIGINS with dev IP example
- .env: add http://192.168.0.94:5173 to ALLOWED_ORIGINS for local dev
- SESSION_SECRET and PASSWORD_HASH moved out of config.json into env vars
- data.ts: AppConfig no longer holds secrets; loadConfig/loadData seed from
defaults/ on first run if data/ files are missing
- auth.ts: requireAuth/authRequest read SESSION_SECRET from process.env directly
- login/+server.ts: reads PASSWORD_HASH and SESSION_SECRET from process.env
- defaults/config.json: ships with image (no secrets)
- defaults/units.json: ships with image as initial unit data
- package.json: add dotenv dep; start/serve load .env via -r dotenv/config
- Dockerfile: copy defaults/ into image; data/ is PVC-only
- .env.example: documents required env vars for local dev
- Remove k8s/ — managed externally
Implements full admin interface for managing units and groups.
Migrates converter from static imports to server-side data loading.
- Switch adapter-static → adapter-node
- Add bcryptjs session auth with HMAC-signed cookies
- Add data/units.json and data/config.json data layer
- Add atomic file writes via temp-file rename
- Add public GET /api/units endpoint
- Add auth-gated admin CRUD API for units and groups
- Add two-panel admin UI with group tree and edit forms
- Add YOLO mode toggle for cross-group conversions
- Add visual group dividers in converter results grid
- Update ResultItem type for nullable convertedValue and isYolo flag
- Group deletion supports reassign/orphan with toBase recalculation
Rollback point: 067fd44
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>