CREATE TRIGGER ledger_immutable_update BEFORE UPDATE ON ledger BEGIN SELECT RAISE(ABORT, 'Catatan keuangan tidak dapat diubah; gunakan koreksi'); END;
--> statement-breakpoint
CREATE TRIGGER ledger_immutable_delete BEFORE DELETE ON ledger BEGIN SELECT RAISE(ABORT, 'Catatan keuangan tidak dapat dihapus'); END;
--> statement-breakpoint
CREATE TRIGGER verified_donation_immutable BEFORE UPDATE OF amount,program_id,name,contact,receipt_snapshot ON donations WHEN OLD.verified_at IS NOT NULL BEGIN SELECT RAISE(ABORT, 'Donasi terverifikasi tidak dapat diubah'); END;
--> statement-breakpoint
CREATE TRIGGER verified_donation_no_delete BEFORE DELETE ON donations WHEN OLD.verified_at IS NOT NULL BEGIN SELECT RAISE(ABORT, 'Donasi terverifikasi tidak dapat dihapus'); END;
--> statement-breakpoint
CREATE TRIGGER bank_match_capacity BEFORE INSERT ON bank_matches WHEN NOT EXISTS (SELECT 1 FROM bank_matches WHERE bank_id=NEW.bank_id AND donation_id=NEW.donation_id) BEGIN
 SELECT CASE WHEN NEW.amount+(SELECT COALESCE(SUM(amount),0) FROM bank_matches WHERE bank_id=NEW.bank_id)>(SELECT credit FROM bank_transactions WHERE id=NEW.bank_id) THEN RAISE(ABORT,'Alokasi melebihi kredit bank') END;
 SELECT CASE WHEN NEW.amount+(SELECT COALESCE(SUM(amount),0) FROM bank_matches WHERE donation_id=NEW.donation_id)>(SELECT amount FROM donations WHERE id=NEW.donation_id) THEN RAISE(ABORT,'Alokasi melebihi nominal donasi') END;
 SELECT CASE WHEN (SELECT status FROM donations WHERE id=NEW.donation_id) IN ('verified','refunded') THEN RAISE(ABORT,'Pencocokan donasi terverifikasi dikunci') END;
END;
--> statement-breakpoint
CREATE TRIGGER bank_matches_immutable_update BEFORE UPDATE ON bank_matches BEGIN SELECT RAISE(ABORT,'Pencocokan tidak dapat diubah diam-diam'); END;
--> statement-breakpoint
CREATE TRIGGER bank_matches_locked_delete BEFORE DELETE ON bank_matches WHEN (SELECT status FROM donations WHERE id=OLD.donation_id) IN ('verified','refunded') BEGIN SELECT RAISE(ABORT,'Pencocokan terverifikasi dikunci'); END;
--> statement-breakpoint
CREATE TRIGGER receipt_requires_match BEFORE INSERT ON ledger WHEN NEW.kind='receipt' AND NOT EXISTS(SELECT 1 FROM ledger WHERE source_key=NEW.source_key) BEGIN
 SELECT CASE WHEN NOT EXISTS(SELECT 1 FROM donations WHERE id=NEW.donation_id AND amount=NEW.amount AND program_id IS NEW.program_id AND status IN ('waiting_verification','waiting_payment','expired')) THEN RAISE(ABORT,'Penerimaan tidak sesuai permintaan donasi') END;
 SELECT CASE WHEN (SELECT COALESCE(SUM(amount),0) FROM bank_matches WHERE donation_id=NEW.donation_id)!=NEW.amount THEN RAISE(ABORT,'Pencocokan penerimaan bank belum lengkap') END;
END;
--> statement-breakpoint
CREATE TRIGGER ledger_balance_guard BEFORE INSERT ON ledger WHEN NEW.kind IN ('expense','fee','refund','receipt_reversal','allocation_out') AND NOT EXISTS(SELECT 1 FROM ledger WHERE source_key=NEW.source_key) BEGIN
 SELECT CASE WHEN NEW.amount>(SELECT COALESCE(SUM(CASE WHEN kind IN ('receipt','correction_credit','allocation_in') THEN amount ELSE -amount END),0) FROM ledger WHERE program_id IS NEW.program_id) THEN RAISE(ABORT,'Saldo dana tidak cukup') END;
END;
--> statement-breakpoint
CREATE TRIGGER refund_limit BEFORE INSERT ON ledger WHEN NEW.kind IN ('refund','receipt_reversal') AND NOT EXISTS(SELECT 1 FROM ledger WHERE source_key=NEW.source_key) BEGIN
 SELECT CASE WHEN NEW.amount+(SELECT COALESCE(SUM(amount),0) FROM ledger WHERE donation_id=NEW.donation_id AND kind IN ('refund','receipt_reversal'))>(SELECT amount FROM donations WHERE id=NEW.donation_id) THEN RAISE(ABORT,'Pengembalian atau koreksi melebihi penerimaan') END;
END;
--> statement-breakpoint
CREATE TRIGGER correction_limit BEFORE INSERT ON ledger WHEN NEW.kind='correction_credit' AND NOT EXISTS(SELECT 1 FROM ledger WHERE source_key=NEW.source_key) BEGIN
 SELECT CASE WHEN NEW.amount+(SELECT COALESCE(SUM(amount),0) FROM ledger WHERE related_id=NEW.related_id AND kind='correction_credit')>(SELECT amount FROM ledger WHERE id=NEW.related_id AND kind IN ('expense','fee')) THEN RAISE(ABORT,'Koreksi melebihi biaya awal') END;
END;
--> statement-breakpoint
CREATE TRIGGER audit_no_delete BEFORE DELETE ON audit BEGIN SELECT RAISE(ABORT,'Riwayat aktivitas tidak dapat dihapus'); END;
--> statement-breakpoint
CREATE TRIGGER audit_no_update BEFORE UPDATE ON audit BEGIN SELECT RAISE(ABORT,'Riwayat aktivitas tidak dapat diubah'); END;
