Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Operator limits: operator API to read usage

Closed
#278 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@Schacki-Jr is already working on this.

Since Oct 15, 2026.

  • #356 by @Schacki-Jr — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
18/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript
Domain
api, backend

Research direction

This depends on the operator API from #275 and the usage table from #272, so check whether both are merged before starting. Read the operator routes and the usage repository functions they expose, then add the feed, per-workspace, and summary endpoints, plus the cursor encoding and the settled-at safety lag. Extend contracts/operator-api.v1.json and make the test table T01 to T10 pass. Done means those integration tests pass and the real responses validate against the contract.

Written by the indexing model from the issue text.

Description

area: app type: feature

Part of #268. Depends on #272 and #275.

Problem

An external service that sets limits also has to read what was consumed: to keep its own accounts, to decide a period's outcome, to answer a support question. The operator API of #275 has no usage endpoint, and the usage table of #272 is only reachable from inside the app.

Behavior

  • GET /api/operator/v1/usage?after=<cursor>&limit= — a page of settled records of every workspace, ordered by (settled_at, id). Each item: id, workspaceId, jobId, reviewKind, keyMode, modelTier (the tier name or null; never a model name), costMicroUsd (integer or null), promptTokens, completionTokens, settledAt, reason (null or a short code such as no_result). The response has an opaque nextCursor.
  • GET /api/operator/v1/workspaces/{id}/usage — the same for one workspace, plus from/to filters on settledAt.
  • GET /api/operator/v1/workspaces/{id}/usage/summary?from=&to= — per kind and key mode: record count, settled count, sum of known cost, number of records with unknown cost.
  • Out-of-order commits. A record becomes visible to the feed only when its settled_at is older than a safety lag (default 60 seconds, a validated instance constant), so a record committed late can never be skipped by a reader that already moved past its position. Readers must still treat id as the idempotency key; the contract says so.
  • Records are immutable once served. void and reserved records are not served.
  • No pull request, repository, branch, title or user data in any item.
  • The contract file contracts/operator-api.v1.json grows with these shapes and examples.

Scope

Routes, cursor encoding (opaque, validated, bounded), repository read functions use those of #272, contract additions, docs, tests.

Out of scope

Pushing events to a URL, deleting or correcting records, exports to files.

Test cases

ID kind level case expected
T01 behavior integration three settled records served in (settled_at, id) order with a cursor that continues without gaps or repeats
T02 behavior integration a record settled 10 seconds ago not served yet; served after the lag
T03 behavior integration reserved and void records never served
T04 security integration items and logs contain no model name, repository, pull request, email or key
T05 behavior integration summary for a period counts and sums match the records; unknown costs counted separately
T06 negative integration malformed or oversized cursor, limit out of range 400 with a stable code
T07 security integration no token 404 with the token unset, 401 with a wrong one (as #275)
T08 behavior integration a workspace filter only that workspace's records
T09 contract integration real answers valid against operator-api.v1.json
T10 regression integration a new record for a job with a repeated completion the feed shows one item
Dominant language
TypeScript
Stars
0
Forks
1
Avg merge
1h 15m
Merged PRs (30d)
217

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ExpidetGames/code-reviewer

All issues in ExpidetGames/code-reviewer

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.