-- file: ks-store/migrations/0004_decode_materialization_store.sql -- version: 2 -- Common versioned decode, coverage and materialization store. -- This migration uses the current PostgreSQL schema from the active profile. CREATE TABLE IF NOT EXISTS kb_sol_decode_events ( id BIGSERIAL, processor_name TEXT NOT NULL, processor_version TEXT NOT NULL, input_key TEXT NOT NULL, input_hash TEXT NOT NULL, event_key TEXT NOT NULL, signature TEXT NOT NULL, slot BIGINT NOT NULL, instruction_path TEXT NOT NULL, program_id TEXT NOT NULL, protocol_code TEXT NOT NULL, surface_code TEXT NOT NULL, event_code TEXT NOT NULL, event_name TEXT NOT NULL, event_family TEXT NOT NULL, source_kind TEXT NOT NULL, confidence TEXT NOT NULL, proof_kind TEXT NOT NULL, proof_jsonb JSONB NOT NULL, payload_jsonb JSONB NOT NULL, transaction_failed BOOLEAN NOT NULL, transaction_error_jsonb JSONB, observation_committed BOOLEAN NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT pk_kb_sol_decode_events PRIMARY KEY (id), CONSTRAINT ck_kb_sol_decode_events_slot_non_negative CHECK (slot >= 0), CONSTRAINT ck_kb_sol_decode_events_failed_not_committed CHECK (NOT transaction_failed OR NOT observation_committed) ); CREATE UNIQUE INDEX IF NOT EXISTS ux_kb_sol_decode_events_processor_input_event ON kb_sol_decode_events (processor_name, processor_version, input_key, event_key); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_events_signature_path ON kb_sol_decode_events (signature, instruction_path); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_events_program_surface ON kb_sol_decode_events (program_id, surface_code, event_code); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_events_family_commit ON kb_sol_decode_events (event_family, transaction_failed, observation_committed); CREATE TABLE IF NOT EXISTS kb_sol_decode_coverage_declarations ( id BIGSERIAL, processor_name TEXT NOT NULL, processor_version TEXT NOT NULL, program_id TEXT NOT NULL, surface_code TEXT, entry_kind TEXT NOT NULL, entry_code TEXT NOT NULL, discriminator_hex TEXT, historical BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT pk_kb_sol_decode_coverage_declarations PRIMARY KEY (id) ); CREATE UNIQUE INDEX IF NOT EXISTS ux_kb_sol_decode_coverage_declarations_identity ON kb_sol_decode_coverage_declarations ( processor_name, processor_version, program_id, COALESCE(surface_code, ''), entry_kind, entry_code, COALESCE(discriminator_hex, '') ); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_coverage_declarations_program ON kb_sol_decode_coverage_declarations (program_id, processor_name, processor_version); CREATE TABLE IF NOT EXISTS kb_sol_decode_coverage_observations ( id BIGSERIAL, processor_name TEXT NOT NULL, processor_version TEXT NOT NULL, input_key TEXT NOT NULL, input_hash TEXT NOT NULL, signature TEXT NOT NULL, slot BIGINT NOT NULL, instruction_path TEXT NOT NULL, program_id TEXT NOT NULL, surface_code TEXT, entry_code TEXT, discriminator_hex TEXT, status TEXT NOT NULL, recognized BOOLEAN NOT NULL, decoded_count INTEGER NOT NULL DEFAULT 0, materialized_count INTEGER NOT NULL DEFAULT 0, error_count INTEGER NOT NULL DEFAULT 0, transaction_failed BOOLEAN NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT pk_kb_sol_decode_coverage_observations PRIMARY KEY (id), CONSTRAINT ck_kb_sol_decode_coverage_observations_slot_non_negative CHECK (slot >= 0), CONSTRAINT ck_kb_sol_decode_coverage_observations_counts_non_negative CHECK (decoded_count >= 0 AND materialized_count >= 0 AND error_count >= 0) ); CREATE UNIQUE INDEX IF NOT EXISTS ux_kb_sol_decode_coverage_observations_identity ON kb_sol_decode_coverage_observations (processor_name, processor_version, input_key); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_coverage_observations_program_status ON kb_sol_decode_coverage_observations (program_id, status, transaction_failed); CREATE INDEX IF NOT EXISTS ix_kb_sol_decode_coverage_observations_entry ON kb_sol_decode_coverage_observations (processor_name, processor_version, surface_code, entry_code); CREATE TABLE IF NOT EXISTS kb_sol_mat_events ( id BIGSERIAL, processor_name TEXT NOT NULL, processor_version TEXT NOT NULL, input_key TEXT NOT NULL, input_hash TEXT NOT NULL, output_key TEXT NOT NULL, source_event_key TEXT NOT NULL, source_decoder_name TEXT NOT NULL, source_decoder_version TEXT NOT NULL, source_decode_input_key TEXT NOT NULL, signature TEXT NOT NULL, slot BIGINT NOT NULL, materialized_family TEXT NOT NULL, payload_jsonb JSONB NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT pk_kb_sol_mat_events PRIMARY KEY (id), CONSTRAINT ck_kb_sol_mat_events_slot_non_negative CHECK (slot >= 0) ); CREATE UNIQUE INDEX IF NOT EXISTS ux_kb_sol_mat_events_processor_input_output ON kb_sol_mat_events (processor_name, processor_version, input_key, output_key); CREATE INDEX IF NOT EXISTS ix_kb_sol_mat_events_signature_family ON kb_sol_mat_events (source_decoder_name, source_decoder_version, source_decode_input_key, signature, materialized_family);