Files
Investidor-V2/migrations/003_mne_integrity.sql
T
nala 3dc7c5c649
tests / ci (push) Canceled after 0s
commit 30/9
2026-09-30 09:05:43 +02:00

49 lines
2.1 KiB
PL/PgSQL

-- Incremental hardening; no records or application tables are copied.
BEGIN;
SET LOCAL lock_timeout = '10s';
SELECT pg_advisory_xact_lock(290926, 170003);
DO $indexes$
DECLARE fk record; index_name text;
BEGIN
FOR fk IN
SELECT c.conrelid, c.conkey, c.conname, t.relname,
(SELECT string_agg(quote_ident(a.attname), ', ' ORDER BY k.position)
FROM unnest(c.conkey) WITH ORDINALITY k(attnum, position)
JOIN pg_attribute a ON a.attrelid=c.conrelid AND a.attnum=k.attnum) AS columns
FROM pg_constraint c JOIN pg_class t ON t.oid=c.conrelid
JOIN pg_namespace n ON n.oid=t.relnamespace
WHERE n.nspname='mne' AND c.contype='f'
ORDER BY t.relname,c.conname
LOOP
IF NOT EXISTS (
SELECT 1 FROM pg_index i JOIN pg_class ix ON ix.oid=i.indexrelid
JOIN pg_am am ON am.oid=ix.relam
WHERE i.indrelid=fk.conrelid AND i.indisvalid AND i.indisready
AND i.indpred IS NULL AND am.amname='btree'
AND i.indnkeyatts >= cardinality(fk.conkey)
AND ARRAY(SELECT x FROM unnest(i.indkey::smallint[]) WITH ORDINALITY u(x,p)
WHERE p <= cardinality(fk.conkey) ORDER BY p)=fk.conkey
) THEN
index_name := 'ix_mne_003_' || md5(fk.relname || ':' || fk.conname);
EXECUTE format('CREATE INDEX %I ON mne.%I (%s)', index_name, fk.relname, fk.columns);
EXECUTE format('COMMENT ON INDEX mne.%I IS %L', index_name, 'Owned by 003_mne_integrity');
END IF;
END LOOP;
END $indexes$;
CREATE OR REPLACE FUNCTION mne.reject_evidence_mutation() RETURNS trigger
LANGUAGE plpgsql SET search_path = pg_catalog AS $guard$
BEGIN
RAISE EXCEPTION 'MNE evidence is append-only: %.%', TG_TABLE_SCHEMA, TG_TABLE_NAME
USING ERRCODE = '23514';
END $guard$;
DO $triggers$
DECLARE table_name text;
BEGIN
FOREACH table_name IN ARRAY ARRAY['audit_events','business_status_history','document_versions','negotiation_events'] LOOP
EXECUTE format('CREATE OR REPLACE TRIGGER mne_evidence_immutable BEFORE UPDATE OR DELETE OR TRUNCATE ON mne.%I FOR EACH STATEMENT EXECUTE FUNCTION mne.reject_evidence_mutation()', table_name);
END LOOP;
END $triggers$;
COMMIT;