pub async fn transition(
conn: &mut PgConnection,
id: Uuid,
transition: &Transition,
) -> ModelResult<CreditRegistration>Expand description
Moves a ledger row to a new state and appends the matching audit event, atomically.
The only writer of state, and the one place (from → to) legality is decided: an edge outside
the transition’s TransitionPolicy is refused as InvalidRequest rather than written.
Deliberately not PreconditionFailed, which the phases read as “another writer got here first”
and skip over.
Owns the lifecycle stamps, so callers must not touch them: state_entered_at, terminal_at,
first_failed_at, registered_at, submitted_at, enrolment_checked_at,
enrolment_banner_dismissed_at, which entering no_usable_enrolment clears, and
next_attempt_at, which takes the target state’s default cadence unless the caller names a time.