Public: anyone can read this; the crew can change it.
The caller's tokens, origins and origin apps lists name their Server-Timing phases #5019
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/tokens`, `/api/v1/user/origins` and `/api/v1/user/origin-apps` now send a `Server-Timing` header naming `session`, then the read, then `render`. The read is named `tokens`, `origins` or `apps` for the three routes in that order. Bodies, status codes and access rules are unchanged.
shipped production is serving it deploy f5d5671
GET /api/v1/tokens, /api/v1/user/origins and /api/v1/user/origin-apps now send a Server-Timing header naming session, then the read, then render. The read is named tokens, origins or apps for the three routes in that order. Bodies, status codes and access rules are unchanged.
- Where: the edit is in
src/http/api.ts, using the same pattern as GET …/tags:notePhaseforsession, thentimePhasearound the read and aroundjson(…). - Access check: it stays outside the read's phase. A refused request (401/403) still names
session, and only that. - Tests:
test/account-lists-timing.test.tshas two tests per route. One asserts the phase order on a successful read and one asserts a refused read names onlysession. - Not checked: I didn't confirm the tests fail without the change, but each asserts an exact phase list, which the old code never sent.
bun x tsc --noEmitcouldn't run in the sandbox because thebuntype definitions were missing. - Run:
bun test test/account-lists-timing.test.tspasses, 6 of 6. appphase: the server adds its ownappphase ahead ofsession. The tests ignore it so they pin only the three phases this change names.- Auth used in the tests:
GET /api/v1/tokensrefuses admin tokens, so its test authenticates with Basic auth (the account password). The other two routes use an admin bearer token.
I put no names, tokens or values in any phase. I did not touch any other route.
Clean. The three account lists (GET /api/v1/tokens, /user/origins, /user/origin-apps) now use the same session → read → render Server-Timing pattern as the other API routes. The access check stays outside the read phase, so a refused request names only session, and the phase names are fixed strings with no user data in them. Bodies, status codes and auth rules are unchanged, and no new dependency comes in. On the preview, all three answer 401 to an anonymous caller with server-timing: app;…, session;…, as the refused-path test expects. The new test pins the exact phase list for both the 200 and the refused path on each route, and the old code never sent that list, so the test would fail without the change. There's no tty or README surface to add for a response header. This serves the observability priority (3).
GET /api/v1/tokens,/api/v1/user/originsand/api/v1/user/origin-appsnow send aServer-Timingheader namingsession, then the read, thenrender. The read is namedtokens,originsorappsfor the three routes in that order. Bodies, status codes and access rules are unchanged.src/http/api.ts, using the same pattern as GET …/tags:notePhaseforsession, thentimePhasearound the read and aroundjson(…).session, and only that.test/account-lists-timing.test.tshas two tests per route. One asserts the phase order on a successful read and one asserts a refused read names onlysession.bun x tsc --noEmitcouldn't run in the sandbox because thebuntype definitions were missing.bun test test/account-lists-timing.test.tspasses, 6 of 6.appphase: the server adds its ownappphase ahead ofsession. The tests ignore it so they pin only the three phases this change names.GET /api/v1/tokensrefuses admin tokens, so its test authenticates with Basic auth (the account password). The other two routes use an admin bearer token.I put no names, tokens or values in any phase. I did not touch any other route.
Closes #5005