184 lines
8.6 KiB
SQL
184 lines
8.6 KiB
SQL
-- Migration: Execution System
|
|
-- Description: Creates execution (with workflow columns), inquiry, and rule tables
|
|
-- Version: 20250101000006
|
|
|
|
-- ============================================================================
|
|
-- EXECUTION TABLE
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE execution (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
action BIGINT REFERENCES action(id) ON DELETE SET NULL,
|
|
action_ref TEXT NOT NULL,
|
|
config JSONB,
|
|
env_vars JSONB,
|
|
parent BIGINT REFERENCES execution(id) ON DELETE SET NULL,
|
|
enforcement BIGINT REFERENCES enforcement(id) ON DELETE SET NULL,
|
|
executor BIGINT REFERENCES identity(id) ON DELETE SET NULL,
|
|
status execution_status_enum NOT NULL DEFAULT 'requested',
|
|
result JSONB,
|
|
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
is_workflow BOOLEAN DEFAULT false NOT NULL,
|
|
workflow_def BIGINT,
|
|
workflow_task JSONB,
|
|
updated TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX idx_execution_action ON execution(action);
|
|
CREATE INDEX idx_execution_action_ref ON execution(action_ref);
|
|
CREATE INDEX idx_execution_parent ON execution(parent);
|
|
CREATE INDEX idx_execution_enforcement ON execution(enforcement);
|
|
CREATE INDEX idx_execution_executor ON execution(executor);
|
|
CREATE INDEX idx_execution_status ON execution(status);
|
|
CREATE INDEX idx_execution_created ON execution(created DESC);
|
|
CREATE INDEX idx_execution_updated ON execution(updated DESC);
|
|
CREATE INDEX idx_execution_status_created ON execution(status, created DESC);
|
|
CREATE INDEX idx_execution_status_updated ON execution(status, updated DESC);
|
|
CREATE INDEX idx_execution_action_status ON execution(action, status);
|
|
CREATE INDEX idx_execution_executor_created ON execution(executor, created DESC);
|
|
CREATE INDEX idx_execution_parent_created ON execution(parent, created DESC);
|
|
CREATE INDEX idx_execution_result_gin ON execution USING GIN (result);
|
|
CREATE INDEX idx_execution_env_vars_gin ON execution USING GIN (env_vars);
|
|
|
|
-- Trigger
|
|
CREATE TRIGGER update_execution_updated
|
|
BEFORE UPDATE ON execution
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_column();
|
|
|
|
-- Comments
|
|
COMMENT ON TABLE execution IS 'Executions represent action runs, supports nested workflows';
|
|
COMMENT ON COLUMN execution.action IS 'Action being executed (may be null if action deleted)';
|
|
COMMENT ON COLUMN execution.action_ref IS 'Action reference (preserved even if action deleted)';
|
|
COMMENT ON COLUMN execution.config IS 'Snapshot of action configuration at execution time';
|
|
COMMENT ON COLUMN execution.env_vars IS 'Environment variables for this execution as key-value pairs (string -> string). These are set in the execution environment and are separate from action parameters. Used for execution context, configuration, and non-sensitive metadata.';
|
|
COMMENT ON COLUMN execution.parent IS 'Parent execution ID for workflow hierarchies';
|
|
COMMENT ON COLUMN execution.enforcement IS 'Enforcement that triggered this execution (if rule-driven)';
|
|
COMMENT ON COLUMN execution.executor IS 'Identity that initiated the execution';
|
|
COMMENT ON COLUMN execution.status IS 'Current execution lifecycle status';
|
|
COMMENT ON COLUMN execution.result IS 'Execution output/results';
|
|
|
|
-- ============================================================================
|
|
|
|
-- ============================================================================
|
|
-- INQUIRY TABLE
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE inquiry (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
execution BIGINT NOT NULL REFERENCES execution(id) ON DELETE CASCADE,
|
|
prompt TEXT NOT NULL,
|
|
response_schema JSONB,
|
|
assigned_to BIGINT REFERENCES identity(id) ON DELETE SET NULL,
|
|
status inquiry_status_enum NOT NULL DEFAULT 'pending',
|
|
response JSONB,
|
|
timeout_at TIMESTAMPTZ,
|
|
responded_at TIMESTAMPTZ,
|
|
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX idx_inquiry_execution ON inquiry(execution);
|
|
CREATE INDEX idx_inquiry_assigned_to ON inquiry(assigned_to);
|
|
CREATE INDEX idx_inquiry_status ON inquiry(status);
|
|
CREATE INDEX idx_inquiry_timeout_at ON inquiry(timeout_at) WHERE timeout_at IS NOT NULL;
|
|
CREATE INDEX idx_inquiry_created ON inquiry(created DESC);
|
|
CREATE INDEX idx_inquiry_status_created ON inquiry(status, created DESC);
|
|
CREATE INDEX idx_inquiry_assigned_status ON inquiry(assigned_to, status);
|
|
CREATE INDEX idx_inquiry_execution_status ON inquiry(execution, status);
|
|
CREATE INDEX idx_inquiry_response_gin ON inquiry USING GIN (response);
|
|
|
|
-- Trigger
|
|
CREATE TRIGGER update_inquiry_updated
|
|
BEFORE UPDATE ON inquiry
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_column();
|
|
|
|
-- Comments
|
|
COMMENT ON TABLE inquiry IS 'Inquiries enable human-in-the-loop workflows with async user interactions';
|
|
COMMENT ON COLUMN inquiry.execution IS 'Execution that is waiting on this inquiry';
|
|
COMMENT ON COLUMN inquiry.prompt IS 'Question or prompt text for the user';
|
|
COMMENT ON COLUMN inquiry.response_schema IS 'JSON schema defining expected response format';
|
|
COMMENT ON COLUMN inquiry.assigned_to IS 'Identity who should respond to this inquiry';
|
|
COMMENT ON COLUMN inquiry.status IS 'Current inquiry lifecycle status';
|
|
COMMENT ON COLUMN inquiry.response IS 'User response data';
|
|
COMMENT ON COLUMN inquiry.timeout_at IS 'When this inquiry expires';
|
|
COMMENT ON COLUMN inquiry.responded_at IS 'When the response was received';
|
|
|
|
-- ============================================================================
|
|
|
|
-- ============================================================================
|
|
-- RULE TABLE
|
|
-- ============================================================================
|
|
|
|
CREATE TABLE rule (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
ref TEXT NOT NULL UNIQUE,
|
|
pack BIGINT NOT NULL REFERENCES pack(id) ON DELETE CASCADE,
|
|
pack_ref TEXT NOT NULL,
|
|
label TEXT NOT NULL,
|
|
description TEXT NOT NULL,
|
|
action BIGINT REFERENCES action(id) ON DELETE SET NULL,
|
|
action_ref TEXT NOT NULL,
|
|
trigger BIGINT REFERENCES trigger(id) ON DELETE SET NULL,
|
|
trigger_ref TEXT NOT NULL,
|
|
conditions JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
action_params JSONB DEFAULT '{}'::jsonb,
|
|
trigger_params JSONB DEFAULT '{}'::jsonb,
|
|
enabled BOOLEAN NOT NULL,
|
|
is_adhoc BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Constraints
|
|
CONSTRAINT rule_ref_lowercase CHECK (ref = LOWER(ref)),
|
|
CONSTRAINT rule_ref_format CHECK (ref ~ '^[^.]+\.[^.]+$')
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX idx_rule_ref ON rule(ref);
|
|
CREATE INDEX idx_rule_pack ON rule(pack);
|
|
CREATE INDEX idx_rule_action ON rule(action);
|
|
CREATE INDEX idx_rule_trigger ON rule(trigger);
|
|
CREATE INDEX idx_rule_enabled ON rule(enabled) WHERE enabled = TRUE;
|
|
CREATE INDEX idx_rule_is_adhoc ON rule(is_adhoc) WHERE is_adhoc = true;
|
|
CREATE INDEX idx_rule_created ON rule(created DESC);
|
|
CREATE INDEX idx_rule_trigger_enabled ON rule(trigger, enabled);
|
|
CREATE INDEX idx_rule_action_enabled ON rule(action, enabled);
|
|
CREATE INDEX idx_rule_pack_enabled ON rule(pack, enabled);
|
|
CREATE INDEX idx_rule_action_params_gin ON rule USING GIN (action_params);
|
|
CREATE INDEX idx_rule_trigger_params_gin ON rule USING GIN (trigger_params);
|
|
|
|
-- Trigger
|
|
CREATE TRIGGER update_rule_updated
|
|
BEFORE UPDATE ON rule
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_column();
|
|
|
|
-- Comments
|
|
COMMENT ON TABLE rule IS 'Rules link triggers to actions with conditions';
|
|
COMMENT ON COLUMN rule.ref IS 'Unique rule reference (format: pack.name)';
|
|
COMMENT ON COLUMN rule.label IS 'Human-readable rule name';
|
|
COMMENT ON COLUMN rule.action IS 'Action to execute when rule triggers (null if action deleted)';
|
|
COMMENT ON COLUMN rule.trigger IS 'Trigger that activates this rule (null if trigger deleted)';
|
|
COMMENT ON COLUMN rule.conditions IS 'Condition expressions to evaluate before executing action';
|
|
COMMENT ON COLUMN rule.action_params IS 'Parameter overrides for the action';
|
|
COMMENT ON COLUMN rule.trigger_params IS 'Parameter overrides for the trigger';
|
|
COMMENT ON COLUMN rule.enabled IS 'Whether this rule is active';
|
|
COMMENT ON COLUMN rule.is_adhoc IS 'True if rule was manually created (ad-hoc), false if installed from pack';
|
|
|
|
-- ============================================================================
|
|
|
|
-- Add foreign key constraints now that rule table exists
|
|
ALTER TABLE enforcement
|
|
ADD CONSTRAINT enforcement_rule_fkey
|
|
FOREIGN KEY (rule) REFERENCES rule(id) ON DELETE SET NULL;
|
|
|
|
ALTER TABLE event
|
|
ADD CONSTRAINT event_rule_fkey
|
|
FOREIGN KEY (rule) REFERENCES rule(id) ON DELETE SET NULL;
|
|
|
|
-- ============================================================================
|