Skip to content

accelerate-v0.6.274

@kanat kanat tagged this 05 Nov 04:09
## Why

Volt's staff Usage tab lists an organization's usage through the staff
gateway. The gateway refuses `api_key` in a staff call's query ("a staff
call names no api_key"). The usage service reads the key filter only as
`api_key` (`internal/usage/server/manage.go:684`) and ignores
`api_key_id`, so `?api_key_id=<key>` answers every key's events with no
error. Staff cannot filter usage by key at all. #1726 renamed the same
filter on the router's own operations. This PR does the same on the
usage service.

## How it works

```
GET /v1/manage/accounts/{org}/usage?...      (listUsage, staff)
GET /v1/accounts/{org}/usage?...             (readAccountUsage, same input)
 ├─ api_key_id=K                  -> events of key K          (new)
 ├─ api_key=K                     -> events of key K          (alias, 1 release)
 ├─ api_key_id=K & api_key=K      -> events of key K
 ├─ api_key_id=K & api_key=J      -> 400 naming both
 └─ neither (or both empty)       -> every key's events       (unchanged)
```

`api_key` stays readable for one release. Reasons: the router and usage
pods roll out together in one release, and the router's own client still
sends `api_key` (`internal/usage/customer.go:212`). This PR does not
switch that client. If it did, a new router talking to an old usage pod
during rollout would get unfiltered rows.

## Changes

- `listUsageInput` gains `api_key_id`. `api_key` is marked `deprecated`.
`readAccountUsage` uses the same input, so it gets both.
- `internal/usage/server/openapi.yaml` is regenerated with `go run
./cmd/usage openapi`. The router's `api/openapi.yaml` and the clients do
not change: the usage service spec is not a client generator input.
- CHANGELOG entry under Bug Fixes.

## Validation

| Test (`ServerSuite`, both endpoints in each) | Catches | On base |
| --- | --- | --- |
| `TestListUsageFiltersByAPIKeyID` | `api_key_id` is ignored; a key
named twice with the same value is refused; an empty `api_key_id`
filters | fails (2 rows, unfiltered) |
| `TestListUsageStillFiltersByTheOldNameAPIKey` | the alias is dropped;
an empty `api_key_id` beside it is refused | passes (control) |
| `TestListUsageRefusesTwoDifferentKeys` | two different keys pass, or
the 400 does not name both | fails (200) |

Mutation checks (9): each half of the `cmp.Or`, the conflict case
removed, each of its three conditions dropped, the query tag renamed,
and the message. Each fails one of the tests above, except swapping the
`cmp.Or` order. That mutant is equivalent: the order only matters when
both names hold different keys, and that case is refused first.

`go test -tags integration ./internal/usage/...` passes on the branch
merged with `accelerate`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Assets 2
Loading