-- Approval Workflow Schema (VS-03) -- Maker-Checker approval gates for model activation -- INSERT-only, PIT-tracked with correlation_id CREATE SCHEMA IF NOT EXISTS model_operations; -- Approval proposals (DRAFT → PROPOSED → APPROVED → ACTIVE) CREATE TABLE IF NOT EXISTS model_operations.approval_proposals ( id UUID PRIMARY KEY, model_id UUID NOT NULL REFERENCES model_operations.models(id), status VARCHAR(50) NOT NULL, created_by VARCHAR(255) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), justification TEXT NOT NULL, effective_at DATE NOT NULL, proposed_at TIMESTAMPTZ, approved_by VARCHAR(255), approved_at TIMESTAMPTZ, approval_notes TEXT, activated_by VARCHAR(255), activated_at TIMESTAMPTZ, published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), revision INT NOT NULL DEFAULT 1, correlation_id UUID NOT NULL ); CREATE INDEX IF NOT EXISTS idx_approval_proposals_model_id ON model_operations.approval_proposals(model_id); CREATE INDEX IF NOT EXISTS idx_approval_proposals_status ON model_operations.approval_proposals(status); CREATE INDEX IF NOT EXISTS idx_approval_proposals_created_by ON model_operations.approval_proposals(created_by); -- Approval evidence (PBO/DSR/OOS artifacts) CREATE TABLE IF NOT EXISTS model_operations.approval_evidence ( id UUID PRIMARY KEY, approval_proposal_id UUID NOT NULL REFERENCES model_operations.approval_proposals(id), evidence_type VARCHAR(50) NOT NULL, evidence_url TEXT NOT NULL, reviewer_comment TEXT, published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), correlation_id UUID NOT NULL ); CREATE INDEX IF NOT EXISTS idx_approval_evidence_proposal_id ON model_operations.approval_evidence(approval_proposal_id); -- Approval events (audit trail) CREATE TABLE IF NOT EXISTS model_operations.approval_events ( id UUID PRIMARY KEY, approval_proposal_id UUID NOT NULL REFERENCES model_operations.approval_proposals(id), event_type VARCHAR(50) NOT NULL, actor_email VARCHAR(255) NOT NULL, event_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), details JSONB, published_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), correlation_id UUID NOT NULL ); CREATE INDEX IF NOT EXISTS idx_approval_events_proposal_id ON model_operations.approval_events(approval_proposal_id); CREATE INDEX IF NOT EXISTS idx_approval_events_type ON model_operations.approval_events(event_type);