Ecto/Postgres implementation of Attesto.CIBAStore.
Every state transition is a single guarded atomic statement, so the CIBA authentication-request state machine is race-free across nodes:
approve/3/deny/2—UPDATE ... WHERE status = 'pending' AND expires_at > $now RETURNING, so the user's decision is taken exactly once and never lands on an expired request.poll/2— one conditionalUPDATE ... SET last_polled_at = $now WHERE auth_req_id_hash = $1 AND (last_polled_at IS NULL OR last_polled_at <= $now - interval) RETURNING, enforcing the CIBA Core §7.3 minimum token-request interval (the ROW'sintervalcolumn - the value the client was told at issue) and reading the row's state in the same statement. A zero-row result is disambiguated asslow_downvs unknown by one follow-up existence check (both are non-mint outcomes, so it is not a security race).consume/2—UPDATE ... SET status = 'consumed' WHERE status = 'approved' AND expires_at > $now RETURNING, so an approved request mints exactly one token family.
Backs the schema AttestoPhoenix.Schema.CIBARequest. Only the auth_req_id's
hash is stored.