Repository navigation
Maple Review Bot / Maple / review
succeeded
Nov 13, 2026 in 2m 55s
Confidence 10/10 · No issues found
🟢 Confidence 10/10 · safe to merge. Contained, well-tested provider work; the only open question is the vendors' live contracts, which no test can cover.
no findings · tests covered · risk high · 3/3 new units observable
Adds Anthropic and OpenAI as pasted-credential cost sources: key check, sealed connection, daily sync into cost_daily, plus the Cost page and lab entries. Safe to merge; the open VcsWebhookEnqueueFailure and McpOAuthProtocolError issues raised in apps/api/src/runtime/http-graph.ts come from that file's existing wiring and this diff neither fixes nor worsens them.
AnthropicCostConnectionServiceandOpenAiCostConnectionServicecheck a vendor key, then seal it throughCostConnectionStoreplanCostSyncgives both providers a three-month daily history with a four-day head- Each vendor's
normalize.tsfolds a day's lines intocost_dailyrows, cents to dollars for Anthropic - The three pasted-credential routes now share
cost-connection-handlers.ts
Before merge
- Manual · Call both vendors once with a real admin key: Anthropic accepting
ending_atof tomorrow, thegroup_by[]spelling, and how far back each serves
Fixed since the last review
- ✅
F1 · OpenAI costs query sendsgroup_by, not thegroup_by[]the endpoint takes
Production impact
Open errors in the changed files (2)
| Issue | Service | Occurrences | File |
|---|---|---|---|
| @maple/api/routes/VcsWebhookEnqueueFailure (2 issues) | maple-api | 9 | apps/api/src/runtime/http-graph.ts |
| @maple/backend/errors/McpOAuthProtocolError | maple-api | 4 | apps/api/src/runtime/http-graph.ts |
After this merges, Maple checks whether they stop.
Telemetry this change adds and removes (17)
- ➕ span name
HttpAnthropicCost.set·apps/api/src/routes/internal/anthropic-cost.http.ts:15 - ➕ span name
HttpAnthropicCost.remove·apps/api/src/routes/internal/anthropic-cost.http.ts:19 - ➕ span name
HttpOpenAiCost.set·apps/api/src/routes/internal/openai-cost.http.ts:15 - ➕ span name
HttpOpenAiCost.remove·apps/api/src/routes/internal/openai-cost.http.ts:19 - ➕ span name
AnthropicCostConnectionService.validateWithAnthropic·packages/backend/src/services/cost/AnthropicCostConnectionService.ts:73 - ➕ span name
AnthropicCostConnectionService.set·packages/backend/src/services/cost/AnthropicCostConnectionService.ts:88 - ➕ span name
AnthropicCostConnectionService.remove·packages/backend/src/services/cost/AnthropicCostConnectionService.ts:127 - ➕ span name
OpenAiCostConnectionService.validateWithOpenAi·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:71 - ➕ attribute
maple.cost.openai.pages·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:99 - ➕ attribute
maple.cost.openai.organization_header·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:100 - ➕ attribute
maple.cost.openai.organizations·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:101 - ➕ attribute
maple.cost.openai.has_results·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:102 - ➕ span name
OpenAiCostConnectionService.set·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:125 - ➕ span name
OpenAiCostConnectionService.remove·packages/backend/src/services/cost/OpenAiCostConnectionService.ts:164 - ➕ span name
AnthropicCostProvider.pull·packages/backend/src/services/cost/providers/anthropic/AnthropicCostProvider.ts:92 - ➕ attribute
maple.cost.anthropic.pages·packages/backend/src/services/cost/providers/anthropic/AnthropicCostProvider.ts:108 - ➕ span name
OpenAiCostProvider.pull·packages/backend/src/services/cost/providers/openai/OpenAiCostProvider.ts:62
What was checked
group_by[]is sent as repeated params, pinned inOpenAiCostProvider.test.tsandAnthropicCostConnectionService.test.ts- Rows carry the connection's stored
accountId, so a replaced key cannot restamp a source (OpenAiCostProvider.ts:97) couldBeAdminKeyrefuses anything unshaped before a request, pinned by the refusal test atAnthropicCostConnectionService.test.ts:108
Observability coverage: 3 of 3 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| PUT/DELETE /internal/cost/anthropic and /internal/cost/openai | inbound HTTP | yes | Effect.withSpan("HttpAnthropicCost.set") / HttpOpenAiCost.set in the new *-cost.http.ts |
| Anthropic and OpenAI vendor cost calls | outbound HTTP | yes | Effect.annotateSpans("peer.service", ...) plus maple.cost.* status attributes in each *-cost-api.ts |
| Scheduled cost sync pull per source | background worker | yes | Effect.fn("OpenAiCostProvider.pull") and the Anthropic equivalent, with days, pages, rows and error reason |
effdb8e · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Loading