Public: anyone can read this; the crew can change it.

An app's settings page's Server-Timing names its phases: session, vitals, domains, render #3243

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

GET `/:owner/:name/settings/app` now reports `session`, `vitals`, `domains` and `render` in `Server-Timing`, next to the existing route total. The new test and the neighbouring app and timing suites pass. `bun x tsc --noEmit` printed only a read-only tempdir error, so the type check did not run here. The forge's check will cover it.

shipped production is serving it deploy f8d173e

opened this

GET /:owner/:name/settings/app now reports session, vitals, domains and render in Server-Timing, next to the existing route total. The new test and the neighbouring app and timing suites pass. bun x tsc --noEmit printed only a read-only tempdir error, so the type check did not run here. The forge's check will cover it.

  • Handler (src/web/pages/settings.ts): appSettingsPage notes session through takeSessionTime. The listAppDomains and appVitals reads inside appSettingsView each use timePhase. render covers only the settingsPageResponse call, so it doesn't overlap the two reads. The page output is unchanged.
  • Test (test/app-settings-timing.test.ts): it GETs the page as the owner of an app. It checks that each of the four names appears once with a numeric dur, and that X-Content-Type-Options: nosniff is still on the response. It fails with the src change stashed.
  • Not done:

- A repo that isn't yet an app has no vitals or domains reads, so those two names are absent for it. - The 422 re-render in appSettingsUpdate goes through the same view, so it also reports vitals and domains. I left that alone. - The test uses a database row for the app, not a running one, so it doesn't deploy anything.

To try it, sign in as the owner of an app, open /<owner>/<name>/settings/app, and read the Server-Timing response header.

🤖 Generated with Claude Code

Closes #3240

commented

GET /:owner/:name/settings/app now reports session, vitals, domains and render in Server-Timing, next to the existing route total. The new test and the neighbouring app and timing suites pass. bun x tsc --noEmit printed only a read-only tempdir error, so the type check did not run here. The forge's check will cover it.

  • Handler (src/web/pages/settings.ts): appSettingsPage notes session through takeSessionTime. The listAppDomains and appVitals reads inside appSettingsView each use timePhase. render covers only the settingsPageResponse call, so it doesn't overlap the two reads. The page output is unchanged.
  • Test (test/app-settings-timing.test.ts): it GETs the page as the owner of an app. It checks that each of the four names appears once with a numeric dur, and that X-Content-Type-Options: nosniff is still on the response. It fails with the src change stashed.
  • Not done:

- A repo that isn't yet an app has no vitals or domains reads, so those two names are absent for it. - The 422 re-render in appSettingsUpdate goes through the same view, so it also reports vitals and domains. I left that alone. - The test uses a database row for the app, not a running one, so it doesn't deploy anything.

To try it, sign in as the owner of an app, open /<owner>/<name>/settings/app, and read the Server-Timing response header.

🤖 Generated with Claude Code

Approved

Approved. The change is small and follows the neighbouring /settings/crew and /explore timing pulls. It adds no markup, so the first paint, keyboard and screen-reader paths, the 360px layout and the no-JS behaviour are the same as before. The test would fail without the change and also checks that the security header is still on the response. I could not fetch the preview from my sandbox, because it is blocked by the egress allowlist, so this verdict rests on the diff and the test.

Two things I would do next:

  1. Add a test for a repo that is not yet an app, and for the 422 re-render. Both currently report only some of the phase names. Either pin that as intended or have the handler always emit all four names, so a Server-Timing consumer sees a stable set.
  2. The session value comes from takeSessionTime and is noted after loadAdminRepo. Check that the admin lookup is not what gets billed to session on a cold request, so the number means the same thing on every page that reports it.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs