-- Migration 002: Knowledge graph tables -- Adds nodes, cells, facts, and graph edges to the unified database. -- Nodes are entities in the knowledge graph. -- A node is either a note or an artifact link. CREATE TABLE IF NOT EXISTS nodes ( id TEXT PRIMARY KEY, parent_id TEXT, -- parent node ID (C2 wiki style hierarchy) name TEXT NOT NULL, -- human-readable name type TEXT NOT NULL DEFAULT 'note', -- 'note' or 'artifact_link' created TEXT NOT NULL, -- ISO 8601 UTC modified TEXT NOT NULL, -- ISO 8601 UTC FOREIGN KEY (parent_id) REFERENCES nodes (id) ); CREATE INDEX IF NOT EXISTS idx_nodes_parent ON nodes (parent_id); CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes (name); -- Many-to-many junction: nodes <-> tags. CREATE TABLE IF NOT EXISTS node_tags ( node_id TEXT NOT NULL, tag_id TEXT NOT NULL, FOREIGN KEY (node_id) REFERENCES nodes (id), FOREIGN KEY (tag_id) REFERENCES tags (id) ); -- Many-to-many junction: nodes <-> categories. CREATE TABLE IF NOT EXISTS node_categories ( node_id TEXT NOT NULL, category_id TEXT NOT NULL, FOREIGN KEY (node_id) REFERENCES nodes (id), FOREIGN KEY (category_id) REFERENCES categories (id) ); -- Cells are content units within a note. -- Inspired by Quiver's cell-based structure. CREATE TABLE IF NOT EXISTS cells ( id TEXT PRIMARY KEY, node_id TEXT NOT NULL, type TEXT NOT NULL DEFAULT 'markdown', -- 'markdown', 'code', etc. contents BLOB, ordinal INTEGER NOT NULL DEFAULT 0, -- display order within the node created TEXT NOT NULL, modified TEXT NOT NULL, FOREIGN KEY (node_id) REFERENCES nodes (id) ); CREATE INDEX IF NOT EXISTS idx_cells_node ON cells (node_id); -- Facts record EAV relationships with transactional history. -- entity + attribute + transaction form the natural key. CREATE TABLE IF NOT EXISTS facts ( id TEXT PRIMARY KEY, entity_id TEXT NOT NULL, -- the subject (node or artifact UUID) entity_name TEXT NOT NULL, -- human-readable entity name attribute_id TEXT NOT NULL, -- attribute UUID attribute_name TEXT NOT NULL, -- human-readable attribute name value_contents TEXT NOT NULL, value_type TEXT NOT NULL, tx_timestamp INTEGER NOT NULL, -- Unix epoch of the transaction retraction INTEGER NOT NULL DEFAULT 0 -- 1 = this fact is retracted ); CREATE INDEX IF NOT EXISTS idx_facts_entity ON facts (entity_id); CREATE INDEX IF NOT EXISTS idx_facts_attribute ON facts (attribute_id); -- Graph edges link nodes to other nodes or artifacts. CREATE TABLE IF NOT EXISTS edges ( id TEXT PRIMARY KEY, source_id TEXT NOT NULL, -- source node UUID target_id TEXT NOT NULL, -- target node or artifact UUID relation TEXT NOT NULL, -- 'child', 'parent', 'related', 'artifact_link', etc. created TEXT NOT NULL, FOREIGN KEY (source_id) REFERENCES nodes (id) ); CREATE INDEX IF NOT EXISTS idx_edges_source ON edges (source_id); CREATE INDEX IF NOT EXISTS idx_edges_target ON edges (target_id); INSERT INTO schema_version (version, applied) VALUES (2, datetime('now'));