-- v16.0 reference implementation closure.
-- Evaluation/proposal/audit only. Automatic model activation, customer publication,
-- automatic order submission and KIS submission remain forbidden.

create table if not exists evaluation.model_operation_lease (
    operation_code text not null,
    scope_key text not null,
    fencing_token bigint not null check (fencing_token > 0),
    lease_owner text not null,
    acquired_at timestamptz not null,
    expires_at timestamptz not null,
    heartbeat_at timestamptz not null,
    dispatch_revision integer not null check (dispatch_revision >= 0),
    primary key (operation_code, scope_key),
    check (expires_at > acquired_at),
    check (heartbeat_at >= acquired_at)
);

create table if not exists evaluation.model_evaluation_reconciliation (
    reconciliation_id uuid primary key,
    prediction_evidence_id uuid not null,
    window_trading_days integer not null check (window_trading_days in (1,5,20,63,126,252)),
    action text not null check (action in ('NONE','PLAN_MISSING','QUARANTINE_DUPLICATE','BUSINESS_HOLD_LATE','RECALCULATE_REVISION')),
    metric_definition_set_hash text not null,
    cohort_definition_hash text not null,
    dataset_id text not null,
    source_revision_hash text not null,
    reason_code text not null,
    content_hash text not null unique,
    created_at timestamptz not null,
    unique (prediction_evidence_id, window_trading_days, content_hash)
);

create table if not exists building_blocks.projection_rebuild_request (
    rebuild_request_id uuid primary key,
    projection_name text not null,
    requested_version integer not null check (requested_version > 0),
    source_watermark text not null,
    requested_by text not null,
    reason_code text not null,
    status text not null check (status in ('REQUESTED','RUNNING','SUCCEEDED','FAILED','QUARANTINED')),
    before_hash text null,
    after_hash text null,
    requested_at timestamptz not null,
    completed_at timestamptz null,
    content_hash text not null unique,
    check (completed_at is null or completed_at >= requested_at)
);

create table if not exists governance.ui_adapter_compatibility_evidence (
    compatibility_evidence_id uuid primary key,
    contract_version text not null,
    provider_id text not null,
    provider_version text not null,
    capability_hash text not null,
    contract_test_hash text not null,
    accessibility_test_hash text not null,
    visual_test_hash text null,
    performance_test_hash text null,
    rollback_test_hash text null,
    status text not null check (status in ('PROPOSED','APPROVED','REJECTED','RETIRED')),
    approved_by text null,
    approved_at timestamptz null,
    created_at timestamptz not null,
    content_hash text not null unique,
    check (status <> 'APPROVED' or (approved_by is not null and approved_at is not null))
);

drop trigger if exists model_evaluation_reconciliation_append_only on evaluation.model_evaluation_reconciliation;
create trigger model_evaluation_reconciliation_append_only before update or delete on evaluation.model_evaluation_reconciliation
for each row execute function building_blocks.prevent_append_only_change();

drop trigger if exists ui_adapter_compatibility_evidence_append_only on governance.ui_adapter_compatibility_evidence;
create trigger ui_adapter_compatibility_evidence_append_only before update or delete on governance.ui_adapter_compatibility_evidence
for each row execute function building_blocks.prevent_append_only_change();

insert into evaluation.model_operation_schedule
(schedule_id, operation_code, operation_name, scope_key, cadence, automation_mode, queue_name,
 schedule_version, enabled, next_due_at, max_lag, primary_owner, secondary_owner,
 calendar_id, due_policy, dependency_json, catch_up_policy, max_catch_up, anchor_at, timezone_id)
values
('e4100000-0000-4000-8000-000000000041','J41','SchedulerLeaseIntegrityAudit','GLOBAL','DAILY','EVALUATION_ONLY','q-control',1,false,now()+interval '1 day',interval '1 day','SRE/QA','BE/DBA','GLOBAL_UTC','FIXED_CADENCE','["LEASE_CONTRACT_APPROVED","ALERT_RUNBOOK_APPROVED"]','LATEST_ONLY',1,now()+interval '1 day','UTC'),
('e4100000-0000-4000-8000-000000000042','J42','ModelEvaluationReconciliation','GLOBAL','DAILY','EVALUATION_ONLY','q-evaluation',1,false,now()+interval '1 day',interval '1 day','Quant/QA','Data/Risk','GLOBAL_UTC','FIXED_CADENCE','["TRADING_CALENDAR_APPROVED","METRIC_COHORT_APPROVED","SOURCE_REVISION_INDEX_READY"]','LATEST_ONLY',1,now()+interval '1 day','UTC')
on conflict (operation_code, scope_key, schedule_version) do nothing;

comment on table evaluation.model_operation_lease is 'Lease fencing prevents stale workers from advancing schedules or duplicating model evaluation side effects.';
comment on table evaluation.model_evaluation_reconciliation is 'Append-only evaluation repair plan. It never activates a model or submits an order.';
