# Paliad — developer entrypoints. # # Targets here are the gate tier from the test-strategy design # (docs/design-paliad-test-strategy-2026-05-19.md). Slice 1 lands: # # make verify-migrations — dry-run every pending migration (BEGIN..ROLLBACK) # plus the full boot smoke (apply + tracker # advances + /healthz returns 200). # make verify-mig — alias for verify-migrations. # make test — short test pass: go test ./internal/... -short # plus the cmd/server package. Includes the # live-DB tests when TEST_DATABASE_URL is set, # skips them otherwise. # make test-go — go test ./... -race (full Go suite). # # Future slices will extend this with: # make test-frontend — bun test (Slice 3 / Slice 6) # make e2e — Playwright golden-path suite (Slice 4) # # All targets are idempotent. None of them write to the filesystem outside # the test runner's working dirs. None of them touch internal/db/migrations/ # files. .PHONY: help verify-migrations verify-mig verify-mig-app test test-go test-frontend refresh-snapshot help: @echo "Paliad — developer targets" @echo "" @echo " verify-migrations Dry-run pending migrations + boot smoke (needs TEST_DATABASE_URL)" @echo " verify-mig Alias for verify-migrations" @echo " verify-mig-app End-to-end migration smoke as non-superuser role" @echo " (needs TEST_APP_DATABASE_URL — t-paliad-282 / m/paliad#114)" @echo " test Short test pass — covers gate tier" @echo " test-go Full Go suite with race detector" @echo " test-frontend Frontend bun:test suite" @echo "" @echo "Set TEST_DATABASE_URL to enable live-DB tests. Example:" @echo " export TEST_DATABASE_URL=postgres://paliad:...@localhost:11833/paliad_test" @echo "" @echo "Set TEST_APP_DATABASE_URL to enable the role-split smoke. Example:" @echo " export TEST_APP_DATABASE_URL=postgres://paliad_app:...@localhost:5432/paliad_scratch" # Gate target — the test that would have caught mig 098 / mig 099 before # deploy. Combines: # - TestMigrations_DryRun (internal/db): per-migration BEGIN..ROLLBACK # - TestBootSmoke (cmd/server): apply-end-to-end + tracker advances # + /healthz 200 # # Requires TEST_DATABASE_URL. Without it, both tests skip and the target # is effectively a no-op — guard against that explicitly so CI doesn't # silently green a missing env var. verify-migrations: @if [ -z "$$TEST_DATABASE_URL" ]; then \ echo "ERROR: TEST_DATABASE_URL is not set."; \ echo " The migration gate cannot run without a scratch DB."; \ echo " Set TEST_DATABASE_URL to a Postgres URL the test can"; \ echo " open transactions against, e.g."; \ echo " export TEST_DATABASE_URL=postgres://paliad:PW@localhost:11833/paliad_test"; \ exit 2; \ fi @echo "==> migration dry-run (per-mig BEGIN..ROLLBACK)" go test -count=1 -run TestMigrations_DryRun ./internal/db/ @echo "==> boot smoke (apply + tracker + /healthz)" go test -count=1 -run TestBootSmoke ./cmd/server/ verify-mig: verify-migrations # Gate-tier test pass. -short skips the slow live-DB tests when the # author opts out via `if testing.Short() { t.Skip(...) }`; today most of # paliad's live-DB tests gate on TEST_DATABASE_URL instead, so -short is # forward-compatible rather than load-bearing. test: go test -short ./internal/... ./cmd/... # Full Go suite with race detection. Slower but catches concurrent-map # regressions that -short would skip; intended for the merge-to-main gate # (full suite, not per-PR). test-go: go test -race ./... # Frontend bun:test suite. Runs the 4 existing pure-TS tests today; will # grow as mendel's Slice 3 (frontend test infill) lands. test-frontend: cd frontend && bun test # Role-split end-to-end migration smoke — the catch for the mig 129 42501 # ownership class (m/paliad#114). Runs ApplyMigrations as a non-superuser # role against TEST_APP_DATABASE_URL. Fails the build if any migration # assumes more privilege than the deploy role has. # # Developer setup (local): # psql -c "CREATE ROLE paliad_app LOGIN PASSWORD 'ci' NOSUPERUSER;" # psql -c "CREATE DATABASE paliad_scratch OWNER paliad_app;" # export TEST_APP_DATABASE_URL=postgres://paliad_app:ci@localhost:5432/paliad_scratch verify-mig-app: @if [ -z "$$TEST_APP_DATABASE_URL" ]; then \ echo "ERROR: TEST_APP_DATABASE_URL is not set."; \ echo " The role-split migration smoke cannot run without a non-superuser scratch DB."; \ echo " See Makefile comments above this target for setup."; \ exit 2; \ fi go test -count=1 -run TestMigrations_EndToEndAsAppRole ./internal/db/ # Refresh the prod schema snapshot used by CI's migration smoke # (t-paliad-282 / m/paliad#114). Connects to youpc-supabase prod, dumps # the paliad schema + applied_migrations rows, strips rows beyond the # current branch's max on-disk version, and writes # internal/db/testdata/prod-snapshot.sql. # # When to refresh: # - After merging a PR that added a new migration to main. # - When CI's migration smoke starts spuriously failing because the # snapshot's applied set diverges from on-disk by more than this # branch's worth of new migs. # # Requires PALIAD_PROD_DATABASE_URL env var (a Postgres URL with # pg_dump rights on youpc-supabase). Example: # export PALIAD_PROD_DATABASE_URL='postgres://postgres:PW@100.99.98.201:11833/postgres' refresh-snapshot: @if [ -z "$$PALIAD_PROD_DATABASE_URL" ]; then \ echo "ERROR: PALIAD_PROD_DATABASE_URL is not set."; \ echo " Refresh requires read access to youpc-supabase prod."; \ exit 2; \ fi @echo "==> dumping paliad schema (no owner, no privs)..." @pg_dump --schema-only --schema=paliad --no-owner --no-privileges \ --no-publications --no-subscriptions \ "$$PALIAD_PROD_DATABASE_URL" > internal/db/testdata/prod-snapshot.sql.tmp @echo "==> appending applied_migrations rows..." @pg_dump --data-only --table=paliad.applied_migrations \ --no-owner --no-privileges \ "$$PALIAD_PROD_DATABASE_URL" >> internal/db/testdata/prod-snapshot.sql.tmp @echo "==> stripping pg16 \\restrict / \\unrestrict commands for pg15 compat..." @sed -i.bak '/^\\restrict /d; /^\\unrestrict /d' internal/db/testdata/prod-snapshot.sql.tmp @rm -f internal/db/testdata/prod-snapshot.sql.tmp.bak @echo "==> stripping applied_migrations rows beyond branch's max on-disk version..." @MAX_VER=$$(ls internal/db/migrations/*.up.sql | xargs -I{} basename {} | sed 's/_.*//' | sort -n | tail -1); \ awk -v max=$$MAX_VER ' \ /^[0-9]+\t/ { split($$0, a, "\t"); if (a[1]+0 > max) next; } \ { print } \ ' internal/db/testdata/prod-snapshot.sql.tmp > internal/db/testdata/prod-snapshot.sql @rm internal/db/testdata/prod-snapshot.sql.tmp @wc -l internal/db/testdata/prod-snapshot.sql