Repository navigation
chore(deps)!: es-entity 0.20.0, job 0.18.5, obix 0.14.4; bon replaces derive_builder - #912
Merged
Merged
Conversation
es-entity 0.20 drops derive_builder and generates {Entity}Hydrator, so
the eight entities (Account, AccountSet, Entry, Journal, Transaction,
TxTemplate, VelocityControl, VelocityLimit) hydrate through
X::hydrator() / build(events). obix 0.14.4's MailboxConfig build() is
infallible. job and obix move with es-entity because they share its
types.
derive_builder is replaced by bon everywhere:
- New* and *Update types without validation derive bon::Builder;
build() returns the value. A missing required field is now a
compile error, so the runtime "fails when mandatory fields are
missing" unit tests are gone (agreed with Justin).
- AccountUpdate, AccountSetUpdate and JournalUpdate are now the bon
structs themselves; the *UpdateValues layer and the &mut Default
builder pattern are gone (Justin chose bon over a hand-written
&mut builder). The (values, fields) From impls fill fields
directly.
- metadata setters stay fallible via bon `with` closures and return
Result<Builder, serde_json::Error> as before.
- Validating builders become #[bon] fallible constructors with the
same checks: CEL-expression builders (NewTxTemplateEntry,
NewTxTemplateTransaction, NewVelocityControl, NewVelocityLimit,
NewPartitionKey, NewLimit, NewBalanceLimit) return
CelParseRejection; NewParamDefinition returns the new
InvalidParamDefinition; CalaLedgerConfig returns the new
InvalidCalaLedgerConfig. Messages no longer go through to_string().
- NewTransaction's correlation_id defaults to id.to_string() via a
bon default instead of the custom id setter.
New unit tests pin that invalid CEL, a mistyped param default and a
config with zero or two connection sources are still rejected.
cala-ledger-core-types never used derive_builder and drops it.
fuzz/Cargo.lock was stale on main and moves forward with the bump.
BREAKING CHANGE: New*/*Update builders are bon builders. build() is
infallible except for the validating builders listed above, whose
XBuilderError types are replaced. AccountUpdateValues,
AccountSetUpdateValues and JournalUpdateValues are removed and
*Update::default() + &mut setters no longer exist.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bodymindarts
marked this pull request as ready for review
October 22, 2026 14:25
Contributor
📊 Performance ReportCommit: c6a36f2 Cala Performance Benchmark Results (non-representative)Criterion Benchmark Results (single-threaded)
Load Testing Results (parallel-execution)
Note: Performance results may vary based on system resources and database state. Last updated by commit c6a36f2 |
Cargo.lock: - rustls-webpki 0.103.15 -> 0.103.16 (RUSTSEC-2026-0382) - webpki-roots 1.0.6 -> 1.0.10 (RUSTSEC-2026-0381) - yanked: chacha20 0.10.0 -> 0.10.2, spin 0.9.8 -> 0.9.9, js-sys/web-sys 0.3.86 -> 0.3.106 and wasm-bindgen 0.2.109 -> 0.2.129 (moved together; web-sys pins js-sys exactly) fuzz/Cargo.lock: - rustls 0.23.45 -> 0.23.46 (RUSTSEC-2026-0346..0349) - rustls-webpki 0.103.15 -> 0.103.16, webpki-roots 1.0.9 -> 1.0.10 - yanked: chacha20 0.10.1 -> 0.10.2 Both crates arrive transitively via sqlx; no manifest changes. The remaining warnings (im, sized-chunks, bitmaps unmaintained/unsound) come from im 15.1.0, the latest release, required directly by es-entity and obix, so no lockfile bump clears them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
es-entity0.19.2 → 0.20.0,job0.18.3 → 0.18.5,obix0.14.3 → 0.14.4 together (they share es-entity types).errlanesfollows es-entity. Both lockfiles regenerated by cargo;fuzz/Cargo.lockwas stale on main (es-entity 0.17, cala 0.32.2-dev) and moves forward too.Account,AccountSet,Entry,Journal,Transaction,TxTemplate,VelocityControl,VelocityLimit) hydrate via the generatedX::hydrator()/build(events).derive_builderis replaced bybon = "3"everywhere and removed from every manifest.cargo tree -i derive_buildermatches nothing forcala-ledger,cala-ledger-core-types,cala-cel-interpreter,cala-perf,cala-ledger-example-rustand the fuzz crate.cala-ledger-core-typesnever used derive_builder and simply drops it.Carrier/Absorb/AbsorbFailBy/Repr/kind/LaneRef,narrow*,fatal(..)lift cases,UninitializedFieldError): onlyUninitializedFieldError-style hydration was used in cala. job 0.18.5 keptJobSvcConfig's shape; obix 0.14.4'sMailboxConfig::build()is infallible (outbox/publisher.rsdrops.expect).API changes (breaking)
Infallible
build()(bon typestate — a missing required field is now a compile error):NewAccount,NewAccountSet,NewJournal,NewTxTemplate,NewVelocityEnforcement,NewEntry,NewTransaction,AccountUpdate,AccountSetUpdate,JournalUpdate.Fallible
build()with a new error type (validation unchanged, now a#[bon]fallible constructor; messages no longer go throughto_string()):NewTxTemplateEntry,NewTxTemplateTransaction,NewVelocityControl,NewVelocityLimit,NewPartitionKey,NewLimit,NewBalanceLimitXBuilderError(UninitializedField/ValidationError(String))cel_interpreter::CelParseRejectionNewParamDefinitionNewParamDefinitionBuilderErrorInvalidParamDefinition(Parse,Evaluationdelegate to the CEL rejections;DefaultTypeMismatch { specified, source }, codeCALA_PARAM_DEFAULT_TYPE_MISMATCH)CalaLedgerConfigCalaLedgerConfigBuilderErrorInvalidCalaLedgerConfig(NoConnection,BothConnections; codesCALA_LEDGER_CONFIG_*)Update types:
AccountUpdate,AccountSetUpdate,JournalUpdateare now plain structs with#[derive(bon::Builder, Default)];AccountUpdateValues,AccountSetUpdateValues,JournalUpdateValuesare removed.X::default()+&mutsetters +.build()?becomesX::builder().<setters>.build().update()still takesimpl Into<XUpdate>, andX::default()is still an empty update.Setters: names,
intoconversion andOptionsetters takingTare kept; every optional member also getsmaybe_x(Option<_>). Setters consume the builder (owned) instead of&mut self, so statement-styleb.x(..);on alet mutbuilder no longer compiles.metadata(..)stays fallible (Result<Builder, serde_json::Error>) via a bonwithclosure.NewBalanceLimitBuilder::always_active()consumes the builder and is only callable whilestartis unset.NewTransaction.correlation_iddefaults toid.to_string()via a bon default instead of the customidsetter.XBuildertype names still exist but are now generic over bon's typestate and have noDefault;X::builder()is the only entry point.Tests: the runtime
fails_when_mandatory_fields_are_missing/fails_when_missing_required_fieldsunit tests (NewAccount,NewJournal,NewTransaction,NewTxTemplate,NewEntry) are removed because the case is now a compile error (agreed with Justin). New unit tests pin that invalid CEL, a mistyped param default, and a config with zero or two connection sources are still rejected. All other test edits are mechanical call-shape migrations.Downstream call-site changes
From the lana-bank checkout (
48b17701e5, worktrees andtarget/excluded). Counts areX::builder()call sites / files.Drop
.expect(..)/.unwrap()/?afterbuild()(now infallible):NewAccount— 18 sites / 12 files (e.g.core/accounting/src/chart_of_accounts/{chart_node/entity.rs,ledger/closing_balances.rs},core/{alt-credit,exchange,fx,holding,payments}/src/**/ledger/mod.rs, tests incore/accounting,core/credit/collection,core/fx,core/exchange)NewAccountSet— 18 / 12 (core/accounting/src/{balance_sheet,profit_and_loss,trial_balance,chart_of_accounts}/…,core/alt-credit/src/credit_facility_product/ledger/mod.rs,core/holding/src/ledger.rs, tests incore/{accounting,alt-credit,credit,deposit,exchange})NewJournal— 9 / 9 (core/accounting/src/journal/service.rs,core/payments/src/ledger/mod.rs, test helpers in 7 crates)NewTxTemplate— 26 / 26 (every template file undercore/{accounting,alt-credit,exchange,fx,holding,payments}/src/**/templates*plus 5 test files)AccountSetUpdate— 1 / 1:core/accounting/src/chart_of_accounts/ledger/mod.rs:113,let mut update_values = AccountSetUpdate::default(); update_values.metadata(..).expect(..)→AccountSetUpdate::builder().metadata(..).expect(..).build()Error type changes (fallible
build()stays; only matters where the error is named or converted):NewTxTemplateEntry66/26,NewTxTemplateTransaction27/27,NewParamDefinition123/17,NewVelocityControl6/6,NewVelocityLimit9/6,NewLimit9/6,NewBalanceLimit9/6,CalaLedgerConfig23/18. Non-test lana code uses.expect(..)on all of these; the?sites are tests returninganyhow::Result, which accept the new errors unchanged. No lana file names any calaXBuilderError,XBuilderor*UpdateValuestype, and noFrom/#[from]impl wraps them, so no error-enum changes are needed.let mutbuilder patterns (2 sites, bothNewTxTemplateEntrywith an optionalmetadata):core/exchange/src/ledger/templates/settle_internal_bitcoin_purchase.rs:221andcore/holding/src/template.rs:173→ a single chain with.maybe_metadata(opt).Unchanged for lana:
.always_active()(9 sites, all inline in chains),.metadata(..)onNew*builders (4 sites, stillResult),JobSvcConfig,default_expr.Test plan
Gate output is in the task report:
cargo fmt,cargo clippy --workspace --all-targets --all-features -D warnings,nix flake check(fmt, clippy, audit, deny),nix run .#nextest(nextest + doctests + docs, local Postgres), fuzz cratecargo check --all-targets, andmake check-event-schemas(no schema diff). No.sqlxchanges (no query changes).🤖 Generated with Claude Code
Note
Medium Risk
Wide breaking API change to every entity/template builder and a major es-entity bump; behavior should match prior validation but downstream crates must update call sites and error types.
Overview
Replaces
derive_builderwithbonacross the workspace and bumpses-entity0.20.0,job0.18.5, andobix0.14.4 (lockfiles updated, including fuzz). Entity hydration for accounts, journals, templates, etc. now usesX::hydrator()from es-entity 0.20 instead of per-entityderive_builderonEsEntitytypes.Builder API shifts: many
New*/ update types usebon::Builderwith compile-time required fields (infallible.build()); validated constructors (CalaLedgerConfig,NewParamDefinition, tx-template CEL pieces, velocity limits) return typed errors (InvalidCalaLedgerConfig,InvalidParamDefinition,CelParseRejection) instead of stringlyderive_buildervalidation. Update DTOs are renamed/consolidated (e.g.AccountUpdatereplacesAccountUpdateValues). Optional fields gainmaybe_*setters; metadata uses bonwithclosures.Tests, examples, and perf crates are migrated mechanically (drop
.unwrap()on infallible builds, chain builders instead oflet mut).Reviewed by Cursor Bugbot for commit c6a36f2. Bugbot is set up for automated code reviews on this repo. Configure here.