commit melhorias sgf
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
CREATE TABLE an_criteria(id bigserial PRIMARY KEY,tenant_id bigint NOT NULL,company_id bigint NOT NULL,unit_id bigint NOT NULL,metric text NOT NULL CHECK(metric IN('cash_coverage_single_payable','cash_expense_share')),version bigint NOT NULL CHECK(version>0),previous_id bigint UNIQUE REFERENCES an_criteria(id),action text NOT NULL CHECK(action IN('prepare','review')),state text NOT NULL CHECK(state IN('prepared','reviewed','refused')),prepared_by bigint NOT NULL REFERENCES users(id),actor_id bigint NOT NULL REFERENCES users(id),definition jsonb NOT NULL,source_hash char(64) NOT NULL,reason text NOT NULL CHECK(length(reason)>=10),created_at timestamptz NOT NULL DEFAULT now(),UNIQUE(tenant_id,company_id,unit_id,metric,version),FOREIGN KEY(tenant_id,company_id,unit_id) REFERENCES units(tenant_id,company_id,id));
|
||||
CREATE TABLE an_results(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),criterion_id bigint REFERENCES an_criteria(id),input jsonb NOT NULL,result jsonb NOT NULL,source_snapshot jsonb NOT NULL,reason text NOT NULL CHECK(length(reason)>=10),created_at timestamptz NOT NULL DEFAULT now(),FOREIGN KEY(tenant_id,company_id,unit_id) REFERENCES units(tenant_id,company_id,id));
|
||||
CREATE TABLE an_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_an_guard() RETURNS trigger LANGUAGE plpgsql AS $$
|
||||
DECLARE p an_criteria;permission_name text;
|
||||
BEGIN
|
||||
PERFORM sgf_wo_environment();PERFORM 1 FROM companies WHERE tenant_id=NEW.tenant_id AND id=NEW.company_id FOR UPDATE;
|
||||
IF TG_TABLE_NAME='an_results' THEN permission_name:='financial_analysis.prepare';ELSE permission_name:='financial_analysis.'||NEW.action;END IF;
|
||||
IF NOT EXISTS(SELECT 1 FROM company_memberships WHERE user_id=NEW.actor_id AND tenant_id=NEW.tenant_id AND company_id=NEW.company_id) OR 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_AN_ACCESS';END IF;
|
||||
IF TG_TABLE_NAME='an_results' THEN RETURN NEW;END IF;
|
||||
SELECT * INTO p FROM an_criteria WHERE (tenant_id,company_id,unit_id,metric)=(NEW.tenant_id,NEW.company_id,NEW.unit_id,NEW.metric) ORDER BY version DESC LIMIT 1;
|
||||
IF NEW.version<>coalesce(p.version,0)+1 OR NEW.previous_id IS DISTINCT FROM p.id THEN RAISE EXCEPTION 'SGF_AN_STALE';END IF;
|
||||
IF NEW.action='prepare' THEN IF NEW.state<>'prepared' OR NEW.prepared_by<>NEW.actor_id THEN RAISE EXCEPTION 'SGF_AN_PREPARE';END IF;
|
||||
ELSE IF p.id IS NULL OR p.state<>'prepared' OR NEW.prepared_by<>p.prepared_by OR NEW.actor_id=p.prepared_by OR NEW.definition IS DISTINCT FROM p.definition OR NEW.source_hash<>p.source_hash OR NEW.state NOT IN('reviewed','refused') THEN RAISE EXCEPTION 'SGF_AN_REVIEW';END IF;END IF;
|
||||
RETURN NEW;
|
||||
END; $$;
|
||||
CREATE TRIGGER an_criterion_guard BEFORE INSERT ON an_criteria FOR EACH ROW EXECUTE FUNCTION sgf_an_guard();
|
||||
CREATE TRIGGER an_result_guard BEFORE INSERT ON an_results FOR EACH ROW EXECUTE FUNCTION sgf_an_guard();
|
||||
CREATE TRIGGER an_criteria_immutable BEFORE UPDATE OR DELETE ON an_criteria FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
|
||||
CREATE TRIGGER an_results_immutable BEFORE UPDATE OR DELETE ON an_results FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
|
||||
CREATE TRIGGER an_commands_immutable BEFORE UPDATE OR DELETE ON an_commands FOR EACH ROW EXECUTE FUNCTION sgf_append_only_audit();
|
||||
CREATE TRIGGER an_commands_test BEFORE INSERT ON an_commands FOR EACH ROW EXECUTE FUNCTION sgf_wo_test_only();
|
||||
REVOKE ALL ON an_criteria,an_results,an_commands FROM PUBLIC;
|
||||
REVOKE ALL ON SEQUENCE an_criteria_id_seq,an_results_id_seq,an_commands_id_seq FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION sgf_an_guard() FROM PUBLIC;
|
||||
Reference in New Issue
Block a user