pub const MIGRATION_V1_SQL: &str = r"
CREATE TABLE IF NOT EXISTS items (
item_id TEXT PRIMARY KEY,
title TEXT NOT NULL,
description TEXT,
kind TEXT NOT NULL CHECK (kind IN ('task', 'goal', 'bug')),
state TEXT NOT NULL CHECK (state IN ('open', 'doing', 'done', 'archived')),
urgency TEXT NOT NULL DEFAULT 'default' CHECK (urgency IN ('urgent', 'default', 'punt')),
size TEXT CHECK (size IS NULL OR size IN ('xs', 's', 'm', 'l', 'xl')),
parent_id TEXT REFERENCES items(item_id) ON DELETE SET NULL,
compact_summary TEXT,
snapshot_json TEXT,
is_deleted INTEGER NOT NULL DEFAULT 0 CHECK (is_deleted IN (0, 1)),
deleted_at_us INTEGER,
search_labels TEXT NOT NULL DEFAULT '',
created_at_us INTEGER NOT NULL,
updated_at_us INTEGER NOT NULL,
CHECK (item_id GLOB '[a-z][a-z]-*' OR item_id GLOB '[a-z][a-z][a-z]-*')
);
CREATE TABLE IF NOT EXISTS item_labels (
item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
label TEXT NOT NULL CHECK (length(trim(label)) > 0),
created_at_us INTEGER NOT NULL,
PRIMARY KEY (item_id, label)
);
CREATE TABLE IF NOT EXISTS item_assignees (
item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
agent TEXT NOT NULL CHECK (length(trim(agent)) > 0),
created_at_us INTEGER NOT NULL,
PRIMARY KEY (item_id, agent)
);
CREATE TABLE IF NOT EXISTS item_dependencies (
item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
depends_on_item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
link_type TEXT NOT NULL CHECK (length(trim(link_type)) > 0),
created_at_us INTEGER NOT NULL,
PRIMARY KEY (item_id, depends_on_item_id, link_type),
CHECK (item_id <> depends_on_item_id)
);
CREATE TABLE IF NOT EXISTS item_comments (
comment_id INTEGER PRIMARY KEY AUTOINCREMENT,
item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
event_hash TEXT NOT NULL UNIQUE,
author TEXT NOT NULL,
body TEXT NOT NULL,
created_at_us INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS event_redactions (
target_event_hash TEXT PRIMARY KEY,
item_id TEXT NOT NULL REFERENCES items(item_id) ON DELETE CASCADE,
reason TEXT NOT NULL,
redacted_by TEXT NOT NULL,
redacted_at_us INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS projection_meta (
id INTEGER PRIMARY KEY CHECK (id = 1),
schema_version INTEGER NOT NULL,
last_event_offset INTEGER NOT NULL DEFAULT 0,
last_event_hash TEXT,
last_rebuild_at_us INTEGER NOT NULL DEFAULT 0
);
INSERT OR IGNORE INTO projection_meta (
id,
schema_version,
last_event_offset,
last_event_hash,
last_rebuild_at_us
) VALUES (1, 1, 0, NULL, 0);
";Expand description
Migration v1: core normalized tables plus projection metadata.