commit melhorias sgf

This commit is contained in:
2026-11-11 09:00:17 +02:00
parent 0b05a1192c
commit 1d11a5e57b
736 changed files with 40746 additions and 210 deletions
+35
View File
@@ -0,0 +1,35 @@
CREATE TABLE sd_versions(
id bigserial PRIMARY KEY,tenant_id bigint NOT NULL,company_id bigint NOT NULL,unit_id bigint NOT NULL,
document_key uuid NOT NULL,version integer NOT NULL CHECK(version>0),previous_id bigint UNIQUE REFERENCES sd_versions(id),
kind text NOT NULL CHECK(kind IN('receipt','credit_note','invoice_receipt')),
action text NOT NULL CHECK(action IN('prepare','review','issue')),state text NOT NULL CHECK(state IN('draft','approved','refused','issued')),
prepared_by bigint NOT NULL REFERENCES users(id),actor_id bigint NOT NULL REFERENCES users(id),data jsonb NOT NULL,dependencies jsonb NOT NULL,
reason text NOT NULL CHECK(length(reason)>=10),created_at timestamptz NOT NULL DEFAULT now(),
UNIQUE(tenant_id,company_id,unit_id,document_key,version),FOREIGN KEY(tenant_id,company_id,unit_id) REFERENCES units(tenant_id,company_id,id)
);
CREATE TABLE sd_outputs(id bigserial PRIMARY KEY,tenant_id bigint NOT NULL,company_id bigint NOT NULL,unit_id bigint NOT NULL,document_key uuid NOT NULL UNIQUE,version_id bigint NOT NULL UNIQUE REFERENCES sd_versions(id),kind text NOT NULL,number bigint NOT NULL,invoice_id bigint NOT NULL REFERENCES si_invoices(id),effect_id bigint REFERENCES sr_effects(id),snapshot jsonb NOT NULL,pdf_base64 text NOT NULL,pdf_sha256 char(64) NOT NULL,actor_id bigint NOT NULL REFERENCES users(id),created_at timestamptz NOT NULL DEFAULT now(),UNIQUE(tenant_id,company_id,unit_id,kind,number));
CREATE UNIQUE INDEX sd_receipt_allocation_once ON sd_outputs(effect_id) WHERE kind='receipt';
CREATE UNIQUE INDEX sd_credit_effect_once ON sd_outputs(effect_id) WHERE kind='credit_note';
CREATE UNIQUE INDEX sd_invoice_receipt_once ON sd_outputs(invoice_id) WHERE kind='invoice_receipt';
CREATE TABLE sd_commands(id bigserial PRIMARY KEY,tenant_id bigint NOT NULL,company_id bigint NOT NULL,unit_id bigint NOT NULL,actor_id bigint NOT NULL REFERENCES users(id),command_key uuid NOT NULL,request_hash char(64) NOT NULL,result jsonb NOT NULL,created_at timestamptz NOT NULL DEFAULT now(),UNIQUE(tenant_id,company_id,unit_id,actor_id,command_key));
CREATE FUNCTION sgf_sd_guard() RETURNS trigger LANGUAGE plpgsql AS $$
DECLARE p sd_versions; permission_name text;
BEGIN
PERFORM sgf_wo_environment();PERFORM 1 FROM companies WHERE id=NEW.company_id FOR UPDATE;
permission_name:='service_documents.'||CASE NEW.action WHEN 'review' THEN 'review' WHEN 'issue' THEN 'issue' ELSE 'prepare' END;
IF NOT EXISTS(SELECT 1 FROM permission_grants WHERE user_id=NEW.actor_id AND tenant_id=NEW.tenant_id AND company_id=NEW.company_id AND unit_id=NEW.unit_id AND permission=permission_name) THEN RAISE EXCEPTION 'SGF_SD_ACCESS'; END IF;
SELECT * INTO p FROM sd_versions WHERE (tenant_id,company_id,unit_id,document_key)=(NEW.tenant_id,NEW.company_id,NEW.unit_id,NEW.document_key) ORDER BY version DESC LIMIT 1;
IF (p.id IS NULL AND (NEW.version<>1 OR NEW.action<>'prepare' OR NEW.previous_id IS NOT NULL OR NEW.prepared_by<>NEW.actor_id)) OR(p.id IS NOT NULL AND(NEW.previous_id IS DISTINCT FROM p.id OR NEW.version<>p.version+1 OR NEW.kind<>p.kind OR NEW.prepared_by<>p.prepared_by OR p.state='issued')) THEN RAISE EXCEPTION 'SGF_SD_VERSION'; END IF;
IF NEW.action='review' AND(p.state<>'draft' OR NEW.actor_id=NEW.prepared_by) THEN RAISE EXCEPTION 'SGF_SD_SELF_REVIEW'; END IF;
IF NEW.action='issue' AND p.state<>'approved' THEN RAISE EXCEPTION 'SGF_SD_UNREVIEWED'; END IF;
RETURN NEW;
END; $$;
CREATE TRIGGER sd_guard BEFORE INSERT ON sd_versions FOR EACH ROW EXECUTE FUNCTION sgf_sd_guard();
CREATE TRIGGER sd_versions_immutable BEFORE UPDATE OR DELETE ON sd_versions FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
CREATE TRIGGER sd_outputs_immutable BEFORE UPDATE OR DELETE ON sd_outputs FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
CREATE TRIGGER sd_commands_immutable BEFORE UPDATE OR DELETE ON sd_commands FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
REVOKE ALL ON sd_versions,sd_outputs,sd_commands FROM PUBLIC;
REVOKE ALL ON FUNCTION sgf_sd_guard() FROM PUBLIC;
CREATE TRIGGER sd_outputs_test BEFORE INSERT ON sd_outputs FOR EACH ROW EXECUTE FUNCTION sgf_wo_test_only();
CREATE TRIGGER sd_commands_test BEFORE INSERT ON sd_commands FOR EACH ROW EXECUTE FUNCTION sgf_wo_test_only();