cadrumo.domain.user_profile.schema module¶
Strict Pydantic records for the centralized user-profile schema.
Each schema section declares a SensitivityClass that governs
the encryption tier applied when the section’s data is persisted to the
secure DB backend.
- class ProfileFieldType(*values)[source]¶
Bases:
StrEnumClosed catalogue of field types allowed by the profile schema TOML.
- STRING¶
- BOOLEAN¶
- INTEGER¶
- DECIMAL¶
- MONEY¶
- DATE¶
- EMAIL¶
- ENUM¶
- ARRAY¶
- OBJECT¶
- class ProfileSnapshotPolicy(*values)[source]¶
Bases:
StrEnumAccepted profile snapshot stale-check policies.
- IMMUTABLE_SECURE_SNAPSHOT_HASH¶
- class ProfileRemovePolicy(*values)[source]¶
Bases:
StrEnumAccepted profile removal policies.
- LIVE_PROFILE_TOMBSTONE_RETAIN_SNAPSHOTS¶
- class ProfileFieldDefinition(**data)[source]¶
Bases:
BaseModelOne field declared inside a user-profile schema section.
- Parameters:
data (Any)
- key: _FieldKey¶
- type: ProfileFieldType¶
- required: bool¶
- nullable: bool¶
- sensitivity: SensitivityClass¶
- effective_dated: bool¶
- description: _Description¶
- enum_values: tuple[str, ...]¶
- model_selectors: tuple[_Selector, ...]¶
- required_for_modelos: tuple[Modelo, ...]¶
Modelos that require this field even though it is not globally required.
requiredis a property of the field across the whole profile: it drives completeness, overview and presentation, so setting it to satisfy one modelo demands the fact from every taxpayer, including those with no such obligation. This axis carries the modelo-scoped requirement instead, and ONLY the filing-preflight walk consults it.
- schedule_predicates: tuple[_Selector, ...]¶
- legal_refs: tuple[_Description, ...]¶
- minimum: Decimal | None¶
- maximum: Decimal | None¶
- class ProfileSectionDefinition(**data)[source]¶
Bases:
BaseModelA top-level section in the user-profile schema.
- Parameters:
data (Any)
- key: _SectionKey¶
- title: _Description¶
- sensitivity: SensitivityClass¶
- effective_dated: bool¶
- repeatable: bool¶
- fields: tuple[ProfileFieldDefinition, ...]¶
- class ProfileDerivedSelectorDefinition(**data)[source]¶
Bases:
BaseModelA namespace of profile paths the calculation engine owns and computes.
A derived path is NOT taxpayer data. Its value is computed at calculate time from the source facts named in
derived_from, so the schema declares the namespace as a pattern rather than one field per filing year. The pattern exists so registry binding selectors targeting these paths still resolve once the per-year field declarations are gone.This is a DECLARATION of engine ownership, never a resolution route for values: nothing here supplies a value to the binding resolver.
- Parameters:
data (Any)
- pattern: _DerivedSelectorPattern¶
- derived_from: tuple[_FieldPath, ...]¶
- entry_surface: _Description¶
- description: _Description¶
- legal_refs: tuple[_Description, ...]¶
- derived_selector_for_path(path, derived_selectors)[source]¶
Return the declared namespace owning path, or
Noneif it is not derived.The single written-once judgment on whether a profile path is engine-derived. Every consumer – the registry contract validator and the write-door refusal – asks through here, so the two can never disagree about what “derived” means.
Deliberately NOT routed through
profile_value_refusal(), which is the authority on whether a VALUE may be stored at a declared field. That judgment is value-scoped against aProfileFieldDefinitionand expressly declines to judge absence; this one is path-scoped, refuses every value including a clear, and must keep answering once the per-year field declarations are gone and there is no declaration left to judge against. The two live in one module because they are both schema-level judgments, not because they are the same judgment.The definition is returned rather than a bare bool so a caller can name the surface that edits the real source facts without re-scanning the namespace.
- Return type:
- Parameters:
path (str)
derived_selectors (Iterable[ProfileDerivedSelectorDefinition])
- class ProfileSchemaDefinition(**data)[source]¶
Bases:
BaseModelThe committed centralized user-profile schema.
- Parameters:
id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=^[a-z][a-z0-9_.-]*$, ascii_only=None)])
version (int)
title (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=512, pattern=None, ascii_only=None)])
snapshot_policy (ProfileSnapshotPolicy)
remove_policy (ProfileRemovePolicy)
sections (tuple[ProfileSectionDefinition, ...])
derived_selectors (tuple[ProfileDerivedSelectorDefinition, ...])
- id: _SchemaId¶
- version: int¶
- title: _Description¶
- snapshot_policy: ProfileSnapshotPolicy¶
- remove_policy: ProfileRemovePolicy¶
- sections: tuple[ProfileSectionDefinition, ...]¶
- derived_selectors: tuple[ProfileDerivedSelectorDefinition, ...]¶
- section(key)[source]¶
Return a
ProfileSectionDefinitionby canonical section key.- Return type:
- Parameters:
key (str)
- field(path)[source]¶
Return a field by canonical dotted path.
- Return type:
- Returns:
The
ProfileFieldDefinitionfor the given path.- Parameters:
path (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=3, max_length=160, pattern=^[a-z][a-z0-9_]*(?:\.[a-z0-9_]+)+$, ascii_only=None)])
- path_for_model_selector(selector)[source]¶
Return the canonical dotted path of the field declaring
selector.The inverse of the
model_selectorsdeclaration. Surfaces that hold a selector token rather than a path - a deadline-engine gating key, a registry binding’s consumed profile key - need the path before they can resolve the field’s operator label and legal grounding, and every other schema lookup here runs path-first.Ambiguity is refused rather than guessed: the schema does not constrain a token to one declaring field, so a token declared by two fields has no single correct answer and returning either would mislabel one of them. An unknown token is likewise not an error - the callers mix selector tokens with identifiers from other namespaces and must be able to ask without knowing which they hold.
- NUMERIC_PROFILE_FIELD_TYPES: frozenset[ProfileFieldType]¶
The field types whose values are numbers, and whose bounds therefore bind.
Mirrors the set
ProfileFieldDefinition._validate_enum_values()already uses to decide whereminimum/maximummay be declared, so the types that may CARRY a bound and the types that are CHECKED against one cannot drift apart.
- numeric_value_refusal(field, value)[source]¶
Return why
valuefailsfield’s numeric declaration, orNone.The single authority for “is this a legal value for this numeric field”. It exists because the declaration was inert:
minimumandmaximumwere validated for their own coherence at schema build and then never compared to anything, so a participation percentage declared0..100accepted999on write and carried it into an attribution calculation unchallenged. Both the write door and the readers that consume these facts ask this one function, rather than each forming its own opinion.Numbers are
Decimal(orint), neverfloat. These are financial quantities – a participation percentage and an assigned base that divide a taxable amount between members – so binary floating point is the wrong carrier: its rounding is invisible at the point of entry and shows up as a cent that does not reconcile in a filing.boolis rejected despite being anintsubclass, becauseTrueis an answer to a different question and would otherwise silently satisfy a numeric field as1.Absence is not this rule’s business. A
Nonevalue is a cleared or unanswered field, which the required-field check judges; refusing it here would report one missing field as two unrelated faults.Non-finite values need no check: the fact carrier’s own union rejects a
NaNor infiniteDecimalbefore it can be constructed, so an unorderable value cannot reach a bound comparison.- Parameters:
field (
ProfileFieldDefinition) – The declaration the value must satisfy.value (
object) – The value carried by the fact, after the fact carrier has restored its type.
- Return type:
- Returns:
An instructive message naming the field and the range it accepts, or
Nonewhen the value is admissible or the field is not numeric.
- boolean_value_refusal(field, value)[source]¶
Return why
valuefailsfield’s boolean declaration, orNone.The single authority for “is this a legal value for this boolean field”, the counterpart to
numeric_value_refusal(). It exists because the declaration was inert: a field declaredbooleanacceptedbanana,placeholderand''on write and stored them unchallenged, while every reader then had to decide for itself what an unreadable value meant. Readers that resolve a stored boolean default an unreadable one toFalse– safe only if a value this door admitted can always be read, which is what this function makes true.Readability, not spelling, is the test. A taxpayer answering
síis saying yes, and refusing that while acceptingtruewould be a vocabulary rule dressed up as a type rule. The judgement therefore comes fromcadrumo.core.parsing.parse_bool, the one boolean vocabulary the rest of the codebase already reads answers with, rather than a set spelled out here that could drift from it.A real
boolis admissible by construction: it needs no parsing and carries no ambiguity.Absence is not this rule’s business. A
Nonevalue is a cleared or unanswered field, which the required-field check judges. An empty string is NOT absence – it is an answer that says nothing – and is refused, as the enum and date declarations already refuse it.- Parameters:
field (
ProfileFieldDefinition) – The declaration the value must satisfy.value (
object) – The value carried by the fact, after the fact carrier has restored its type.
- Return type:
- Returns:
An instructive message naming the field and what it accepts, or
Nonewhen the value is admissible or the field is not boolean.
- class ProfileValueRefusalKind(*values)[source]¶
Bases:
StrEnumWhich declaration a refused value failed.
A closed set, because it is the join between the one rule that judges a value and the two surfaces that have to say something about the verdict: the validation service turns a kind into its issue code, and an operator surface turns the same kind into the sentence it shows and the editor it offers. Both read the kind rather than matching on the message, so the prose stays free to change without either one silently stopping working.
- ENUM¶
- DATE¶
- NUMERIC¶
- BOOLEAN¶
- EMAIL¶
- class ProfileValueRefusal(**data)[source]¶
Bases:
BaseModelWhy one value fails its field’s declaration.
Carries the kind as well as the message so a caller can classify the refusal without parsing the sentence: the codes an issue report uses and the copy an operator reads are both decided from
kind.- Parameters:
data (Any)
- kind: ProfileValueRefusalKind¶
- message: str¶
- date_value_refusal(field, value)[source]¶
Return why
valuefailsfield’s date declaration, orNone.The sibling of
boolean_value_refusal()andnumeric_value_refusal(), and here for the same reason: the rule lived only inside the validation service, so a surface wanting to refuse a bad date at the box the operator typed it into had nowhere to ask and would have had to restate the layout itself.A real
datetime.dateis admissible by construction. A string is accepted only when it matches the zero-padded extended layout AND parses as a calendar day, which together reject a non-ISO layout (15/03/1978), the compact basic form (19780315), an impossible month or day (1978-13-45), a non-calendar day (1978-02-30), and plain garbage – without any hand-rolled calendar maths.- Return type:
- Parameters:
field (ProfileFieldDefinition)
value (object)
- email_value_refusal(field, value)[source]¶
Return why
valuefailsfield’s email declaration, orNone.The declaration was inert before this: a field declared
emailacceptedbananaand stored it, so the one type in the schema that names its own content format was the one type nothing checked.Only a string can be an address. A non-string reaching an
emailfield is a fact carrier that promoted the value to something else — a bare numeral, a date-shaped token — and is refused as the same fault rather than allowed through for want of a branch.- Return type:
- Parameters:
field (ProfileFieldDefinition)
value (object)
- enum_value_refusal(field, value)[source]¶
Return why
valueis outsidefield’s declared token set, orNone.Comparison is exact rather than case-folded. The declared sets are case-significant and inconsistent between fields by design – some carry AEAT’s own uppercase tokens, others the profile’s lowercase vocabulary – so folding would silently admit a spelling the declaring authority does not use.
- Return type:
- Parameters:
field (ProfileFieldDefinition)
value (object)
- profile_value_refusal(field, value)[source]¶
Return why
valuefailsfield’s declaration, orNone.THE authority on whether a value may be stored at a field, gathering the four per-type rules behind one call so that every surface asks the same question in the same words. The write door asks it to build its issue report; an operator surface asks it to refuse a value at the box it was typed into, before a round trip to storage. Two surfaces judging a value apart is how one comes to accept what the other rejects, and the operator meets that as a dialog that closes on a value the record then refuses.
Absence is not this rule’s business. A
Nonevalue is a cleared or unanswered field, which the required-field check judges.- Parameters:
field (
ProfileFieldDefinition) – The declaration the value must satisfy.value (
object) – The value carried by the fact, after the fact carrier has restored its type. Passing a raw string a fact would have promoted ("true","1978-03-15") asks a different question from the one the write door asks.
- Return type:
- Returns:
A
ProfileValueRefusalnaming what failed and what the field accepts, orNonewhen the value is admissible.