Summary
Spec 3.0.x adds billing_entity (B2B invoicing entity, bank details write-only — MUST NOT serialize on response) and reporting_bucket. Need projection helpers so adopters don't accidentally leak bank details on read.
Design
Bank-details guard
Two options — pick one during implementation:
- Pydantic
model_validator on the Account type that strips billing_entity.bank_details on response serialization
- Separate
AccountResponse projection type with bank details omitted from the model entirely
Option 2 is more explicit and harder to misuse — leaning that way pending discussion.
Migration
Alembic migration template for adopters with existing Account tables to add the new columns:
billing_entity (JSON column or normalized table)
reporting_bucket (string column)
Why this matters
Prevents the bank-details-on-read leak that's easy to miss during adopter implementation. The spec is clear that bank details are write-only, but Pydantic's default serialization round-trips everything.
Cross-references
🤖 Generated with Claude Code
Summary
Spec 3.0.x adds
billing_entity(B2B invoicing entity, bank details write-only — MUST NOT serialize on response) andreporting_bucket. Need projection helpers so adopters don't accidentally leak bank details on read.Design
Bank-details guard
Two options — pick one during implementation:
model_validatoron theAccounttype that stripsbilling_entity.bank_detailson response serializationAccountResponseprojection type with bank details omitted from the model entirelyOption 2 is more explicit and harder to misuse — leaning that way pending discussion.
Migration
Alembic migration template for adopters with existing Account tables to add the new columns:
billing_entity(JSON column or normalized table)reporting_bucket(string column)Why this matters
Prevents the bank-details-on-read leak that's easy to miss during adopter implementation. The spec is clear that bank details are write-only, but Pydantic's default serialization round-trips everything.
Cross-references
🤖 Generated with Claude Code