BEGIN; CREATE TABLE customer_login_session ( token_hash char(64) PRIMARY KEY, csrf_hash char(64) NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), expires_at timestamptz NOT NULL, consumed_at timestamptz ); CREATE INDEX customer_login_session_expiry ON customer_login_session(expires_at); CREATE TABLE customer_sms_challenge ( id uuid PRIMARY KEY, session_hash char(64) NOT NULL REFERENCES customer_login_session(token_hash) ON DELETE CASCADE, phone_digest char(64) NOT NULL, phone_ciphertext bytea NOT NULL, code_hash char(64) NOT NULL, request_id uuid NOT NULL, status varchar(16) NOT NULL DEFAULT 'SENDING' CHECK(status IN ('SENDING','SENT','FAILED','CONSUMED')), attempts integer NOT NULL DEFAULT 0 CHECK(attempts BETWEEN 0 AND 5), created_at timestamptz NOT NULL DEFAULT now(), expires_at timestamptz NOT NULL, consumed_at timestamptz, UNIQUE(session_hash,request_id) ); CREATE INDEX customer_sms_phone_recent ON customer_sms_challenge(phone_digest,created_at); COMMIT;