Add authorable per-level briefing checklist

The case briefing showed a wall of body text. Add a checklist of short,
player-tickable steps authored per level: a new `checklist` on the level brief
(table osint.level_brief_checklist_items), read/written with the board, cloned
on template freeze/instantiate, and carried through the mystery importer and the
mystery:pull exporter. Player tick state is guidance-only, persisted locally per
level rather than on the shared board. Convert the Barricelli inventor-proof
brief from prose into a short intro plus a six-step checklist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 22:50:50 +02:00
co-authored by Claude Opus 4.8
parent 95b17e945c
commit e37dc651f3
9 changed files with 53 additions and 12 deletions
+3
View File
@@ -15,6 +15,7 @@ export async function clearBoard(client: PoolClient, boardId: string) {
await client.query('DELETE FROM osint.board_views WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.brief_concepts WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.level_briefs WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.level_brief_checklist_items WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.level_goals WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.evidence_match_rules WHERE board_id=$1', [boardId])
await client.query('DELETE FROM osint.metadata_fields WHERE board_id=$1', [boardId])
@@ -253,6 +254,8 @@ export async function cloneBoard(client: PoolClient, sourceBoardId: string, targ
const brief = await client.query<{ body: string }>('SELECT body FROM osint.level_briefs WHERE board_id=$1', [sourceBoardId])
if (brief.rows[0]) await client.query('INSERT INTO osint.level_briefs (board_id,body) VALUES ($1,$2)', [targetBoardId, brief.rows[0].body])
const checklist = await client.query<{ sort_order: number; text: string }>('SELECT sort_order,text FROM osint.level_brief_checklist_items WHERE board_id=$1 ORDER BY sort_order,id', [sourceBoardId])
for (const row of checklist.rows) await client.query('INSERT INTO osint.level_brief_checklist_items (id,board_id,sort_order,text) VALUES ($1,$2,$3,$4)', [randomUUID(), targetBoardId, row.sort_order, row.text])
const concepts = await client.query<{
id: string; label: string; context_text: string; sort_order: number; expected_party_kind: string | null; resolved_party_exhibit_id: string | null
}>('SELECT id,label,context_text,sort_order,expected_party_kind,resolved_party_exhibit_id FROM osint.brief_concepts WHERE board_id=$1 ORDER BY sort_order,id', [sourceBoardId])