213 lines
8.5 KiB
SQL

-- GooseFactory PostgreSQL Init Script
-- Creates required extensions and initial schemas
-- UUID generation
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- Full-text search (used by factory_search tool)
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- Enum types (mirrors TypeScript types from CONTRACTS.md)
CREATE TYPE pipeline_status AS ENUM ('active', 'paused', 'completed', 'failed', 'archived');
CREATE TYPE pipeline_stage AS ENUM ('intake', 'scaffolding', 'building', 'testing', 'review', 'staging', 'production', 'published');
CREATE TYPE priority_level AS ENUM ('critical', 'high', 'medium', 'low');
CREATE TYPE pipeline_template AS ENUM ('mcp-server-standard', 'mcp-server-minimal', 'mcp-server-enterprise');
CREATE TYPE stage_status AS ENUM ('pending', 'active', 'completed', 'skipped', 'failed');
CREATE TYPE task_type AS ENUM ('approval', 'review', 'decision', 'manual_action', 'fix_required');
CREATE TYPE task_status AS ENUM ('pending', 'claimed', 'in_progress', 'completed', 'expired', 'escalated');
CREATE TYPE task_decision AS ENUM ('approved', 'rejected', 'deferred', 'escalated');
CREATE TYPE approval_type AS ENUM ('stage_gate', 'deploy', 'code_review', 'manual_check');
CREATE TYPE approval_status AS ENUM ('pending', 'approved', 'rejected', 'expired');
CREATE TYPE agent_type AS ENUM ('ai_builder', 'test_runner', 'deployer', 'monitor');
CREATE TYPE agent_status AS ENUM ('idle', 'active', 'error', 'offline');
CREATE TYPE asset_type AS ENUM ('code', 'config', 'docs', 'build', 'test_report', 'screenshot');
CREATE TYPE actor_type AS ENUM ('user', 'agent', 'system', 'webhook');
CREATE TYPE generator_type AS ENUM ('user', 'agent', 'ci');
-- Pipelines table
CREATE TABLE IF NOT EXISTS pipelines (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(200) NOT NULL,
slug VARCHAR(200) UNIQUE NOT NULL,
template pipeline_template NOT NULL DEFAULT 'mcp-server-standard',
platform VARCHAR(100) NOT NULL,
current_stage pipeline_stage NOT NULL DEFAULT 'intake',
status pipeline_status NOT NULL DEFAULT 'active',
priority priority_level NOT NULL DEFAULT 'medium',
created_by UUID,
assignee_id UUID,
config JSONB NOT NULL DEFAULT '{}',
metadata JSONB NOT NULL DEFAULT '{}',
sla_deadline TIMESTAMPTZ,
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Pipeline stage records
CREATE TABLE IF NOT EXISTS pipeline_stages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
pipeline_id UUID NOT NULL REFERENCES pipelines(id) ON DELETE CASCADE,
stage_name pipeline_stage NOT NULL,
stage_order INT NOT NULL,
status stage_status NOT NULL DEFAULT 'pending',
requires_approval BOOLEAN NOT NULL DEFAULT false,
approval_type VARCHAR(20) NOT NULL DEFAULT 'manual',
auto_advance BOOLEAN NOT NULL DEFAULT false,
validation_rules JSONB NOT NULL DEFAULT '[]',
entered_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
duration_seconds INT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Tasks (decision queue)
CREATE TABLE IF NOT EXISTS tasks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
pipeline_id UUID REFERENCES pipelines(id) ON DELETE SET NULL,
stage_name pipeline_stage,
type task_type NOT NULL,
title VARCHAR(500) NOT NULL,
description TEXT,
context JSONB NOT NULL DEFAULT '{}',
status task_status NOT NULL DEFAULT 'pending',
priority priority_level NOT NULL DEFAULT 'medium',
assignee_id UUID,
claimed_at TIMESTAMPTZ,
claimed_by UUID,
decision task_decision,
decision_notes TEXT,
decision_data JSONB NOT NULL DEFAULT '{}',
decided_at TIMESTAMPTZ,
decided_by UUID,
sla_deadline TIMESTAMPTZ,
sla_warnings_sent INT NOT NULL DEFAULT 0,
sla_breached BOOLEAN NOT NULL DEFAULT false,
escalation_level INT NOT NULL DEFAULT 0,
blocks_stage_advance BOOLEAN NOT NULL DEFAULT false,
blocks_pipeline_id UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Approvals
CREATE TABLE IF NOT EXISTS approvals (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
pipeline_id UUID NOT NULL REFERENCES pipelines(id) ON DELETE CASCADE,
stage_name pipeline_stage NOT NULL,
type approval_type NOT NULL,
status approval_status NOT NULL DEFAULT 'pending',
approved_by UUID,
approved_at TIMESTAMPTZ,
rejection_reason TEXT,
conditions JSONB NOT NULL DEFAULT '[]',
required_approvers INT NOT NULL DEFAULT 1,
current_approvers INT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Agents
CREATE TABLE IF NOT EXISTS agents (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(200) NOT NULL,
type agent_type NOT NULL,
status agent_status NOT NULL DEFAULT 'idle',
current_task_id UUID,
current_pipeline_id UUID,
health JSONB NOT NULL DEFAULT '{}',
capabilities JSONB NOT NULL DEFAULT '[]',
config JSONB NOT NULL DEFAULT '{}',
tasks_completed_total INT NOT NULL DEFAULT 0,
avg_task_duration_seconds INT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Assets
CREATE TABLE IF NOT EXISTS assets (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
pipeline_id UUID NOT NULL REFERENCES pipelines(id) ON DELETE CASCADE,
stage_name pipeline_stage,
type asset_type NOT NULL,
name VARCHAR(500) NOT NULL,
path TEXT,
storage_key TEXT NOT NULL,
storage_bucket TEXT,
size_bytes BIGINT NOT NULL DEFAULT 0,
content_type VARCHAR(100) NOT NULL,
checksum_sha256 VARCHAR(64) NOT NULL,
version INT NOT NULL DEFAULT 1,
previous_version_id UUID,
generated_by UUID NOT NULL,
generator_type generator_type NOT NULL DEFAULT 'agent',
metadata JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Audit log
CREATE TABLE IF NOT EXISTS audit_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
actor_type actor_type NOT NULL,
actor_id UUID,
actor_name VARCHAR(200),
action VARCHAR(200) NOT NULL,
entity_type VARCHAR(100) NOT NULL,
entity_id UUID NOT NULL,
changes JSONB NOT NULL DEFAULT '{}',
metadata JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Notifications
CREATE TABLE IF NOT EXISTS notifications (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL,
type VARCHAR(50) NOT NULL,
title VARCHAR(500) NOT NULL,
body TEXT,
data JSONB NOT NULL DEFAULT '{}',
channels JSONB NOT NULL DEFAULT '[]',
delivered_via JSONB NOT NULL DEFAULT '[]',
read BOOLEAN NOT NULL DEFAULT false,
read_at TIMESTAMPTZ,
dismissed BOOLEAN NOT NULL DEFAULT false,
entity_type VARCHAR(100),
entity_id UUID,
action_url TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Webhooks
CREATE TABLE IF NOT EXISTS webhooks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
url TEXT NOT NULL,
events JSONB NOT NULL DEFAULT '[]',
secret VARCHAR(256) NOT NULL,
active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_pipelines_status ON pipelines(status);
CREATE INDEX IF NOT EXISTS idx_pipelines_stage ON pipelines(current_stage);
CREATE INDEX IF NOT EXISTS idx_pipelines_priority ON pipelines(priority);
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
CREATE INDEX IF NOT EXISTS idx_tasks_pipeline ON tasks(pipeline_id);
CREATE INDEX IF NOT EXISTS idx_tasks_sla ON tasks(sla_breached, sla_deadline);
CREATE INDEX IF NOT EXISTS idx_approvals_status ON approvals(status);
CREATE INDEX IF NOT EXISTS idx_approvals_pipeline ON approvals(pipeline_id);
CREATE INDEX IF NOT EXISTS idx_audit_entity ON audit_log(entity_type, entity_id);
CREATE INDEX IF NOT EXISTS idx_audit_actor ON audit_log(actor_id);
CREATE INDEX IF NOT EXISTS idx_audit_created ON audit_log(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications(user_id, read);
CREATE INDEX IF NOT EXISTS idx_assets_pipeline ON assets(pipeline_id);
-- Full-text search index on pipelines
CREATE INDEX IF NOT EXISTS idx_pipelines_name_trgm ON pipelines USING gin (name gin_trgm_ops);
CREATE INDEX IF NOT EXISTS idx_tasks_title_trgm ON tasks USING gin (title gin_trgm_ops);