75 行
4.2 KiB
Bash
75 行
4.2 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
[[ "${RUN_ISOLATED_DB_TEST:-}" == "1" ]] || { printf '%s\n' 'Set RUN_ISOLATED_DB_TEST=1 to run a disposable local database test.'; exit 1; }
|
|
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
migration_name=20260909210000_reimbursement_draft_expense_type
|
|
container_id="$(docker run -d --rm --network none --tmpfs /var/lib/postgresql/data -e POSTGRES_HOST_AUTH_METHOD=trust postgres:16-alpine)"
|
|
trap 'docker rm -f "$container_id" >/dev/null' EXIT
|
|
ready=false
|
|
for attempt in $(seq 1 30); do
|
|
if docker exec "$container_id" pg_isready -U postgres >/dev/null 2>&1; then ready=true; break; fi
|
|
sleep 1
|
|
done
|
|
[[ "$ready" == true ]] || { printf '%s\n' 'Disposable database did not become ready.'; exit 1; }
|
|
run_sql() { docker exec -i "$container_id" psql -X -q -v ON_ERROR_STOP=1 -U postgres; }
|
|
for migration in "$project_root"/server/prisma/migrations/*/migration.sql; do
|
|
[[ "$migration" == *"/$migration_name/"* ]] && continue
|
|
run_sql < "$migration" >/dev/null
|
|
done
|
|
run_sql <<'SQL'
|
|
INSERT INTO departments (id, name) VALUES ('10000000-0000-4000-8000-000000000001', 'synthetic-department');
|
|
INSERT INTO employees (id, employee_no, name, email, department_id, title, hire_date, bank_account_encrypted, bank_name, password_hash)
|
|
VALUES ('10000000-0000-4000-8000-000000000002', 'synthetic-migration', 'synthetic', '[email protected]', '10000000-0000-4000-8000-000000000001', 'synthetic', '2026-09-09', 'not-real-bank-data', 'synthetic', 'not-a-login-hash');
|
|
INSERT INTO expense_types (id, code, name, category, sort_order)
|
|
VALUES ('10000000-0000-4000-8000-000000000003', 'synthetic_migration', 'synthetic', 'office', 999);
|
|
INSERT INTO reimbursement_forms (id, owner_id, submitter_id, department_id, reimbursement_date)
|
|
VALUES ('10000000-0000-4000-8000-000000000004', '10000000-0000-4000-8000-000000000002', '10000000-0000-4000-8000-000000000002', '10000000-0000-4000-8000-000000000001', '2026-09-09');
|
|
INSERT INTO reimbursement_items (id, reimbursement_id, expense_type_id, expense_date, amount, description)
|
|
VALUES ('10000000-0000-4000-8000-000000000005', '10000000-0000-4000-8000-000000000004', '10000000-0000-4000-8000-000000000003', '2026-09-09', 100, 'synthetic');
|
|
DO $$ BEGIN
|
|
BEGIN
|
|
UPDATE reimbursement_items SET expense_type_id = NULL;
|
|
RAISE EXCEPTION 'baseline unexpectedly accepts null classification';
|
|
EXCEPTION WHEN not_null_violation THEN NULL;
|
|
END;
|
|
END $$;
|
|
SQL
|
|
run_sql < "$project_root/server/prisma/migrations/$migration_name/migration.sql"
|
|
run_sql <<'SQL'
|
|
DO $$ BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM reimbursement_items WHERE expense_type_id = '10000000-0000-4000-8000-000000000003' AND amount = 100) THEN
|
|
RAISE EXCEPTION 'existing item changed';
|
|
END IF;
|
|
END $$;
|
|
INSERT INTO reimbursement_items (id, reimbursement_id, expense_type_id, expense_date, amount, description)
|
|
VALUES ('10000000-0000-4000-8000-000000000006', '10000000-0000-4000-8000-000000000004', NULL, '2026-09-09', 50, 'synthetic unclassified');
|
|
DO $$ BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM reimbursement_items WHERE id = '10000000-0000-4000-8000-000000000006' AND expense_type_id IS NULL) THEN
|
|
RAISE EXCEPTION 'unclassified item not persisted';
|
|
END IF;
|
|
BEGIN
|
|
UPDATE reimbursement_items SET expense_type_id = '10000000-0000-4000-8000-000000000099';
|
|
RAISE EXCEPTION 'foreign key no longer enforced';
|
|
EXCEPTION WHEN foreign_key_violation THEN NULL;
|
|
END;
|
|
BEGIN
|
|
UPDATE reimbursement_items SET amount = NULL;
|
|
RAISE EXCEPTION 'amount became nullable';
|
|
EXCEPTION WHEN not_null_violation THEN NULL;
|
|
END;
|
|
BEGIN
|
|
UPDATE reimbursement_items SET expense_date = NULL;
|
|
RAISE EXCEPTION 'date became nullable';
|
|
EXCEPTION WHEN not_null_violation THEN NULL;
|
|
END;
|
|
BEGIN
|
|
ALTER TABLE reimbursement_items ALTER COLUMN expense_type_id SET NOT NULL;
|
|
RAISE EXCEPTION 'unsafe rollback unexpectedly succeeded';
|
|
EXCEPTION WHEN not_null_violation THEN NULL;
|
|
END;
|
|
END $$;
|
|
UPDATE reimbursement_items SET expense_type_id = '10000000-0000-4000-8000-000000000003' WHERE expense_type_id IS NULL;
|
|
ALTER TABLE reimbursement_items ALTER COLUMN expense_type_id SET NOT NULL;
|
|
SQL
|
|
printf '%s\n' 'PASS: baseline, persisted null classification, unchanged existing data, FK, required amount/date, guarded rollback.'
|