fix(db): make V12 migration H2-compatible (drop partial-index WHERE clauses)
V12__add_guest_order_columns.sql used PostgreSQL partial indexes: CREATE UNIQUE INDEX ... ON orders(guest_token) WHERE guest_token IS NOT NULL CREATE INDEX ... ON orders(guest_email) WHERE guest_email IS NOT NULL H2 (the in-memory DB used by tests/dev, per application.yml) does not support partial indexes -- the WHERE clause throws JdbcSQLSyntaxErrorException. Flyway therefore failed to run V12 at Spring context startup, so the ApplicationContext could not load, failing all 80 @SpringBootTest tests (:backend:test) and aborting CI before coverage verification ever ran. This was the actual root cause of the PR's red CI -- not a coverage shortfall. Verified locally (Temurin JDK 21): ./gradlew :backend:jacocoTestCoverageVerification now BUILD SUCCESSFUL; all 188 tests pass; bundle coverage 80.8% line / 64.9% branch (thresholds 70% / 60%). Semantics preserved: both H2 and PostgreSQL treat NULLs as distinct in a UNIQUE index, so user-owned orders (NULL guest_token) never collide while non-NULL guest tokens stay unique -- the same guarantee the partial index provided, but portable across both databases. Migration is not yet on master, so editing V12 in this PR is safe (no checksum mismatch against origin/master).
This commit is contained in:
parent
be069aa92c
commit
afe70125f1
1 changed files with 10 additions and 9 deletions
|
|
@ -1,24 +1,25 @@
|
||||||
-- Allows orders without a registered user (guest checkout).
|
-- Allows orders without a registered user (guest checkout).
|
||||||
-- Users can place and pay for letters without creating an account.
|
-- Users can place and pay for letters without creating an account.
|
||||||
--
|
--
|
||||||
-- user_id: previously NOT NULL — drop the constraint so guest orders
|
-- user_id: previously NOT NULL - drop the constraint so guest orders
|
||||||
-- can be created without a registered user. The FK stays in
|
-- can be created without a registered user. The FK stays in
|
||||||
-- place (NULL user_id is FK-legal).
|
-- place (NULL user_id is FK-legal).
|
||||||
-- guest_email: contact address for the guest. Used to send the magic
|
-- guest_email: contact address for the guest. Used to send the magic
|
||||||
-- link that lets them revisit their order status.
|
-- link that lets them revisit their order status.
|
||||||
-- guest_token: opaque UUID v4 — the only credential a guest has. Acts
|
-- guest_token: opaque UUID v4 - the only credential a guest has. Acts
|
||||||
-- as their session token for order lookup + payment confirm.
|
-- as their session token for order lookup + payment confirm.
|
||||||
|
|
||||||
ALTER TABLE orders ALTER COLUMN user_id DROP NOT NULL;
|
ALTER TABLE orders ALTER COLUMN user_id DROP NOT NULL;
|
||||||
ALTER TABLE orders ADD COLUMN guest_email VARCHAR(255);
|
ALTER TABLE orders ADD COLUMN guest_email VARCHAR(255);
|
||||||
ALTER TABLE orders ADD COLUMN guest_token UUID;
|
ALTER TABLE orders ADD COLUMN guest_token UUID;
|
||||||
|
|
||||||
-- Partial unique index: only enforce uniqueness on non-NULL tokens.
|
-- Unique index on guest_token. Both H2 (tests/dev) and PostgreSQL (prod)
|
||||||
-- Multiple NULLs allowed — existing user-owned orders have no token,
|
-- treat NULLs as distinct in a UNIQUE index, so user-owned orders (which
|
||||||
-- and that's fine.
|
-- have a NULL token) never collide, while non-NULL guest tokens are
|
||||||
|
-- enforced unique. A plain index is used instead of a partial
|
||||||
|
-- (WHERE guest_token IS NOT NULL) index because H2 does not support
|
||||||
|
-- partial indexes, and the plain form preserves the intended semantics.
|
||||||
CREATE UNIQUE INDEX idx_orders_guest_token
|
CREATE UNIQUE INDEX idx_orders_guest_token
|
||||||
ON orders(guest_token)
|
ON orders(guest_token);
|
||||||
WHERE guest_token IS NOT NULL;
|
|
||||||
CREATE INDEX idx_orders_guest_email
|
CREATE INDEX idx_orders_guest_email
|
||||||
ON orders(guest_email)
|
ON orders(guest_email);
|
||||||
WHERE guest_email IS NOT NULL;
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue