Issue #10 — the MISSIONS tab is now functional (no placeholder data):
DB: new missions table (type/description/target/condition/reward/state); deterministic seeded generation anchored by turn; board topped up to ≥3 AVAILABLE after every action; one ACTIVE at a time. Backfill step v6 (SCHEMA_VERSION 5→6) — old saves get their board on first read, no DB wipe.
Types: DELIVER (jump to target system), EXPLORE (scan N bodies), FIND (haul an item of a kind). Completion hooks inside jumpToSystem/explorePlanet before persist → completion + reward + top-up land in one atomic write; rewards granted as inventory rows.
API:GET /api/missions, POST /api/missions/{id}/accept (400/404/409, no mutation on failure); OpenAPI now 14 paths.
UI: live mission cards with state badges + ACCEPT enabled only when AVAILABLE and nothing else active; refetch on tab open, responses applied directly.
Tests: unit 59 → 73 (generation determinism over 200 draws, top-up idempotency, v6 backfill, accept validation, per-type completion incl. wrong-system non-completion + reward accumulation); e2e 13 → 14 (accept in UI → complete via scan loop/BFS jump → DONE + reward in hold; board deep-equal across restart).
Local verification: tsc ✓, vitest 73/73 ✓, playwright --list 14 ✓, next build clean (7 tab triggers SSR-rendered) + live API smoke.
Issue #10 — the MISSIONS tab is now functional (no placeholder data):
- **DB:** new `missions` table (type/description/target/condition/reward/state); deterministic seeded generation anchored by turn; board topped up to ≥3 AVAILABLE after every action; one ACTIVE at a time. Backfill step v6 (`SCHEMA_VERSION` 5→6) — old saves get their board on first read, no DB wipe.
- **Types:** DELIVER (jump to target system), EXPLORE (scan N bodies), FIND (haul an item of a kind). Completion hooks inside `jumpToSystem`/`explorePlanet` before persist → completion + reward + top-up land in one atomic write; rewards granted as inventory rows.
- **API:** `GET /api/missions`, `POST /api/missions/{id}/accept` (400/404/409, no mutation on failure); OpenAPI now 14 paths.
- **UI:** live mission cards with state badges + ACCEPT enabled only when AVAILABLE and nothing else active; refetch on tab open, responses applied directly.
- **Tests:** unit 59 → 73 (generation determinism over 200 draws, top-up idempotency, v6 backfill, accept validation, per-type completion incl. wrong-system non-completion + reward accumulation); e2e 13 → 14 (accept in UI → complete via scan loop/BFS jump → DONE + reward in hold; board deep-equal across restart).
Local verification: tsc ✓, vitest 73/73 ✓, playwright --list 14 ✓, next build clean (7 tab triggers SSR-rendered) + live API smoke.
New missions table (schema + DDL). Pure model in lib/game/missions.ts:
DELIVER / EXPLORE / FIND contracts generated from missionRng(seed, turn),
board always topped up to >=3 AVAILABLE after every action. save.ts wires
SCHEMA_VERSION 5 -> 6 with a v6 backfill step and completion hooks inside
jumpToSystem/explorePlanet (one atomic persist). Unit tests cover generation
determinism, top-up idempotency, backfill, accept validation and per-type
completion incl. reward accumulation.
Routes call ensureSave first (mission functions assume an initialized save),
map MissionError to 404/409 and non-integer path ids to 400. OpenAPI spec in
code gains both paths + the Mission schema (12 -> 14 paths); openapi.test.ts
covers the new shapes.
Self-fetching MissionPanel (world-map pattern — refetches on each tab open,
accept responses applied directly). One card per contract: type title + state
badge, CONTRACT // #id line, objective, reward line, EXPLORE progress line.
ACCEPT enabled only when AVAILABLE and nothing else is ACTIVE. Placeholder
encounter content removed.
smoke: pick an AVAILABLE contract (non-DELIVER preferred), accept it through
the UI (card flips ACTIVE, button disables), complete via API — scan loop for
EXPLORE/FIND, BFS jump path for DELIVER — assert DONE and the reward landed in
the hold. state: mission board deep-equal across the mid-run container restart.
CI run 358: the ACTIVE assertion used exact text but badge.tsx renders a
'●' dot prefix for ACTIVE variants (text is '●ACTIVE'), so it could never
match. And attempt 1's accept persisted an ACTIVE mission, leaving every
ACCEPT button disabled on retry. Drop exact matching and, when a leftover
active mission exists, assert the UI state and complete that one instead of
re-accepting.
kamilkrzywda
scheduled this pull request to auto merge when all checks succeed 2026-09-29 04:21:12 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Issue #10 — the MISSIONS tab is now functional (no placeholder data):
missionstable (type/description/target/condition/reward/state); deterministic seeded generation anchored by turn; board topped up to ≥3 AVAILABLE after every action; one ACTIVE at a time. Backfill step v6 (SCHEMA_VERSION5→6) — old saves get their board on first read, no DB wipe.jumpToSystem/explorePlanetbefore persist → completion + reward + top-up land in one atomic write; rewards granted as inventory rows.GET /api/missions,POST /api/missions/{id}/accept(400/404/409, no mutation on failure); OpenAPI now 14 paths.Local verification: tsc ✓, vitest 73/73 ✓, playwright --list 14 ✓, next build clean (7 tab triggers SSR-rendered) + live API smoke.