cadrumo.domain.calculations.registry.binding_value_contract module

The declared value contract a binding promises its consumers.

A binding’s value contract answers two questions that the authored declaration previously left implicit and a consumer had to re-derive: what the value means (BindingDataType) and which typed channel carries it (BindingValueChannel). The two axes are kept separate rather than collapsed to one token because they are not the same statement – money and integer are distinct legal quantities that a formula rounds and signs differently, while the channel is the transport a resolver and an export share. They are, however, not independently choosable: CHANNEL_FOR_BINDING_DATA_TYPE pins exactly one channel per data type, so a declaration that pairs them wrongly is a contradiction the schema refuses rather than a preference it honours.

Row-shaped values carry a third axis: the row-assembly grouping. It reuses RowSetGroupingKind, the same canonical cross-layer enum the detail-record source tokens map onto, so the grouping a binding declares and the grouping the assembly layer consumes cannot drift.

class BindingDataType(*values)[source]

Bases: StrEnum

The legal quantity a binding value represents.

MONEY

A monetary amount, signed and rounded by its owning casilla contract.

DECIMAL

A non-monetary decimal quantity.

Distinct from money: it carries no currency and is not rounded or signed by a monetary casilla contract, and distinct from integer: it is genuinely fractional. A prorrata-weighted count is the canonical shape — truncating it to integer would discard the prorrata, and calling it money would label a quantity as currency.

INTEGER

A whole count with no monetary rounding or currency.

BOOLEAN

A declared yes/no fact, distinct from a zero amount.

TEXT

Free or catalogued text carried verbatim to an export.

DATE

A calendar date, never a period token.

ENUM

A member of a closed substrate enum named by typed_enum.

class BindingValueChannel(*values)[source]

Bases: StrEnum

The typed transport a resolver produces and a consumer narrows on.

DECIMAL
INTEGER
BOOLEAN
TEXT
DATE
ENUM
ROW_SET
CHANNEL_FOR_BINDING_DATA_TYPE: Final[Mapping[BindingDataType, BindingValueChannel]]

The one permitted channel per data type.

money is the only pairing whose two tokens differ in spelling: a monetary quantity travels the decimal channel, because the channel names the carrier type and not the legal quantity. Every other data type names its channel identically, which makes the pairing look redundant – it is not, because the two axes are declared independently and the map is what refuses a contradiction.

money and decimal are the one pair of data types that share a channel: both travel as a Decimal, and what separates them is the legal quantity, not the carrier. The map stays a function from data type to channel, so the pairing check remains exact in the direction it is asked.

class BindingValueContract(**data)[source]

Bases: RegistryModel

The typed value shape one binding declaration promises.

typed_enum names the closed substrate enum an enum-channel value bridges; row_grouping names the row-assembly axis a row_set value is grouped by. The row-set channel carries the same scalar data_type vocabulary as a scalar value; cardinality is stated by channel alone.

Parameters:

data (Any)

data_type: Annotated[BindingDataType, BeforeValidator(coerce_enum_member(BindingDataType))]
channel: Annotated[BindingValueChannel, BeforeValidator(coerce_enum_member(BindingValueChannel))]
typed_enum: Annotated[BindingTypedEnumKind | None, BeforeValidator(coerce_enum_member(BindingTypedEnumKind))]
row_grouping: Annotated[RowSetGroupingKind | None, BeforeValidator(coerce_enum_member(RowSetGroupingKind))]