Skip to content

feat(ledger): serialize api money amounts as decimal strings - #114

Merged
tiana-code merged 1 commit into
mainfrom
feat/E-01-money-json-string
Jun 14, 2026
Merged

feat(ledger): serialize api money amounts as decimal strings#114
tiana-code merged 1 commit into
mainfrom
feat/E-01-money-json-string

Conversation

@tiana-code

Copy link
Copy Markdown
Owner

What

Money amounts were serialized over the API as JSON numbers. JSON has one numeric type and JS clients parse it into float64, truncating large or high-scale NUMERIC(38,18) values before any client code runs - a ledger correctness hazard.

This serializes money amounts as JSON decimal strings via BigDecimal.toPlainString() (exact digits, preserved scale, never scientific notation):

before  {"amount": 100.00}
after   {"amount": "100.00"}

Scope

  • MoneyAmountSerializer (JsonSerializer<BigDecimal>)
  • applied to BalanceResponse.amount (the only money output field today) + @Schema(type=string, format=decimal) so generated OpenAPI is accurate
  • per-field annotation, not a global Jackson module: outbox/event/idempotency serialization stays byte-stable
  • input unchanged: default BigDecimal deserialization already accepts string and number

Tests

  • MoneyAmountSerializerTest: trailing zeros preserved (100.00 -> "100.00"); high-scale value 12345678901234567890.123456789012345678 round-trips losslessly with no exponent
  • AccountControllerTest balance assertion updated to the string form (validates the real Spring ObjectMapper path)

Unblocks Sandbox UI Screen 2 (Account Detail + Balance) on a lossless string amount. ADR: Money over JSON (prepared for Wiki).

Closes #113

Money amounts were serialized as JSON numbers, which JS and other JSON
clients truncate to float64, losing precision for large or high-scale
NUMERIC(38,18) values. Add MoneyAmountSerializer writing BigDecimal via
toPlainString (exact digits, preserved scale, no scientific notation)
and apply it to BalanceResponse.amount with @Schema(type=string) so the
generated OpenAPI matches. Input is unaffected; default deserialization
already accepts string and number.

Closes #113
@tiana-code
tiana-code merged commit c672ae8 into main Jun 14, 2026
6 checks passed
@tiana-code
tiana-code deleted the feat/E-01-money-json-string branch June 14, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Serialize ledger API money amounts as JSON decimal strings (lossless)

1 participant