-- Add the confirm deeplink token and the confirmation purpose to email_confirmations. -- purpose tags what verifying the code/token does (email login, identity link, email -- change, or account deletion); link_token_hash holds the SHA-256 hex of the one-click -- deeplink token (only the hash is stored, mirroring the session-token model). -- Expand-contract: both columns are additive. purpose gets a NOT NULL DEFAULT so -- existing rows fill in; link_token_hash is nullable with a partial-unique index. A -- backend image rollback stays DB-safe — older code simply ignores the new columns. The -- table shape changes, so the generated go-jet model for this table is regenerated. -- +goose Up ALTER TABLE backend.email_confirmations ADD COLUMN purpose text NOT NULL DEFAULT 'link', ADD COLUMN link_token_hash text; ALTER TABLE backend.email_confirmations ADD CONSTRAINT email_confirmations_purpose_chk CHECK ((purpose = ANY (ARRAY['login'::text, 'link'::text, 'change'::text, 'delete'::text]))); CREATE UNIQUE INDEX email_confirmations_link_token_hash_key ON backend.email_confirmations (link_token_hash) WHERE link_token_hash IS NOT NULL; -- +goose Down DROP INDEX IF EXISTS backend.email_confirmations_link_token_hash_key; ALTER TABLE backend.email_confirmations DROP CONSTRAINT IF EXISTS email_confirmations_purpose_chk; ALTER TABLE backend.email_confirmations DROP COLUMN IF EXISTS link_token_hash, DROP COLUMN IF EXISTS purpose;