Fix the request timer setting the Server-Timing header too late to ever be sent
Description
The request-timer middleware in src/index.ts registers res.on("finish", ...) and, inside that handler, calls res.setHeader("Server-Timing", ...). By the time the finish event fires the headers and body have already been flushed, so this setHeader call is a no-op (Node will warn or silently ignore writing headers after they are sent) — the Server-Timing header never actually reaches the client despite the comment claiming it "Sets Server-Timing on the response." This issue makes the timing header genuinely emitted.
Requirements and context
- Repository scope: Agentpay-Org/Agentpay-backend only.
- Move the
Server-Timing value onto the response before headers are sent — e.g. hook res.writeHead/res.on("close") is wrong; instead set it on the first byte using a res.on that fires pre-flush, or wrap res.end/res.writeHead, or compute and set it just before each handler responds via an outbound interceptor.
- Keep the existing structured request-completion log on
finish (that part is correct) and the durationMs measurement.
- Ensure the header is present on JSON, CSV, and metrics responses and does not break the
304/empty-body paths.
- Keep tests quiet under
NODE_ENV=test as today.
Suggested execution
- Fork the repo and create a branch
git checkout -b bug/observability-72-server-timing-header
- Implement changes
- Write code in: the request-timer middleware in
src/index.ts.
- Write comprehensive tests in: new
src/server-timing.test.ts — Server-Timing header present on a real response, value parses, present across content types, no "headers already sent" warning.
- Add documentation: note the
Server-Timing header in README.md.
- Add TSDoc on the timer.
- Validate security assumptions: timing exposes only coarse duration, no internal detail.
- Test and commit
Test and commit
- Run
npm test and npm run lint.
- Cover edge cases: JSON response, CSV download, 304 path, error response.
- Include the full
npm test output in the PR description.
Example commit message
fix: emit the server-timing header before the response is flushed
Guidelines
- Minimum 95 percent test coverage for impacted modules.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
- ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.
Fix the request timer setting the Server-Timing header too late to ever be sent
Description
The request-timer middleware in
src/index.tsregistersres.on("finish", ...)and, inside that handler, callsres.setHeader("Server-Timing", ...). By the time thefinishevent fires the headers and body have already been flushed, so thissetHeadercall is a no-op (Node will warn or silently ignore writing headers after they are sent) — theServer-Timingheader never actually reaches the client despite the comment claiming it "Sets Server-Timing on the response." This issue makes the timing header genuinely emitted.Requirements and context
Server-Timingvalue onto the response before headers are sent — e.g. hookres.writeHead/res.on("close")is wrong; instead set it on the first byte using ares.onthat fires pre-flush, or wrapres.end/res.writeHead, or compute and set it just before each handler responds via an outbound interceptor.finish(that part is correct) and thedurationMsmeasurement.304/empty-body paths.NODE_ENV=testas today.Suggested execution
git checkout -b bug/observability-72-server-timing-headersrc/index.ts.src/server-timing.test.ts—Server-Timingheader present on a real response, value parses, present across content types, no "headers already sent" warning.Server-Timingheader inREADME.md.Test and commit
npm testandnpm run lint.npm testoutput in the PR description.Example commit message
fix: emit the server-timing header before the response is flushedGuidelines
Community & contribution rewards