cadrumo.domain.invoices._payload_normalisation module¶
Deserialisation-boundary coercion for raw invoice payloads.
Invoice is strict and frozen, so a payload arriving
from storage or a CLI boundary carries plain strings where the model declares
enums, and untrimmed text where it declares canonical values. These helpers are
the one place that gap is closed, before pydantic sees the mapping.
They are declared as rules rather than as one branch per field. Each field differed only in its key, its target type, its refusal wording, its casing and whether a blank means absence – so as straight-line code the differences that matter were the easiest thing to miss, and the shared shape was invisible.
The blank-handling axis is the load-bearing one. A field that is
absent_when_blank treats the empty string as the same absence a missing key
is: an empty string is not a Member State, an IVA category or an OSS regime, and
must not become one. A field without it is required, so a blank is a value its
enum rejects, which is the refusal the caller wants.