feat: admin page with dynamic converter loading

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>
This commit is contained in:
Falkan
2026-03-17 13:55:11 -04:00
parent 067fd445ef
commit d1f51c141e
27 changed files with 1915 additions and 81 deletions

11
data/units.json Normal file
View File

@@ -0,0 +1,11 @@
{
"units": [
{ "id": "blurb", "label": "Blurb", "labelPlural": "Blurbs", "symbol": "bl", "group": "florp", "toBase": 1.0 },
{ "id": "snorp", "label": "Snorp", "labelPlural": "Snorps", "symbol": "sn", "group": "florp", "toBase": 7.5 },
{ "id": "krumble", "label": "Krumble", "labelPlural": "Krumbles", "symbol": "kr", "group": "florp", "toBase": 0.25 },
{ "id": "wobbit", "label": "Wobbit", "labelPlural": "Wobbits", "symbol": "wb", "group": "florp", "toBase": 144.0 }
],
"groups": [
{ "id": "florp", "label": "Florp Units", "baseUnitId": "blurb", "toUniversal": 1.0 }
]
}