aeat.application.user_profile._bundle module¶
Portable profile-bundle serialisation for bucket export/import.
This module composes
UserProfilePortableExport payloads at
the application boundary. A v3 bundle contains the profile record plus
the four bucket-local history categories that must move with it: work
units, ledger transactions, calculation revisions, and filing records.
The v3 shape additionally carries the generic secure-object custody
schema and coverage manifest, default-empty until the transport-aware
phases populate them.
The ledger category is loaded as a
TransactionCatalogue through
TransactionCatalogueRepository.
Bundles carry typed domain-model payloads, not encrypted blobs, key material, or raw secure-storage rows. Export reads domain records from their owning repositories; import saves those records through the target bucket’s repository save paths so the target bucket re-encrypts them under its own data-encryption key.
The bundle version gate is a ceiling with a durability floor: a version
above BUNDLE_SCHEMA_VERSION was written by a newer application
and is refused; a version at or above BUNDLE_DURABILITY_FLOOR is
readable exactly when the per-hop chain in
BUNDLE_PAYLOAD_UPGRADERS reaches the current version. The floor
starts at the current version (no released bundles exist below it) and
moves forward only through a superseding accepted ADR
(2026-07-08-released-data-durability-adr). Callers must provision and
collision-check the target bucket and hold the appropriate bucket
session before deserialising; this module performs schema-version
validation and typed repository writes.
- BUNDLE_DURABILITY_FLOOR: Final[int]¶
Oldest bundle version the import path keeps readable. Starts at the current version (no released bundles exist below it); moves forward only through a superseding accepted ADR.
- BUNDLE_PAYLOAD_UPGRADERS: Mapping[int, Callable[[dict[str, object]], dict[str, object]]]¶
each transforms the parsed JSON mapping of a version-N bundle into the version-N+1 shape (including restamping
bundle_schema_version) BEFORE strict pydantic validation — the raw mapping is the one sanctioned pre-validation boundary. Empty while the floor equals the current version; a version bump MUST land its hop here in the same change or the lineage gate fails.- Type:
One-hop raw-payload upgraders keyed by
from_version
- SUPPORTED_BUNDLE_SCHEMA_VERSIONS: frozenset[int]¶
the complete floor-to-current range.
- Type:
Versions the import path accepts
- validate_bundle_payload(raw_json, *, expected_written_version=None)[source]¶
Parse, chain-upgrade, and strictly validate a serialized bundle payload.
Reads the payload’s own
bundle_schema_version, refuses a future version (aboveBUNDLE_SCHEMA_VERSION) or one belowBUNDLE_DURABILITY_FLOOR, chain-upgrades an older supported payload hop by hop throughBUNDLE_PAYLOAD_UPGRADERS, and validates the result against the current strictUserProfilePortableExportmodel.- Parameters:
raw_json (
bytes|str) – The serialized bundle payload (decrypted transport bytes or the plaintext export text).expected_written_version (
int|None) – When set, the version a transport envelope declared for this payload; a payload whose own stamped version differs is refused before any upgrade runs.
- Raises:
UnsupportedBundleSchemaVersionError – When the payload does not carry an integer
bundle_schema_version, the version is outside the floor-to-current range, an upgrade hop is unregistered, or the stamped version contradictsexpected_written_version.- Return type:
- serialize_profile_bundle(*, bucket_id, custody_profile=StorageCustodyProfile.STRUCTURED)[source]¶
Build a v3
UserProfilePortableExport.Reads the profile record and all four financial-history categories from
bucket_id’s encrypted repositories and assembles them into one portable payload. The caller is responsible for ensuring a live bucket session is active forbucket_id.- Parameters:
bucket_id (
str) – Profile bucket whose domain repositories are exported.custody_profile (
StorageCustodyProfile|str) – Secure-object custody scope to apply, as aStorageCustodyProfileor one of its string values.
- Return type:
The bundle carries only decrypted pydantic domain-model payloads (no encrypted envelopes or key material). The recipient re-encrypts each object under its own bucket data-encryption key through the standard repository save paths on import.
- deserialize_profile_bundle(bundle, *, target_bucket_id)[source]¶
Import financial-history objects from
bundleintotarget_bucket_id.Validates
bundle.bundle_schema_versionagainstSUPPORTED_BUNDLE_SCHEMA_VERSIONSbefore any writes; only the current v3 shape is accepted.Saves work units, ledger transactions, calculation revisions, and filing records into the target bucket via the standard repository save paths. Each domain object is re-encrypted under the target bucket’s own data-encryption key. No
dict[str, Any]intermediate is used; pydantic models flow directly into typed catalogue saves.The caller is responsible for:
Provisioning the target bucket before calling this function.
Ensuring a live bucket session is active for
target_bucket_id.Running the two-tier collision guard before provisioning.
- Parameters:
bundle (
UserProfilePortableExport) – The validated export bundle.target_bucket_id (
str) – The bucket id under which to write the objects.
- Raises:
UnsupportedBundleSchemaVersionError – When
bundle.bundle_schema_versionis not inSUPPORTED_BUNDLE_SCHEMA_VERSIONS.- Return type: