From 9896e14129d6f9c21cd5243a68bf8921fd81fc35 Mon Sep 17 00:00:00 2001 From: Makisuo Date: Wed, 7 Oct 2026 01:57:20 +0200 Subject: [PATCH] fix(web): divide service overview throughput by the window it queried getServiceOverview falls back to a 24h window when no range is passed, but computed the rate duration from the raw inputs, which fall back to 3600s. Throughput came out 24x too high on the default window. --- apps/web/src/api/warehouse/services.test.ts | 12 ++++++++++++ apps/web/src/api/warehouse/services.ts | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/web/src/api/warehouse/services.test.ts b/apps/web/src/api/warehouse/services.test.ts index b93bc64313..8006d4594d 100644 --- a/apps/web/src/api/warehouse/services.test.ts +++ b/apps/web/src/api/warehouse/services.test.ts @@ -289,4 +289,16 @@ describe("getServiceOverview throughput resolution", () => { ]) }), ) + + // Live clock: the TestClock sits at epoch 0, where the fallback window has no positive start. + it.live("divides by the default 24h window it queried when no range is passed", () => + Effect.gen(function* () { + setActiveOrgId("overview-default-window") + const { data } = yield* getServiceOverview({ data: {} }) + + // 100 spans over the 24h fallback window, not over a 1h fallback duration. + const expected = 100 / (24 * 3600) + assert.ok(Math.abs(data[0].throughput - expected) < 1e-9, `throughput=${data[0].throughput}`) + }), + ) }) diff --git a/apps/web/src/api/warehouse/services.ts b/apps/web/src/api/warehouse/services.ts index 5d96a41bcb..8cc8a9c067 100644 --- a/apps/web/src/api/warehouse/services.ts +++ b/apps/web/src/api/warehouse/services.ts @@ -98,7 +98,9 @@ const getServiceOverviewEffect = Effect.fn("QueryEngine.getServiceOverview")(fun ) return { - data: coerceServiceOverviewRows(result.data, windowDurationSeconds(input.startTime, input.endTime)), + // The window the query actually ran on: the raw inputs fall back to 3600s, + // which would turn a 24h default window into a 24x-inflated rate. + data: coerceServiceOverviewRows(result.data, windowDurationSeconds(startTime, endTime)), } })