-- AEG-X-009 / ADR-DATA-001: append-only source approval boundary.
-- This migration authorizes governance records only. It does not authorize ingestion,
-- recommendation, model activation, client publication, order, or KIS submission.

create schema if not exists governance;

create table if not exists governance.source_approval (
    source_approval_id uuid primary key default gen_random_uuid(),
    source_id text not null,
    source_version text not null,
    domain text not null,
    owner text not null,
    steward text not null,
    license_reference text not null,
    availability_sla text not null,
    freshness_sla text not null,
    timezone text not null,
    calendar_id text not null,
    unit_contract text not null,
    schema_contract_version text not null,
    status text not null,
    content_hash char(64) not null,
    published_at timestamptz,
    revision integer,
    approved_by text not null,
    approved_at timestamptz not null,
    created_at timestamptz not null default now(),
    constraint source_approval_status_valid
        check (status in ('CANDIDATE', 'APPROVED', 'SUSPENDED', 'RETIRED', 'QUARANTINED')),
    constraint source_approval_hash_valid
        check (content_hash ~ '^[0-9A-Fa-f]{64}$'),
    constraint source_approval_approved_requires_publication
        check (status <> 'APPROVED' or (published_at is not null and revision is not null and revision > 0))
);

create unique index if not exists source_approval_identity_idx
    on governance.source_approval (source_id, source_version, revision)
    where revision is not null;

create index if not exists source_approval_status_idx
    on governance.source_approval (status, created_at desc);

create or replace function governance.reject_source_approval_mutation()
returns trigger as $$
begin
    raise exception 'governance.source_approval is append-only; create a correction record';
end;
$$ language plpgsql;

drop trigger if exists source_approval_no_update on governance.source_approval;
create trigger source_approval_no_update
before update or delete on governance.source_approval
for each row execute function governance.reject_source_approval_mutation();
