-- v15.0 execution-completeness delta.
-- Evidence evaluation/proposal automation only. Automatic model activation, client publication,
-- automatic order submission and KIS submission remain forbidden.

alter table evaluation.model_operation_schedule
    add column if not exists dispatch_revision integer not null default 0 check (dispatch_revision >= 0),
    add column if not exists anchor_at timestamptz null,
    add column if not exists timezone_id text not null default 'UTC',
    add column if not exists last_completed_at timestamptz null,
    add column if not exists last_hold_code text null;

update evaluation.model_operation_schedule
set anchor_at = coalesce(anchor_at, next_due_at)
where anchor_at is null;

alter table evaluation.model_operation_request
    add column if not exists execution_revision integer not null default 1 check (execution_revision > 0),
    add column if not exists last_heartbeat_at timestamptz null,
    add column if not exists hold_until timestamptz null,
    add column if not exists status_reason_code text null,
    add column if not exists scheduled_for timestamptz null;

create table if not exists evaluation.prediction_evaluation_window (
    window_request_id uuid primary key,
    prediction_evidence_id uuid not null,
    scope_key text not null,
    calendar_id text not null,
    prediction_session date not null,
    window_trading_days integer not null check (window_trading_days in (1,5,20,63,126,252)),
    due_session date not null,
    status text not null check (status in ('PLANNED','MATURED','EVALUATED','BUSINESS_HOLD','QUARANTINED')),
    dataset_id text not null,
    model_version text not null,
    metric_definition_set_hash text not null,
    content_hash text not null unique,
    created_at timestamptz not null,
    matured_at timestamptz null,
    evaluated_at timestamptz null,
    check (due_session >= prediction_session),
    unique (prediction_evidence_id, window_trading_days, metric_definition_set_hash)
);

create index if not exists ix_prediction_evaluation_window_due
    on evaluation.prediction_evaluation_window (due_session, status, scope_key)
    where status in ('PLANNED','BUSINESS_HOLD');

create table if not exists evaluation.metric_cohort_definition (
    cohort_code text not null,
    definition_version integer not null check (definition_version > 0),
    scope_expression text not null,
    inclusion_expression text not null,
    exclusion_expression text not null,
    minimum_sample_size integer not null check (minimum_sample_size >= 0),
    effective_from timestamptz not null,
    effective_to timestamptz null,
    status text not null check (status in ('PROPOSED','APPROVED','RETIRED')),
    content_hash text not null unique,
    approved_by text null,
    approved_at timestamptz null,
    primary key (cohort_code, definition_version),
    check (effective_to is null or effective_to > effective_from),
    check (status <> 'APPROVED' or (approved_by is not null and approved_at is not null))
);

create table if not exists governance.ui_contract_release (
    ui_contract_release_id uuid primary key,
    contract_version text not null,
    provider_id text not null,
    provider_version text not null,
    capability_hash text not null,
    screen_template_hash text not null,
    accessibility_evidence_hash text not null,
    visual_regression_hash text null,
    performance_evidence_hash text null,
    status text not null check (status in ('PROPOSED','APPROVED','RETIRED')),
    approved_by text null,
    approved_at timestamptz null,
    created_at timestamptz not null default now(),
    content_hash text not null unique,
    unique (contract_version, provider_id, provider_version),
    check (status <> 'APPROVED' or (approved_by is not null and approved_at is not null))
);

-- Evaluation windows, cohort definitions and UI contract approvals are immutable evidence.
drop trigger if exists prediction_evaluation_window_append_only on evaluation.prediction_evaluation_window;
create trigger prediction_evaluation_window_append_only
before update or delete on evaluation.prediction_evaluation_window
for each row execute function building_blocks.prevent_append_only_change();

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

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

comment on table evaluation.prediction_evaluation_window is
'Immutable 1/5/20/63/126/252 trading-session maturity plan. Revisions create new evidence rows.';
comment on table governance.ui_contract_release is
'Approved normalized UI contract/provider evidence. It does not authorize feature behavior or investment decisions.';

-- Integrity audit remains disabled until approved calendar/cohort definitions and alert runbook exist.
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-000000000040','J40','EvaluationWindowIntegrityAudit','GLOBAL','DAILY','EVALUATION_ONLY','q-control',1,false,now()+interval '1 day',interval '1 day','Quant/QA','Data/SRE','GLOBAL_UTC','FIXED_CADENCE','["TRADING_CALENDAR_APPROVED","METRIC_COHORT_APPROVED"]','LATEST_ONLY',1,now()+interval '1 day','UTC')
on conflict (operation_code, scope_key, schedule_version) do nothing;
