Refactor the internal HTTP helper from get() returning raw bytes to
getAndDecode() that streams directly into the target struct via
json.NewDecoder. This eliminates the intermediate []byte allocation
from io.ReadAll on every API response.
The new decoder also validates that responses contain exactly one JSON
value by attempting a second Decode after the primary one — any content
beyond the first value (e.g., concatenated objects from a misbehaving
proxy) returns an error instead of silently discarding it.
Changes:
- api/client.go: Replace get() with getAndDecode(), update FetchStores
and FetchSavings callers to use the new signature
- api/client_test.go: Add TestFetchSavings_TrailingJSONIsRejected and
TestFetchStores_MalformedJSONReturnsDecodeError covering the new
decoder error paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>