Repository navigation
fix(congressional): decode net-worth amounts as fractional and optional members - #401
Merged
Merged
Conversation
…onal
Congressional net-worth disclosures return fractional amounts and omit
or null several members, so the previous integer, required-member
decoding rejected valid rows. Switch the monetary amounts to f64
(MarketValue) and make the frequently-absent members optional so real
responses decode without error.
**Decoding fixes (libfmp):**
* CongressionalMemberNetWorth.value and every
CongressionalMemberNetWorthAggregate amount are now MarketValue (f64)
instead of i64, serialized through the integral_f64 codec.
* CongressionalMemberNetWorth.category, name, owner and value,
CongressionalNetWorthRange.max, CongressionalDebtDetails.date_incurred
and the aggregate real_estate, stock, real_estate_liabilities,
business_and_self_employment, ownership_interest, options,
revolving_and_credit_lines, asset_backed_securities and
business_liabilities are now optional. The itemized members and the
range max keep a required key that may be null; date_incurred and the
aggregate members may be absent and are omitted on re-encode.
**Bindings and SDK:**
* Updated the fmp-py models, generated stubs and typecheck contract to
expose the new float and Optional types.
* Updated the Go SDK models and shadow decoders to use *float64 and
pointer members, handling missing and null values.
**Tests:**
* Added Python, Rust and Go coverage for fractional amounts, null
itemized members, an empty debtDetails object and absent aggregate
members, and relaxed the required-member assertions accordingly.
An empty-string incomeRange ("") on some senate-net-worth rows still fails
to decode; it needs a nested empty-or-null codec and is tracked
separately.
BREAKING CHANGE: CongressionalMemberNetWorth.value and the
CongressionalMemberNetWorthAggregate amounts changed from i64 to f64
(MarketValue). CongressionalMemberNetWorth.category, name, owner and value,
CongressionalNetWorthRange.max, CongressionalDebtDetails.date_incurred and
CongressionalMemberNetWorthAggregate.real_estate, stock,
real_estate_liabilities, business_and_self_employment, ownership_interest,
options, revolving_and_credit_lines, asset_backed_securities and
business_liabilities are now optional (Option / pointer / Optional); handle
None.
…g_if Extend ADR 0033 to cover response members whose key is seen missing from the object, not merely null. Such a member becomes a plain `Option<T>` with `skip_serializing_if = "Option::is_none"` (no `required_option`), decoding an absent or null key to `None` and omitting it on re-encode via `omitzero`, matching serde. This is distinct from the empty-or-null codec rules, which keep a required key. Document the first case: `CongressionalMemberNetWorthAggregate` omits several members across all audited `senate-net-worth-aggregated` rows, with a live probe also seeing `realEstate` and `stock` absent, and `CongressionalDebtDetails` omits `dateIncurred`. Record the new `Codec::Plain` shape in the generator notes. close #377
Add test coverage verifying that omittable aggregate fields decode a JSON null as None and re-encode without the field, across both the Rust and Go SDK parity suites. BREAKING CHANGE: CongressionalMemberNetWorth and CongressionalMemberNetWorthAggregate no longer derive Eq (their f64 amounts); compare fields instead.
benbenbang
enabled auto-merge (rebase)
September 30, 2026 16:18
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.
Congressional net-worth disclosures return fractional monetary amounts and frequently omit or null several members, so the previous integer, required-member decoding rejected valid API responses. This change relaxes the decoding to match the real data across the Rust core, Python bindings and Go SDK.
BREAKING CHANGE: CongressionalMemberNetWorth.value and the CongressionalMemberNetWorthAggregate amounts changed from i64 to f64 (MarketValue). CongressionalMemberNetWorth.category, name, owner and value, CongressionalNetWorthRange.max, CongressionalDebtDetails.date_incurred and the aggregate real_estate, stock, real_estate_liabilities, business_and_self_employment, ownership_interest, options, revolving_and_credit_lines, asset_backed_securities and business_liabilities are now optional (Option / pointer / Optional); handle None. CongressionalMemberNetWorth and CongressionalMemberNetWorthAggregate no longer derive Eq; compare fields instead.
An empty-string incomeRange ("") on some senate-net-worth rows still fails to decode and is tracked separately.
Closes #377
close #377