diff --git a/docs/routes.md b/docs/routes.md new file mode 100644 index 0000000..b1235b8 --- /dev/null +++ b/docs/routes.md @@ -0,0 +1,44 @@ +# Routes & how to test (dev) + +The front end picks what to render from the URL (see `src/main.tsx`). Vite dev +server runs on `http://localhost:5173`. + +| URL | Renders | For | +|---|---|---| +| `/` | Splash → campaign (walks the story graph: cutscene → dialogue → hands off to the board) | Narrative / player flow | +| `/node/` | **Dev/admin teleport** to a story node; a *level* node lands you on that level's board clone | Jumping around the tree while testing | +| `/level/` | A level board directly (add `?edit=1` to author) | Board work / editing | +| `/admin` | Admin panel (mysteries, NPCs, assets, graph editor) | Authoring | +| `/?phone=1` | 3D clamshell phone dialer spike | Phone prototype | + +## Game state (demo) + +A player's whole state is two things on their **playthrough**: +- `playthroughs.current_node_id` — *where* they are (which node; a level node also has `current_level_id`, the board clone). +- `achievements` — *what* they've earned (`(playthrough_id, flag_key, awarded_by_node_id)`). + +Normal play resolves position via `GET /api/playthroughs/current`. `/node/:id` +is just the dev override that *writes* `current_node_id` (the `goto` teleport). + +## Quick test recipes + +**Play the campaign:** open `/` → New Game → click through the intro/briefing → you land on the board. + +**Jump straight to a node:** `/node/`. List the current node ids: +```bash +docker exec osint-board-db psql postgres://osint:osint_secret@localhost:5432/osint_dev -At -F' | ' \ + -c "SELECT n.id,n.node_type,n.label FROM osint.story_nodes n JOIN osint.mysteries m ON m.id=n.mystery_id WHERE m.slug='glass-harbor' ORDER BY n.ypos;" +``` +(The `level` row is the board.) + +**Phone seam (achievements):** `/?phone=1` → dial `55501` (Elias) → voicemail → click **grant elias_number_callable** → the handset glows → dial `55501` again → connects. Voss `55502` stays voicemail; other numbers = unobtainable. + +**Reset to a clean slate:** `docker exec osint-board-db psql postgres://osint:osint_secret@localhost:5432/osint_dev -c "TRUNCATE osint.playthroughs CASCADE;"` then reload (playthroughs + achievements are wiped; `/` shows the splash again). + +## Dev-only endpoints + +Both are gated to `NODE_ENV !== 'production'` (swap for the admin JWT when we want them in a deployed build): +- `POST /api/playthroughs/:id/goto` `{ nodeId }` — teleport (powers `/node/:id`). +- `POST /api/playthroughs/:id/achievements` `{ flagKey }` — grant an achievement (stand-in until the server-side rule engine fires them from play). `GET` the same path lists earned achievements. + +Backend changes need a container rebuild: `docker compose -f docker-compose.dev.yml up -d --build app`. The Vite front end is live on 5173.