From 5ae4e17ec475f5697d74bbd2dff114d110024606 Mon Sep 17 00:00:00 2001 From: Sebastefanelli Date: Sun, 31 May 2026 21:43:36 -0300 Subject: [PATCH] fix: add json tags to ledger totals --- internal/storage/sqlite_test.go | 32 ++++++++++++++++++++++++++++++++ internal/storage/store.go | 10 +++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/internal/storage/sqlite_test.go b/internal/storage/sqlite_test.go index 23c3f24..0d216a0 100644 --- a/internal/storage/sqlite_test.go +++ b/internal/storage/sqlite_test.go @@ -2,6 +2,7 @@ package storage import ( "context" + "encoding/json" "errors" "path/filepath" "testing" @@ -150,6 +151,37 @@ func TestLedgerAndTotals(t *testing.T) { } } +func TestLedgerTotalsJSONTags(t *testing.T) { + totals := LedgerTotals{ + RunID: "run-3", + Calls: 2, + PromptTokens: 300, + CompletionTokens: 130, + Dollars: 0.036, + } + + b, err := json.Marshal(totals) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + var got map[string]any + if err := json.Unmarshal(b, &got); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + + for _, key := range []string{"runId", "calls", "promptTokens", "completionTokens", "dollars"} { + if _, ok := got[key]; !ok { + t.Fatalf("JSON key %q missing from %s", key, string(b)) + } + } + for _, key := range []string{"RunID", "Calls", "PromptTokens", "CompletionTokens", "Dollars"} { + if _, ok := got[key]; ok { + t.Fatalf("unexpected Go field name %q in %s", key, string(b)) + } + } +} + func TestSummarizeLedger(t *testing.T) { s := openTemp(t) ctx := context.Background() diff --git a/internal/storage/store.go b/internal/storage/store.go index 6627dc0..daf0cae 100644 --- a/internal/storage/store.go +++ b/internal/storage/store.go @@ -113,11 +113,11 @@ type ApprovalRecord struct { // LedgerTotals aggregates spend for audit/reporting. type LedgerTotals struct { - RunID string - Calls int64 - PromptTokens int64 - CompletionTokens int64 - Dollars float64 + RunID string `json:"runId"` + Calls int64 `json:"calls"` + PromptTokens int64 `json:"promptTokens"` + CompletionTokens int64 `json:"completionTokens"` + Dollars float64 `json:"dollars"` } // UsageGroup is one bucket of aggregated spend — e.g. one team, one provider, or