casebench
test cases straight onto the board.
git clone https://owenrusk.dev/casebench.git
commit 9e0262e94232b80d40de6d31b5743d82f7b3898c parent 9179d6c1f924eae122db7d4086ffccd8a71727d7 author Owen Rusk <owen@papermothgames.com> date 2025-12-09 15:17:40 -0600
schema.sql: the board tables as the bench expects them for a local database. the hub owns the real ones.
| schema.sql | +61 | -0 |
diff --git a/schema.sql b/schema.sql
new file mode 100644
index 0000000..a25ca6d
--- /dev/null
+++ b/schema.sql
@@ -0,0 +1,61 @@
+-- the board tables casebench touches, as it expects them. the hub owns the real
+-- ones; this is for a local database to test against.
+-- createdb casebench && psql casebench -f schema.sql
+
+create table players (
+ id uuid primary key default gen_random_uuid(),
+ handle text not null unique
+);
+
+create table board_cases (
+ player_id uuid not null references players (id) on delete cascade,
+ case_id text not null,
+ title text not null,
+ source text not null default 'runtime' check (source in ('runtime', 'bench')),
+ placed_at timestamptz not null default now(),
+ primary key (player_id, case_id)
+);
+
+create table board_items (
+ player_id uuid not null,
+ case_id text not null,
+ item_id text not null,
+ position int not null,
+ title text not null,
+ body text not null,
+ images text[] not null default '{}', -- sha256 of rows in board_media
+ primary key (player_id, case_id, item_id),
+ foreign key (player_id, case_id) references board_cases on delete cascade
+);
+
+create table board_media (
+ sha256 text primary key,
+ mime text not null,
+ data bytea not null
+);
+
+create table board_notes (
+ id bigserial primary key,
+ player_id uuid not null,
+ case_id text not null,
+ item_id text, -- null: under the case's title
+ body text not null,
+ written_at timestamptz not null default now(),
+ foreign key (player_id, case_id) references board_cases on delete cascade
+);
+
+create table board_locks (
+ player_id uuid not null,
+ case_id text not null,
+ text text not null default 'locked.',
+ lines int not null,
+ salt bytea not null,
+ answer_hashes text[] not null,
+ rest_after int not null,
+ rest_minutes int not null,
+ wrong int not null default 0,
+ resting_until timestamptz,
+ opened_at timestamptz,
+ primary key (player_id, case_id),
+ foreign key (player_id, case_id) references board_cases on delete cascade
+);