Source code for cadrumo.application.workflow.active_profile
"""Canonical active-profile selection and record-resolution contracts.Workflow state is an encrypted record and must not become a second importsurface for the process-wide active-profile selector. This module owns thetranslation from that core selector to a committed capsule and its authenticatedprofile record.Core types::class:`~cadrumo.domain.user_profile.values.UserProfileRecord`."""from__future__importannotationsfromcollections.abcimportCallablefromdataclassesimportdataclassfromtypingimportTYPE_CHECKINGfrom...core.bucket_pointerimportresolve_active_bucket_idfrom...core.configimportoverride_settingsfrom...core.errors.hierarchyimportNoActiveProfileErrorfrom...core.loggingimportget_loggerfrom...core.profile_sessionimportProfileRecordUnavailabilityfrom.profile_bucket_scanimportresolve_profile_bucketifTYPE_CHECKING:from...domain.calculations.registry.authority_artifactimportProfileDecodeContextfrom...domain.transactions.protocolsimportTransactionCatalogueRepositoryProtocolfrom...domain.user_profile.valuesimportUserProfileRecord_log=get_logger(__name__)
[docs]@dataclass(frozen=True,slots=True)classActiveProfileRecordResolution:"""One active-profile record read, together with why it produced nothing. Exactly one of :attr:`record` and :attr:`unavailability` is populated. The dataclass never crosses a serialization boundary, so it deliberately avoids eagerly importing the domain profile model at module import time. """record:UserProfileRecord|None=Noneunavailability:ProfileRecordUnavailability|None=Nonedef__post_init__(self)->None:"""Require exactly one resolved record or unavailability reason."""if(self.recordisNone)==(self.unavailabilityisNone):raiseValueError("an active-profile record resolution carries either a record or one reason, never both")
[docs]defactive_profile_selection()->tuple[str|None,str|None]:"""Return the raw active selector and its canonical live bucket UUID."""identifier=resolve_active_bucket_id()ifidentifierisNone:returnNone,Nonepointer=resolve_profile_bucket(identifier)returnidentifier,pointer.bucket_idifpointerisnotNoneelseNone
[docs]defrequire_active_profile_bucket_id()->str:"""Return the selected committed bucket or raise the canonical refusal."""_identifier,bucket_id=active_profile_selection()ifbucket_idisNone:raiseNoActiveProfileError(translated_message="application.workflow.errors.no_active_profile_bucket")returnbucket_id
[docs]defresolve_active_profile_record(*,profile_decode_context:ProfileDecodeContext)->ActiveProfileRecordResolution:"""Read the active profile record and name the reason when it is absent."""from...domain.user_profile.errorsimportProfileNotFoundErrorfrom..user_profile.profile_record_repositoryimport(ProfileRecordRepository,profile_record_session_if_authenticated,)identifier,bucket_id=active_profile_selection()ifbucket_idisNone:ifidentifierisnotNone:_log.debug("active profile record resolution found no live bucket for the selected profile")returnActiveProfileRecordResolution(unavailability=ProfileRecordUnavailability.NO_LIVE_CAPSULE)withoverride_settings(cadrumo_active_profile=bucket_id):session=profile_record_session_if_authenticated(bucket_id,profile_decode_context=profile_decode_context,)ifsessionisNone:_log.debug("active profile record resolution found no authenticated session for the committed capsule")returnActiveProfileRecordResolution(unavailability=ProfileRecordUnavailability.SESSION_REQUIRED)try:record=ProfileRecordRepository(session=session).load(bucket_id)exceptProfileNotFoundErrorasexc:_log.debug("active profile record resolution hit a mis-addressed session: %s",type(exc).__name__)returnActiveProfileRecordResolution(unavailability=ProfileRecordUnavailability.SESSION_IDENTITY_MISMATCH,)returnActiveProfileRecordResolution(record=record)
[docs]defactive_transaction_catalogue_repository[RepositoryT:TransactionCatalogueRepositoryProtocol](*,repository_factory:Callable[[str],RepositoryT],)->RepositoryT:"""Compose the active bucket's transaction catalogue through an outward factory."""from...domain.transactions.errorsimportLedgerNoActiveBucketErrortry:bucket_id=require_active_profile_bucket_id()exceptNoActiveProfileErrorasexc:raiseLedgerNoActiveBucketError(translated_message="application.workflow.errors.no_active_profile_bucket",context={"repository":"transaction_catalogue","operation":"resolve_active_bucket"},)fromexcreturnrepository_factory(bucket_id)