aeat.application.wizard._persistence module¶
Persistence adapter for wizard answers.
Serialises a typed answers model back to canonical-token strings, then
persists profile facts through canonical user-profile orchestration.
The reverse projection (project_answers) builds the typed answers
model from a raw canonical-token dict.
persist_answers distinguishes the two wizard verbs. create
registers a fresh profile from the full answer set. edit is a true
patch: only the questions the operator explicitly supplied on the
command line are written, so editing one field never reverts the rest
of a populated profile to its descriptor defaults.
- WizardPersistMode¶
Which wizard verb is persisting —
createregisters a new profile,editupserts facts on an existing one. The verb is the authority for the create-vs-edit branch; it is never re-derived at runtime.alias of
Literal[‘create’, ‘edit’]
- serialise_answers(flow, answers, *, only_question_ids=None)[source]¶
Project a typed answers model into the canonical-token dict.
Only profile-bound questions contribute a key. When
only_question_idsis supplied, the projection is restricted to those question ids — the patch behaviour theeditverb relies on so an unsupplied field is never written back at its default.- Return type:
- Parameters:
flow (WizardFlow)
answers (BaseModel)
only_question_ids (Collection[str] | None)
- persist_answers(flow, answers, *, state, profile_name, profile_id, mode, supplied_question_ids=None, routing_profile_id=None)[source]¶
Persist
answersinto the profile bucket and return updated state.profile_idis the immutable UUID profile identity;profile_nameis the operator-chosen display label.modeis the create-vs-edit discriminator and is the wizard verb itself, not a runtime-detected fact."create"routes toregister_active_profile(), which delegates the whole cross-store create — bucket directory, manifest, encrypted record, and the active-profile pointer — toProfileRepositoryas one unit of work and refuses a label already carried by a live profile."edit"routes toset_active_fields(), which upserts facts on the active profile.supplied_question_idsnames the questions the operator explicitly supplied on the command line. On the"edit"path it scopes the write to exactly those questions:editis a patch, so a field the operator did not name is left untouched. It must be supplied for"edit"; it is ignored for"create", which always registers the full set.Returns the updated
WorkflowStateafter persisting the answers.- Return type:
- Parameters:
flow (WizardFlow)
answers (BaseModel)
state (WorkflowState)
profile_name (str)
profile_id (str)
mode (Literal['create', 'edit'])
supplied_question_ids (Collection[str] | None)
routing_profile_id (str | None)
- profile_values_from_patch(flow, supplied)[source]¶
Project a non-interactive edit patch to schema-path keyed values.
- persist_patch(flow, supplied, *, state)[source]¶
Patch the active profile with only the explicitly supplied flags and return the updated
WorkflowState.suppliedis the canonical-token dict keyed by question id, carrying exactly the flags the operator named on a non-interactiveedit(--quiet/--accept-defaults). This is the true patch path: it never constructs the fullSetupAnswersmodel — which would demand every required field — and never seeds a descriptor default for an unsupplied question. Each supplied value is re-validated through its widget validator, mapped to itsprofile_key, and upserted viaset_active_fields(). A question with noprofile_keyis not a profile fact and is skipped.- Return type:
- Parameters:
flow (WizardFlow)
state (WorkflowState)
- project_answers(flow, values)[source]¶
Reverse projection: build the typed answers model from canonical tokens.
Values absent from
valuesfall back to the descriptor’s default or the answers model’s own field default; the answers model then runs its strict validation.- Return type:
BaseModel- Parameters:
flow (WizardFlow)