go/internal/services/membership/sources.go: transaction-row parser now passes row[idxDate] directly to matching.FormatDate (via a new getRaw helper) instead of stringifying first.
The Sheets API returns date-formatted cells as float64 (Sheets serial-day numbers since 1899-12-30). Pre-stringifying via fmt.Sprint(row[i]) produced "46147" and defeated FormatDate's case float64: dispatch, so the value leaked through unchanged instead of becoming "2026-05-05".
Surfaced by make parity (M5.4): every transactions[].date on /api/adults and /api/juniors showed Python "2026-05-05" vs Go "46147".
sources_test.go::TestLoadTransactions extended with a numeric-serial-day row.
Test plan
go test ./internal/services/membership/... — green (incl. new regression case)
go test ./... + golangci-lint run ./... — clean
Restart make web-go; curl localhost:8080/api/adults | jq '.member_data | to_entries[0].value.months | to_entries[].value.transactions[]?.date' | head — returns YYYY-MM-DD strings, no integers
## Summary
- `go/internal/services/membership/sources.go`: transaction-row parser now passes `row[idxDate]` directly to `matching.FormatDate` (via a new `getRaw` helper) instead of stringifying first.
- The Sheets API returns date-formatted cells as `float64` (Sheets serial-day numbers since 1899-12-30). Pre-stringifying via `fmt.Sprint(row[i])` produced `"46147"` and defeated `FormatDate`'s `case float64:` dispatch, so the value leaked through unchanged instead of becoming `"2026-05-05"`.
- Surfaced by `make parity` (M5.4): every `transactions[].date` on `/api/adults` and `/api/juniors` showed Python `"2026-05-05"` vs Go `"46147"`.
- `sources_test.go::TestLoadTransactions` extended with a numeric-serial-day row.
## Test plan
- [x] `go test ./internal/services/membership/...` — green (incl. new regression case)
- [x] `go test ./...` + `golangci-lint run ./...` — clean
- [ ] Restart `make web-go`; `curl localhost:8080/api/adults | jq '.member_data | to_entries[0].value.months | to_entries[].value.transactions[]?.date' | head` — returns YYYY-MM-DD strings, no integers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The transaction-row parser in services/membership/sources.go used a
helper (`getVal`) that did `fmt.Sprint(row[i])` before passing to
`matching.FormatDate`. The Sheets API returns date-formatted cells
as `float64` (Sheets serial-day numbers); pre-stringifying defeated
`FormatDate`'s `case float64:` dispatch, so values like 46147 leaked
through unchanged as the string "46147" instead of being converted
to "2026-05-05".
Surfaced by `make parity` (M5.4) — every `transactions[].date` on
/api/adults and /api/juniors differed between Python and Go. Python
side passes the raw value through directly (`isinstance(val, (int,
float))` in scripts/match_payments.py format_date), so it was always
correct.
Added a `getRaw` helper that returns row[i] without stringifying;
only the date column needs it. Extended TestLoadTransactions with
a numeric-serial-day row to lock in the regression.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
kacerr
merged commit 4d035213b5 into main2026-05-07 23:24:43 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
go/internal/services/membership/sources.go: transaction-row parser now passesrow[idxDate]directly tomatching.FormatDate(via a newgetRawhelper) instead of stringifying first.float64(Sheets serial-day numbers since 1899-12-30). Pre-stringifying viafmt.Sprint(row[i])produced"46147"and defeatedFormatDate'scase float64:dispatch, so the value leaked through unchanged instead of becoming"2026-05-05".make parity(M5.4): everytransactions[].dateon/api/adultsand/api/juniorsshowed Python"2026-05-05"vs Go"46147".sources_test.go::TestLoadTransactionsextended with a numeric-serial-day row.Test plan
go test ./internal/services/membership/...— green (incl. new regression case)go test ./...+golangci-lint run ./...— cleanmake web-go;curl localhost:8080/api/adults | jq '.member_data | to_entries[0].value.months | to_entries[].value.transactions[]?.date' | head— returns YYYY-MM-DD strings, no integers🤖 Generated with Claude Code