create table if not exists visual_watch_runs ( id bigserial primary key, trigger_type text not null, source_name text not null, instrument_id bigint not null references instruments(id) on delete cascade, candidate_id bigint references trade_plan_candidates(id) on delete set null, signal_id bigint references trade_signals(id) on delete set null, decision_packet_id bigint references decision_packets(id) on delete set null, symbol text not null, timeframe text not null, status text not null, created_ts timestamptz not null default now(), completed_ts timestamptz, payload jsonb not null default '{}'::jsonb ); create index if not exists idx_visual_watch_runs_lookup on visual_watch_runs (instrument_id, trigger_type, created_ts desc, id desc); create table if not exists visual_snapshots ( id bigserial primary key, watch_run_id bigint not null references visual_watch_runs(id) on delete cascade, source_name text not null, image_path text not null, captured_ts timestamptz not null, status text not null, payload jsonb not null default '{}'::jsonb ); create index if not exists idx_visual_snapshots_watch_captured_desc on visual_snapshots (watch_run_id, captured_ts desc, id desc); create table if not exists visual_reviews ( id bigserial primary key, watch_run_id bigint not null references visual_watch_runs(id) on delete cascade, snapshot_id bigint references visual_snapshots(id) on delete set null, visual_state text not null, visual_confidence numeric(6, 4), visual_notes text not null default '', ui_anomalies jsonb not null default '[]'::jsonb, reviewed_ts timestamptz not null, payload jsonb not null default '{}'::jsonb ); create index if not exists idx_visual_reviews_watch_reviewed_desc on visual_reviews (watch_run_id, reviewed_ts desc, id desc);