Add Phase 6: multi-server admin panel (server registry + settings)
Gate a new /api/admin/* route set (register/list/update/delete servers) behind a single shared MCMAPPER_ADMIN_TOKEN header, and add a /admin frontend page (Alpine) to unlock, register new servers, and edit authMode/anonymousChatAllowed/waypointFormat per server — these columns already existed but were only editable via direct DB edit until now. Written test-first per the project's TDD workflow: admin.ts's domain logic, the index.ts route wiring, and a new e2e/tests/admin.spec.ts covering the token gate and register/edit/delete round trip through the real browser UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015tKdPZt78zbPUZMXWzKEKt
This commit is contained in:
@@ -61,20 +61,37 @@ docker compose up
|
||||
migrations on startup (see `api/src/db/migrate.ts`); `worker` consumes the `mcmapper:dirty-chunks`
|
||||
Redis stream via a consumer group (`mcmapper-workers`) so multiple instances split work safely.
|
||||
|
||||
### Phase 1: connecting a mod instance
|
||||
### Connecting a mod instance
|
||||
|
||||
There's no admin registration API yet (Phase 6) — seed one server row by hand, then point the
|
||||
mod's `MapperConfig` at the same token:
|
||||
Register a server via the admin panel at `/admin` (set `MCMAPPER_ADMIN_TOKEN` first — see
|
||||
"Admin panel" below), or seed one row by hand for scripted/headless setup:
|
||||
|
||||
```
|
||||
docker compose run --rm api bun run seed
|
||||
```
|
||||
|
||||
reads `MCMAPPER_SEED_SERVER_NAME`/`MCMAPPER_SEED_SERVER_TOKEN` from `api/.env.example` (edit
|
||||
those first, or override with `-e`). Once the mod connects and sends its initial chunk backfill,
|
||||
tiles appear at `GET /api/tiles/:serverId/:dimension/:zoom/:tileX/:tileY.png` (zoom is always `0`
|
||||
for now — see `worker/src/render/cpu.rs`) and the frontend's Leaflet viewer picks them up
|
||||
automatically from `GET /api/servers`.
|
||||
those first, or override with `-e`). Either way, point the mod's `MapperConfig#serverToken` at
|
||||
the resulting token. Once the mod connects and sends its initial chunk backfill, tiles appear at
|
||||
`GET /api/tiles/:serverId/:dimension/:zoom/:tileX/:tileY.png` (zoom is always `0` for now — see
|
||||
`worker/src/render/cpu.rs`) and the frontend's Leaflet viewer picks them up automatically from
|
||||
`GET /api/servers`.
|
||||
|
||||
### Admin panel
|
||||
|
||||
`/admin` (linked from the map page's header) manages the server registry: register new servers
|
||||
(generates their token — never admin-supplied, so it can't collide with or be guessed from
|
||||
anything else), and edit `authMode`, `anonymousChatAllowed`, and `waypointFormat` per server.
|
||||
It's gated behind a single shared secret, not a per-account role (this is a single-operator
|
||||
backend) — set `MCMAPPER_ADMIN_TOKEN` in `api/`'s untracked `.env` (see `api/.env.example`),
|
||||
restart `api`, then enter that same value into the panel's unlock prompt. Leaving it unset
|
||||
disables every `/api/admin/*` route (401), it does not default to open. The token is remembered
|
||||
in the browser's `localStorage` after unlocking, same pattern as the player-facing session token
|
||||
(see `api/src/link.ts`'s doc comment).
|
||||
|
||||
Settings not exposed here yet (which map types render, dimension filtering, player-position
|
||||
visibility) don't have underlying features built for them either — no point in a knob nothing
|
||||
reads. They'll gain admin UI alongside the feature that needs them.
|
||||
|
||||
## Running tests
|
||||
|
||||
@@ -121,12 +138,14 @@ bunx playwright test
|
||||
(unlike the `bun test` section above): throwaway Postgres/Redis/MinIO containers
|
||||
(`mcmapper-e2e-*`, distinct names/ports from the `bun test` ones so both can run at once),
|
||||
migrations, a seeded server + linked account/session + a 5x5-chunk terrain footprint around the
|
||||
world origin, then the `api`/`frontend`/proxy processes. `global-teardown.ts` kills every spawned
|
||||
process and removes the containers afterward. Covers the two UI flows most worth a real
|
||||
click-through: the marker click-to-place/edit popup (`tests/markers.spec.ts`, including that a
|
||||
marker created while linked shows up in a second browser context with the same session — the
|
||||
cross-device sync claim) and the region-select drag + glTF export (`tests/region-export.spec.ts`,
|
||||
including a real triggered file download).
|
||||
world origin, then the `api`/`frontend`/proxy processes (the `api` process is started with a
|
||||
fixed `MCMAPPER_ADMIN_TOKEN` for `tests/admin.spec.ts` to use — see `config.ts`'s `ADMIN_TOKEN`).
|
||||
`global-teardown.ts` kills every spawned process and removes the containers afterward. Covers the
|
||||
UI flows most worth a real click-through: the marker click-to-place/edit popup
|
||||
(`tests/markers.spec.ts`, including that a marker created while linked shows up in a second
|
||||
browser context with the same session — the cross-device sync claim), the region-select drag +
|
||||
glTF export (`tests/region-export.spec.ts`, including a real triggered file download), and the
|
||||
admin panel's token gate + server register/edit/delete round trip (`tests/admin.spec.ts`).
|
||||
|
||||
## Attribution
|
||||
|
||||
|
||||
Reference in New Issue
Block a user