-- Chains table - DAG of contracts for multi-contract orchestration -- Fits Makima's control theme - she controls through invisible chains CREATE TABLE IF NOT EXISTS chains ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), owner_id UUID NOT NULL REFERENCES owners(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, description TEXT, status VARCHAR(32) NOT NULL DEFAULT 'active', -- active/completed/archived -- Loop control for iterative execution loop_enabled BOOLEAN NOT NULL DEFAULT false, loop_max_iterations INTEGER DEFAULT 10, loop_current_iteration INTEGER DEFAULT 0, loop_progress_check TEXT, -- Prompt/criteria for evaluating progress -- Repository reference (optional - contracts may have their own repos) repository_url VARCHAR(512), local_path VARCHAR(512), -- Versioning for optimistic locking version INTEGER NOT NULL DEFAULT 1, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_chains_owner_id ON chains(owner_id); CREATE INDEX idx_chains_status ON chains(status); -- Chain contracts - links contracts to chains with DAG dependency info -- The depends_on array forms the DAG edges (directed acyclic graph) CREATE TABLE IF NOT EXISTS chain_contracts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), chain_id UUID NOT NULL REFERENCES chains(id) ON DELETE CASCADE, contract_id UUID NOT NULL REFERENCES contracts(id) ON DELETE CASCADE, -- DAG edges: contract IDs this contract depends on (must complete before this starts) depends_on UUID[] DEFAULT '{}', -- Order for display/processing (topological sort order) order_index INTEGER NOT NULL DEFAULT 0, -- Position for GUI editor editor_x FLOAT DEFAULT 0, editor_y FLOAT DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(chain_id, contract_id) ); CREATE INDEX idx_chain_contracts_chain_id ON chain_contracts(chain_id); CREATE INDEX idx_chain_contracts_contract_id ON chain_contracts(contract_id); -- Add chain_id to contracts table for reverse lookup ALTER TABLE contracts ADD COLUMN IF NOT EXISTS chain_id UUID REFERENCES chains(id) ON DELETE SET NULL; CREATE INDEX IF NOT EXISTS idx_contracts_chain_id ON contracts(chain_id); -- Chain events for audit trail CREATE TABLE IF NOT EXISTS chain_events ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), chain_id UUID NOT NULL REFERENCES chains(id) ON DELETE CASCADE, event_type VARCHAR(64) NOT NULL, -- created, contract_added, contract_completed, loop_iteration, completed contract_id UUID REFERENCES contracts(id) ON DELETE SET NULL, event_data JSONB, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_chain_events_chain_id ON chain_events(chain_id);