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.
68 lines
2.9 KiB
PL/PgSQL
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;
|