Files
silo/migrations/014_dag_nodes_edges.sql
Forbes 83e0d6821c feat: add database migrations for DAG and worker system
Migration 014: dag_nodes, dag_edges, dag_cross_edges tables for the
feature-level dependency graph with validation state tracking.

Migration 015: runners, job_definitions, jobs, job_log tables for the
async compute job system with PostgreSQL-backed work queue.

Update TruncateAll in testutil to include new tables.
2026-02-14 13:04:41 -06:00

68 lines
2.9 KiB
PL/PgSQL

-- Dependency DAG: feature-level nodes and edges within items.
-- Migration: 014_dag_nodes_edges
-- Date: 2026-02
BEGIN;
--------------------------------------------------------------------------------
-- DAG Nodes (feature-level nodes within an item's revision)
--------------------------------------------------------------------------------
CREATE TABLE dag_nodes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
item_id UUID NOT NULL REFERENCES items(id) ON DELETE CASCADE,
revision_number INTEGER NOT NULL,
node_key TEXT NOT NULL,
node_type TEXT NOT NULL,
properties_hash TEXT,
validation_state TEXT NOT NULL DEFAULT 'clean',
validation_msg TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE(item_id, revision_number, node_key)
);
CREATE INDEX idx_dag_nodes_item ON dag_nodes(item_id);
CREATE INDEX idx_dag_nodes_item_rev ON dag_nodes(item_id, revision_number);
CREATE INDEX idx_dag_nodes_state ON dag_nodes(validation_state)
WHERE validation_state != 'clean';
CREATE INDEX idx_dag_nodes_type ON dag_nodes(node_type);
--------------------------------------------------------------------------------
-- DAG Edges (dependencies between nodes within a single item)
-- Direction: source → target means "target depends on source"
--------------------------------------------------------------------------------
CREATE TABLE dag_edges (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_node_id UUID NOT NULL REFERENCES dag_nodes(id) ON DELETE CASCADE,
target_node_id UUID NOT NULL REFERENCES dag_nodes(id) ON DELETE CASCADE,
edge_type TEXT NOT NULL DEFAULT 'depends_on',
metadata JSONB DEFAULT '{}',
UNIQUE(source_node_id, target_node_id, edge_type),
CONSTRAINT no_self_edge CHECK (source_node_id != target_node_id)
);
CREATE INDEX idx_dag_edges_source ON dag_edges(source_node_id);
CREATE INDEX idx_dag_edges_target ON dag_edges(target_node_id);
--------------------------------------------------------------------------------
-- Cross-item DAG edges (linking feature nodes across BOM boundaries)
--------------------------------------------------------------------------------
CREATE TABLE dag_cross_edges (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source_node_id UUID NOT NULL REFERENCES dag_nodes(id) ON DELETE CASCADE,
target_node_id UUID NOT NULL REFERENCES dag_nodes(id) ON DELETE CASCADE,
relationship_id UUID REFERENCES relationships(id) ON DELETE SET NULL,
edge_type TEXT NOT NULL DEFAULT 'assembly_ref',
metadata JSONB DEFAULT '{}',
UNIQUE(source_node_id, target_node_id)
);
CREATE INDEX idx_dag_cross_source ON dag_cross_edges(source_node_id);
CREATE INDEX idx_dag_cross_target ON dag_cross_edges(target_node_id);
COMMIT;