-- 0062 was released before the verification challenge table and the complete -- stream-state columns were added. Installations that already recorded 0062 -- need a new immutable migration to repair that drift. ALTER TABLE gateway_security_event_stream_state ADD COLUMN IF NOT EXISTS stream_status text NOT NULL DEFAULT 'unknown', ADD COLUMN IF NOT EXISTS created_at timestamptz NOT NULL DEFAULT now(); DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conrelid = 'gateway_security_event_stream_state'::regclass AND conname = 'gateway_security_event_stream_state_status' ) THEN ALTER TABLE gateway_security_event_stream_state ADD CONSTRAINT gateway_security_event_stream_state_status CHECK (stream_status IN ('unknown','enabled','paused','disabled')); END IF; END $$; CREATE TABLE IF NOT EXISTS gateway_security_event_verification_challenges ( issuer text NOT NULL, audience text NOT NULL, state_hash bytea NOT NULL, created_at timestamptz NOT NULL, expires_at timestamptz NOT NULL, PRIMARY KEY (issuer, audience, state_hash), FOREIGN KEY (issuer, audience) REFERENCES gateway_security_event_stream_state(issuer, audience) ON DELETE CASCADE, CONSTRAINT gateway_security_event_verification_challenge_hash CHECK (octet_length(state_hash) = 32) ); CREATE INDEX IF NOT EXISTS idx_gateway_security_event_challenges_expiry ON gateway_security_event_verification_challenges(expires_at);