| Version 6 (modified by , 2 months ago) ( diff ) |
|---|
Тригери
Приказ на дефинирани тригери, со нивната улога, кога се активираат и зошто се корисни.
1) Тригер за залиха (inventory_brandedmedicine) – сетирање датум и забрана за негативни количини
Што прави: Автоматски поставува last_changed на денешен датум и спречува quantity < 0.
Кога се активира: Пред INSERT или UPDATE на табелата inventory_brandedmedicine.
Зошто е корисен: Осигурува конзистентност на залихата и забрана за нелогични вредности.
CREATE OR REPLACE FUNCTION synergymed.fn_inventory_bm_before()
RETURNS TRIGGER
LANGUAGE plpgsql AS $$
BEGIN
IF NEW.quantity IS NULL OR NEW.quantity < 0 THEN
RAISE EXCEPTION 'Количината не смее да биде негативна';
END IF;
NEW.last_changed := CURRENT_DATE;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_inventory_bm_before_ins ON synergymed.inventory_brandedmedicine;
CREATE TRIGGER trg_inventory_bm_before_ins
BEFORE INSERT ON synergymed.inventory_brandedmedicine
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_bm_before();
DROP TRIGGER IF EXISTS trg_inventory_bm_before_upd ON synergymed.inventory_brandedmedicine;
CREATE TRIGGER trg_inventory_bm_before_upd
BEFORE UPDATE ON synergymed.inventory_brandedmedicine
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_bm_before();
2) Тригер за лојалност (payment) – поени на клуб-картичка при успешно плаќање
Што прави: Додава поени на clubcard ако payment.status = 'завршено'.
Кога се активира: По INSERT или UPDATE на табелата payment.
Зошто е корисен: Автоматска интеграција на лојалност со финансиски трансакции.
CREATE OR REPLACE FUNCTION synergymed.fn_payment_loyalty_after()
RETURNS TRIGGER
LANGUAGE plpgsql AS $$
DECLARE v_inc INT;
BEGIN
IF NEW.status = 'завршено' THEN
IF EXISTS (SELECT 1 FROM synergymed.clubcard WHERE id = NEW.client_id) THEN
v_inc := GREATEST(0, FLOOR(COALESCE(NEW.amount,0) / 10));
UPDATE synergymed.clubcard
SET points = points + v_inc
WHERE id = NEW.client_id;
END IF;
END IF;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_payment_loyalty ON synergymed.payment;
CREATE TRIGGER trg_payment_loyalty
AFTER INSERT OR UPDATE OF status, amount ON synergymed.payment
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_payment_loyalty_after();
3) Тригер за верификација на клиент (sensitiveclientdata) – автоматско одразување во client.is_verified
Што прави: Ако verification_status = 'верифицирано', тогаш client.is_verified = TRUE; ако е 'одбиено' → FALSE.
Кога се активира: По INSERT или UPDATE на табелата sensitiveclientdata.
Зошто е корисен: Автоматски ја усогласува регулаторната состојба на клиентот со flag-от во Client.
CREATE OR REPLACE FUNCTION synergymed.fn_sensitiveclientdata_affect_client_after()
RETURNS TRIGGER
LANGUAGE plpgsql AS $$
BEGIN
IF NEW.verification_status = 'верифицирано' THEN
UPDATE synergymed.client SET is_verified = TRUE WHERE id = NEW.client_id;
ELSIF NEW.verification_status = 'одбиено' THEN
UPDATE synergymed.client SET is_verified = FALSE WHERE id = NEW.client_id;
END IF;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_sensitiveclientdata_affect_client ON synergymed.sensitiveclientdata;
CREATE TRIGGER trg_sensitiveclientdata_affect_client
AFTER INSERT OR UPDATE OF verification_status ON synergymed.sensitiveclientdata
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_sensitiveclientdata_affect_client_after();
4) Тригер за интеракции на лекови (medicineinteraction) – симетрија и анти-рефлексивност
Што прави: Спречува интеракција лек-со-себе, и редоследува пар (id1, id2) така што id1 < id2.
Кога се активира: Пред INSERT или UPDATE на табелата medicineinteraction.
Зошто е корисен: Гарантира уникатни и чисти парови лекови.
CREATE OR REPLACE FUNCTION synergymed.fn_medicineinteraction_order_before()
RETURNS TRIGGER
LANGUAGE plpgsql AS $$
DECLARE a INT; b INT;
BEGIN
IF NEW.medicine_id_1 = NEW.medicine_id_2 THEN
RAISE EXCEPTION 'Лек не може да биде во интеракција сам со себе';
END IF;
a := LEAST(NEW.medicine_id_1, NEW.medicine_id_2);
b := GREATEST(NEW.medicine_id_1, NEW.medicine_id_2);
NEW.medicine_id_1 := a;
NEW.medicine_id_2 := b;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_mi_order_before_ins ON synergymed.medicineinteraction;
CREATE TRIGGER trg_mi_order_before_ins
BEFORE INSERT ON synergymed.medicineinteraction
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_medicineinteraction_order_before();
DROP TRIGGER IF EXISTS trg_mi_order_before_upd ON synergymed.medicineinteraction;
CREATE TRIGGER trg_mi_order_before_upd
BEFORE UPDATE ON synergymed.medicineinteraction
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_medicineinteraction_order_before();
CREATE UNIQUE INDEX IF NOT EXISTS ux_mi_pair
ON synergymed.medicineinteraction (medicine_id_1, medicine_id_2);
5) Тригер за авто-ажурирање на каталогот на аптеки
Што прави: Кога се менува inventory_brandedmedicine, автоматски додава записи во pharmacy_catalog за да гарантира дека секој производ што е во залиха е и во каталогот на аптеката.
Кога се активира: По INSERT или UPDATE на табелата inventory_brandedmedicine.
Зошто е корисен: Ја одржува усогласеноста меѓу залихи и каталог, без рачна интервенција.
CREATE OR REPLACE FUNCTION synergymed.fn_inventory_autocatalog_after()
RETURNS TRIGGER
LANGUAGE plpgsql AS $$
DECLARE
v_pharmacy_id INT;
BEGIN
SELECT ph.company_id INTO v_pharmacy_id
FROM synergymed.inventory i
JOIN synergymed.facility f ON f.id = i.facility_id
JOIN synergymed.pharmacy ph ON ph.company_id = f.company_id
WHERE i.id = COALESCE(NEW.inventory_id, OLD.inventory_id)
LIMIT 1;
IF v_pharmacy_id IS NOT NULL THEN
INSERT INTO synergymed.pharmacy_catalog(pharmacy_id, branded_medicine_id)
VALUES (v_pharmacy_id, COALESCE(NEW.branded_medicine_id, OLD.branded_medicine_id))
ON CONFLICT DO NOTHING;
END IF;
RETURN COALESCE(NEW, OLD);
END;
$$;
DROP TRIGGER IF EXISTS trg_inventory_autocatalog_ins ON synergymed.inventory_brandedmedicine;
CREATE TRIGGER trg_inventory_autocatalog_ins
AFTER INSERT ON synergymed.inventory_brandedmedicine
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_autocatalog_after();
DROP TRIGGER IF EXISTS trg_inventory_autocatalog_upd ON synergymed.inventory_brandedmedicine;
CREATE TRIGGER trg_inventory_autocatalog_upd
AFTER UPDATE OF quantity ON synergymed.inventory_brandedmedicine
FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_autocatalog_after();
6) Тригер за блокирање на клиент со повеќе неуспешни плаќања
Што прави: Кога клиент има 3 или повеќе неуспешни плаќања во последните 10 дена, автоматски го поставува is_verified = FALSE во табелата Client.
Кога се активира: По INSERT или UPDATE на табелата payment кога статусот е „неуспешно“.
Зошто е корисен: Спречува понатамошни обиди за нарачки и злоупотреба од клиенти со повеќекратни неуспешни трансакции, со што ја зголемува безбедноста и стабилноста на системот.
CREATE OR REPLACE FUNCTION synergymed.fn_block_client_after_failed_payment()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
DECLARE
v_failures INT;
BEGIN
SELECT COUNT(*) INTO v_failures
FROM synergymed.payment p
WHERE p.client_id = NEW.client_id
AND p.status = 'неуспешно'
AND p.payment_date >= (CURRENT_DATE - INTERVAL '10 days');
IF v_failures >= 3 THEN
UPDATE synergymed.client
SET is_verified = FALSE
WHERE user_id = NEW.client_id;
END IF;
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_block_client_after_failed_payment ON synergymed.payment;
CREATE TRIGGER trg_block_client_after_failed_payment
AFTER INSERT OR UPDATE OF status ON synergymed.payment
FOR EACH ROW
WHEN (NEW.status = 'неуспешно')
EXECUTE FUNCTION synergymed.fn_block_client_after_failed_payment();
