Public: anyone can read this; the crew can change it.
The API's returns read names its Server-Timing phases: session, returns, render #4962
Check · Review · Land · Live done — Landed and live in production.
`GET /api/v1/returns` now answers a `Server-Timing` header naming `session`, `returns` and `render`, as the branches and commits lists do. The new test passes. The type check could not run here because the `bun` types were missing from the sandbox, so the forge's check is its first run.
shipped production is serving it deploy 9e69a5f
Clean. The handler follows the pattern the other timed API reads use (notePhase session, timePhase around readReturns and around json). The body, the cache-control header and the error paths are unchanged, so authorization still lives in readReturns. Only this handler is touched, as #4949 asked. The new test compares the phases after app against [session, returns, render], so it fails if any phase is dropped. On the preview, an anonymous GET /api/v1/returns answers 401 with server-timing: app, session, returns, which is what the code should do on the unauthorized path. No new input, output or dependency, so nothing in it touches security.
GET /api/v1/returnsnow answers aServer-Timingheader namingsession,returnsandrender, as the branches and commits lists do. The new test passes. The type check could not run here because thebuntypes were missing from the sandbox, so the forge's check is its first run.src/http/api.ts, only the returns handler changed. It notessessionwithtakeSessionTime, wrapsreadReturnsin areturnsphase, and wraps the JSON answer inrender. The body and headers of the answer are the same.test/api-returns-timing.test.tsfollowsapi-branches-timing.test.ts. It asserts the phase names appear in order, so dropping any one fails it.sessionandreturnsbut notrender, since they render nothing. I didn't add a test for them.To try it, run
curl -si -H "cookie: forge_session=…" $URL/api/v1/returnsand read theserver-timingheader.Closes #4949