-- Validation tests: run in a single transaction per block -- =========================================================== -- 1. SEED: units + users INSERT INTO units(code, name, type) VALUES ('DHYD', 'Đại học Y Dược TP.HCM', 'TRUONG'), ('KHCN', 'Phòng Khoa học Công nghệ', 'PHONG'); INSERT INTO users(full_name, title, email, id_number, unit_id, qualification, user_type) VALUES ('Trần Hùng', 'PGS.TS', 'tranhung@ump.edu.vn', '001001', 1, 'Tiến sĩ', 'AUTHOR'), ('Đỗ Quốc Vũ', 'CN.', 'doquocvu@ump.edu.vn', '001002', 2, 'Cử nhân', 'AUTHOR'), ('Nguyễn Hội đồng A', 'PGS.TS', 'hdA@ump.edu.vn', '002001', 1, 'Tiến sĩ', 'COUNCIL'); -- 2. CREATE an application in DRAFT state INSERT INTO applications(code, title, registration_year, status, purpose, primary_unit_id, created_by) VALUES ('SK-2025-001', 'Quy trình xét duyệt Đạo đức trong nghiên cứu trên động vật', 2025, 'DRAFT', 'Chuẩn hoá quy trình xét duyệt hồ sơ', 2, 2); -- 3. ADD authors with DEFERRED constraint (sums to 100 at COMMIT) BEGIN; INSERT INTO application_authors(application_id, user_id, contribution_pct, role) VALUES (1, 1, 50, 'CO_AUTHOR'), (1, 2, 50, 'PRIMARY'); -- At this point sum=100, but app is DRAFT so constraint doesn't even care yet COMMIT; -- Verify SELECT 'Authors inserted:' AS step, count(*) FROM application_authors; -- 4. TRY to submit the application (DRAFT → SUBMITTED): needs classification -- This should FAIL the check constraint because no classification flag is set \echo 'Test 4: should FAIL (missing classification)' UPDATE applications SET status='SUBMITTED' WHERE application_id=1; \echo '' -- Fix and retry UPDATE applications SET is_technical_solution = TRUE, status = 'SUBMITTED' WHERE application_id = 1; SELECT 'After submit:' AS step, status, submitted_at FROM applications WHERE application_id=1; -- 5. TRY invalid transition SUBMITTED → APPROVED (should FAIL) \echo 'Test 5: should FAIL (illegal transition)' UPDATE applications SET status='APPROVED' WHERE application_id=1; \echo '' -- Valid transitions UPDATE applications SET status='UNDER_REVIEW' WHERE application_id=1; -- 6. EVALUATOR scores the application INSERT INTO evaluations(application_id, evaluator_id, novelty_score, effectiveness_score, conclusion) VALUES (1, 3, 35, 50, 'Đề xuất công nhận'); SELECT 'Evaluation:' AS step, novelty_score, effectiveness_score, total_score FROM evaluations; -- 7. Move to EVALUATED → APPROVED UPDATE applications SET status='EVALUATED' WHERE application_id=1; UPDATE applications SET status='APPROVED' WHERE application_id=1; SELECT 'Final status:' AS step, status, decided_at IS NOT NULL AS has_decision_time FROM applications WHERE application_id=1; -- 8. READ: summary view SELECT code, title, status, author_names, avg_score, num_evaluations FROM v_application_summary; -- 9. AUDIT trail: who changed what? SELECT table_name, action, changed_at, (new_data->>'status') AS new_status FROM audit_log WHERE table_name = 'applications' ORDER BY log_id; -- 10. Bad contribution sum should fail at COMMIT \echo 'Test 10: should FAIL (sum != 100 on submitted app)' BEGIN; UPDATE application_authors SET contribution_pct = 30 WHERE application_id=1 AND user_id=1; -- sum is now 30+50=80, but app is APPROVED so trigger will reject at commit COMMIT;