-- 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);
