61 lines
2.3 KiB
PL/PgSQL
61 lines
2.3 KiB
PL/PgSQL
create table if not exists signal_engine.evidence_snapshot (
|
|
evidence_id text primary key,
|
|
as_of timestamptz not null,
|
|
published_at_cutoff timestamptz not null,
|
|
dataset_id text not null,
|
|
data_hash text not null,
|
|
model_version text not null,
|
|
config_version text not null,
|
|
payload jsonb not null,
|
|
content_hash text not null unique,
|
|
created_at timestamptz not null default now()
|
|
);
|
|
|
|
create table if not exists signal_engine.signal_decision (
|
|
decision_id uuid primary key,
|
|
lot_id uuid not null,
|
|
cycle_id uuid not null,
|
|
evidence_id text not null references signal_engine.evidence_snapshot(evidence_id),
|
|
action text not null,
|
|
sell_fraction numeric(9,6) not null check (sell_fraction between 0 and 1),
|
|
policy_id text not null,
|
|
priority integer not null,
|
|
reason_code text not null,
|
|
reentry_eligible boolean not null,
|
|
created_at timestamptz not null,
|
|
decision_hash text not null unique
|
|
);
|
|
|
|
create table if not exists signal_engine.reentry_watch (
|
|
watch_id uuid primary key,
|
|
sell_decision_id uuid not null unique references signal_engine.signal_decision(decision_id),
|
|
prior_cycle_id uuid not null,
|
|
state text not null,
|
|
minimum_wait_sessions integer not null check (minimum_wait_sessions >= 0),
|
|
minimum_spacing_sessions integer not null check (minimum_spacing_sessions >= 0),
|
|
expires_after_sessions integer not null check (expires_after_sessions > 0),
|
|
created_at timestamptz not null
|
|
);
|
|
|
|
create table if not exists signal_engine.reentry_stage (
|
|
watch_id uuid not null references signal_engine.reentry_watch(watch_id),
|
|
stage_no integer not null,
|
|
target_fraction numeric(9,6) not null check (target_fraction > 0 and target_fraction <= 1),
|
|
status text not null,
|
|
eligible_at timestamptz null,
|
|
executed_cycle_id uuid null,
|
|
primary key (watch_id, stage_no)
|
|
);
|
|
|
|
create or replace function signal_engine.prevent_immutable_change()
|
|
returns trigger language plpgsql as $$
|
|
begin
|
|
raise exception 'immutable evidence/decision rows cannot be updated or deleted';
|
|
end;
|
|
$$;
|
|
|
|
drop trigger if exists evidence_snapshot_immutable on signal_engine.evidence_snapshot;
|
|
create trigger evidence_snapshot_immutable
|
|
before update or delete on signal_engine.evidence_snapshot
|
|
for each row execute function signal_engine.prevent_immutable_change();
|