Add game data capture vertical slice

This commit is contained in:
jb
2026-07-31 14:34:24 -04:00
parent 5859f84034
commit fee4dc3a78
75 changed files with 12654 additions and 5 deletions
@@ -0,0 +1,69 @@
-- Additive utility-local schema. Migration content is fingerprinted at application time.
CREATE TABLE IF NOT EXISTS schema_migrations (
version INTEGER PRIMARY KEY,
filename TEXT NOT NULL UNIQUE,
checksum TEXT NOT NULL,
applied_at TEXT NOT NULL
);
CREATE TABLE blobs (
sha256 TEXT PRIMARY KEY CHECK(length(sha256) = 64),
byte_size INTEGER NOT NULL CHECK(byte_size > 0),
media_type TEXT NOT NULL CHECK(length(media_type) <= 100),
created_at TEXT NOT NULL
);
CREATE TABLE captures (
capture_id TEXT PRIMARY KEY,
blob_sha256 TEXT NOT NULL REFERENCES blobs(sha256) ON DELETE RESTRICT,
state TEXT NOT NULL,
received_at TEXT NOT NULL,
receipt_token TEXT NOT NULL UNIQUE,
failure_reason TEXT,
revision INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE jobs (
job_id TEXT PRIMARY KEY,
capture_id TEXT REFERENCES captures(capture_id) ON DELETE RESTRICT,
kind TEXT NOT NULL CHECK(length(kind) <= 100),
state TEXT NOT NULL,
attempt INTEGER NOT NULL DEFAULT 0 CHECK(attempt >= 0 AND attempt <= 20),
max_attempts INTEGER NOT NULL CHECK(max_attempts BETWEEN 1 AND 20),
lease_owner TEXT, lease_expires_at TEXT, last_error_id TEXT,
revision INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX jobs_available ON jobs(state, lease_expires_at);
CREATE TABLE ocr_runs (
run_id TEXT PRIMARY KEY, capture_id TEXT NOT NULL REFERENCES captures(capture_id),
engine_id TEXT NOT NULL, engine_version TEXT NOT NULL, created_at TEXT NOT NULL,
state TEXT NOT NULL, payload_json TEXT NOT NULL CHECK(length(payload_json) <= 1000000)
);
CREATE TABLE regions (
region_id TEXT PRIMARY KEY, run_id TEXT NOT NULL REFERENCES ocr_runs(run_id),
region_json TEXT NOT NULL CHECK(length(region_json) <= 10000), created_at TEXT NOT NULL
);
CREATE TABLE classifications (
classification_id TEXT PRIMARY KEY, run_id TEXT NOT NULL REFERENCES ocr_runs(run_id),
classification_json TEXT NOT NULL CHECK(length(classification_json) <= 10000), created_at TEXT NOT NULL
);
CREATE TABLE extraction_candidates (
candidate_id TEXT PRIMARY KEY, run_id TEXT NOT NULL REFERENCES ocr_runs(run_id),
candidate_json TEXT NOT NULL CHECK(length(candidate_json) <= 1000000), created_at TEXT NOT NULL
);
CREATE TABLE routing_decisions (
decision_id TEXT PRIMARY KEY, candidate_id TEXT REFERENCES extraction_candidates(candidate_id),
decision_json TEXT NOT NULL CHECK(length(decision_json) <= 10000), created_at TEXT NOT NULL
);
CREATE TABLE review_events (
event_id TEXT PRIMARY KEY, candidate_id TEXT REFERENCES extraction_candidates(candidate_id),
event_json TEXT NOT NULL CHECK(length(event_json) <= 10000), created_at TEXT NOT NULL
);
CREATE TABLE lineage (
lineage_id TEXT PRIMARY KEY, child_id TEXT NOT NULL, parent_id TEXT NOT NULL,
relation TEXT NOT NULL CHECK(length(relation) <= 100), created_at TEXT NOT NULL
);
CREATE TABLE exports (
export_id TEXT PRIMARY KEY, state TEXT NOT NULL, manifest_json TEXT NOT NULL CHECK(length(manifest_json) <= 1000000), created_at TEXT NOT NULL, revision INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE runtime_failures (
failure_id TEXT PRIMARY KEY, subject_type TEXT NOT NULL, subject_id TEXT NOT NULL,
code TEXT NOT NULL, message TEXT NOT NULL CHECK(length(message) <= 512), created_at TEXT NOT NULL
);
@@ -0,0 +1,38 @@
-- Durable browser-corpus projections and append-only review evidence.
CREATE TABLE capture_labels (
capture_id TEXT PRIMARY KEY REFERENCES captures(capture_id) ON DELETE RESTRICT,
classification_json TEXT NOT NULL CHECK(length(classification_json) BETWEEN 2 AND 4096),
revision INTEGER NOT NULL DEFAULT 0 CHECK(revision >= 0),
labeled_at TEXT NOT NULL
);
CREATE TABLE capture_label_evidence (
evidence_id INTEGER PRIMARY KEY,
capture_id TEXT NOT NULL REFERENCES captures(capture_id) ON DELETE RESTRICT,
replaced_revision INTEGER NOT NULL CHECK(replaced_revision >= 0),
classification_json TEXT NOT NULL CHECK(length(classification_json) BETWEEN 2 AND 4096),
replaced_at TEXT NOT NULL,
UNIQUE(capture_id, replaced_revision)
);
CREATE INDEX capture_label_evidence_capture ON capture_label_evidence(capture_id, evidence_id);
CREATE INDEX captures_blob_sha256 ON captures(blob_sha256);
CREATE INDEX jobs_capture_id ON jobs(capture_id);
CREATE INDEX ocr_runs_capture_id ON ocr_runs(capture_id);
CREATE INDEX runtime_failures_capture_subject ON runtime_failures(subject_type, subject_id);
CREATE INDEX lineage_child_id ON lineage(child_id);
CREATE INDEX lineage_parent_id ON lineage(parent_id);
CREATE TABLE capture_rejections (
rejection_id INTEGER PRIMARY KEY,
capture_id TEXT NOT NULL UNIQUE REFERENCES captures(capture_id) ON DELETE RESTRICT,
rejected_at TEXT NOT NULL
);
CREATE TABLE capture_deletion_intents (
blob_sha256 TEXT PRIMARY KEY REFERENCES blobs(sha256) ON DELETE RESTRICT,
capture_id TEXT NOT NULL UNIQUE CHECK(length(capture_id) BETWEEN 8 AND 64),
byte_size INTEGER NOT NULL CHECK(byte_size > 0 AND byte_size <= 67108864),
capture_state TEXT NOT NULL CHECK(length(capture_state) BETWEEN 1 AND 32),
received_at TEXT NOT NULL CHECK(length(received_at) BETWEEN 1 AND 40),
receipt_token TEXT NOT NULL UNIQUE CHECK(length(receipt_token) BETWEEN 1 AND 128),
failure_reason TEXT,
revision INTEGER NOT NULL CHECK(revision >= 0),
created_at TEXT NOT NULL CHECK(length(created_at) BETWEEN 1 AND 40)
);