diff --git a/backend/src/main/resources/db/migration/V12__add_guest_order_columns.sql b/backend/src/main/resources/db/migration/V12__add_guest_order_columns.sql index f508fed..0b4412e 100644 --- a/backend/src/main/resources/db/migration/V12__add_guest_order_columns.sql +++ b/backend/src/main/resources/db/migration/V12__add_guest_order_columns.sql @@ -1,24 +1,25 @@ -- Allows orders without a registered user (guest checkout). -- 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 -- place (NULL user_id is FK-legal). -- guest_email: contact address for the guest. Used to send the magic -- 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. 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_token UUID; --- Partial unique index: only enforce uniqueness on non-NULL tokens. --- Multiple NULLs allowed — existing user-owned orders have no token, --- and that's fine. +-- Unique index on guest_token. Both H2 (tests/dev) and PostgreSQL (prod) +-- treat NULLs as distinct in a UNIQUE index, so user-owned orders (which +-- 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 - ON orders(guest_token) - WHERE guest_token IS NOT NULL; + ON orders(guest_token); CREATE INDEX idx_orders_guest_email - ON orders(guest_email) - WHERE guest_email IS NOT NULL; + ON orders(guest_email);