Build the knowledge graph pillar with the kg package: - Node: hierarchical notes with parent/children, C2 wiki-style naming, shared tag/category pool with artifacts - Cell: content units (markdown, code, plain) with ordinal ordering - Fact: EAV tuples with transaction timestamps and retraction support - Edge: directed graph links (child, parent, related, artifact_link) Includes schema migration (002_knowledge_graph.sql), protobuf definitions (kg.proto), full gRPC KnowledgeGraphService implementation, CLI commands (node create/get), and comprehensive test coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
3.2 KiB
SQL
83 lines
3.2 KiB
SQL
-- 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'));
|