Ecto schema + record bridge for the RFC 8628 device-code store
(AttestoPhoenix.Store.EctoDeviceCodeStore).
Backs Attesto.DeviceCodeStore: a device code is a mutable row that moves
through pending → (approved | denied) → consumed. from_record/1
spreads the core's Attesto.DeviceCodeStore.entry() map across the row's
columns for the initial pending insert; to_entry/1 folds a loaded row back
into that contract shape. The mutating transitions are done as guarded atomic
UPDATEs in the store, not through this changeset.
Only the device code's Attesto.Secret.hash/1 is stored, never the plaintext;
user_code is stored normalized.
Summary
Functions
Build the insert changeset for a new pending device code from the core
store record. Fail-closed: a missing required field is rejected, not defaulted.
Fold a loaded row into the Attesto.DeviceCodeStore.entry() contract shape.
The non-consuming Attesto.DeviceCodeStore.pending_view() for the verification
page.
Types
@type t() :: %AttestoPhoenix.Schema.DeviceCode{ __meta__: term(), client_id: term(), device_code_hash: term(), dpop_jkt: term(), expires_at: term(), granted_claims: term(), granted_scope: term(), id: term(), inserted_at: term(), last_polled_at: term(), resource: term(), scope: term(), status: term(), subject: term(), user_code: term() }
Functions
@spec from_record( Attesto.DeviceCodeStore.entry(), keyword() ) :: Ecto.Changeset.t()
Build the insert changeset for a new pending device code from the core
store record. Fail-closed: a missing required field is rejected, not defaulted.
@spec to_entry(t()) :: Attesto.DeviceCodeStore.entry()
Fold a loaded row into the Attesto.DeviceCodeStore.entry() contract shape.
@spec to_pending_view(t()) :: Attesto.DeviceCodeStore.pending_view()
The non-consuming Attesto.DeviceCodeStore.pending_view() for the verification
page.