diff --git a/src/lib/measurements/__tests__/rollup-read-cumulative.test.ts b/src/lib/measurements/__tests__/rollup-read-cumulative.test.ts index 79fd9f161..293193dfd 100644 --- a/src/lib/measurements/__tests__/rollup-read-cumulative.test.ts +++ b/src/lib/measurements/__tests__/rollup-read-cumulative.test.ts @@ -24,7 +24,6 @@ import { prisma } from "@/lib/db"; import { isCumulativeType, readCumulativeDaySums, - readCumulativeDaySumsBatch, resolveBucketSum, } from "../rollup-read-cumulative"; @@ -112,64 +111,6 @@ describe("readCumulativeDaySums", () => { }); }); -describe("readCumulativeDaySumsBatch", () => { - it("groups by type and seeds empty arrays for missing types", async () => { - const since = new Date("2026-04-15T00:00:00.000Z"); - mocks.findMany.mockResolvedValueOnce([ - { - type: "ACTIVITY_STEPS", - bucketStart: new Date("2026-04-15T00:00:00.000Z"), - sumValue: 8120, - count: 4, - mean: 2030, - }, - { - type: "ACTIVITY_STEPS", - bucketStart: new Date("2026-04-16T00:00:00.000Z"), - sumValue: 12480, - count: 5, - mean: 2496, - }, - { - type: "FLIGHTS_CLIMBED", - bucketStart: new Date("2026-04-15T00:00:00.000Z"), - sumValue: 22, - count: 3, - mean: 7.33, - }, - ]); - - const out = await readCumulativeDaySumsBatch( - "user-1", - ["ACTIVITY_STEPS", "FLIGHTS_CLIMBED", "TIME_IN_DAYLIGHT"], - since, - ); - - expect(out.get("ACTIVITY_STEPS")).toHaveLength(2); - expect(out.get("FLIGHTS_CLIMBED")).toHaveLength(1); - // Type with zero rollup rows still surfaces as an empty array so - // the caller can avoid a `.get(...) ?? []` fallback per branch. - expect(out.get("TIME_IN_DAYLIGHT")).toEqual([]); - // Single findMany over the IN-list — replaces the per-type loop - // that drove the A2 cold path on Marc's tenant. - expect(prisma.measurementRollup.findMany).toHaveBeenCalledTimes(1); - const args = mocks.findMany.mock.calls[0][0]; - expect(args.where.type).toEqual({ - in: ["ACTIVITY_STEPS", "FLIGHTS_CLIMBED", "TIME_IN_DAYLIGHT"], - }); - }); - - it("returns an empty map without querying when types is empty", async () => { - const out = await readCumulativeDaySumsBatch( - "user-1", - [], - new Date("2026-04-15T00:00:00.000Z"), - ); - expect(out.size).toBe(0); - expect(prisma.measurementRollup.findMany).not.toHaveBeenCalled(); - }); -}); - describe("resolveBucketSum", () => { it("returns sumValue when populated", () => { expect( diff --git a/src/lib/measurements/rollup-coverage.ts b/src/lib/measurements/rollup-coverage.ts index 76724d89d..46cd15a0b 100644 --- a/src/lib/measurements/rollup-coverage.ts +++ b/src/lib/measurements/rollup-coverage.ts @@ -70,19 +70,6 @@ export async function probeRollupCoverage( return coverage; } -/** - * Returns the set of types the user has logged that do NOT yet have - * DAY-rollup coverage. The bucket-fresh read paths use this to decide - * which types still need the live aggregator branch. - */ -export function typesMissingCoverage(coverage: RollupCoverageMap): string[] { - const missing: string[] = []; - for (const [type, hasBuckets] of coverage.entries()) { - if (!hasBuckets) missing.push(type); - } - return missing; -} - /** * Convenience — `true` when the user has at least one measurement and * every type with measurements also has DAY-bucket coverage. The read diff --git a/src/lib/measurements/rollup-read-cumulative.ts b/src/lib/measurements/rollup-read-cumulative.ts index d88f4fe6f..ffc61beab 100644 --- a/src/lib/measurements/rollup-read-cumulative.ts +++ b/src/lib/measurements/rollup-read-cumulative.ts @@ -108,53 +108,6 @@ export async function readCumulativeDaySums( })); } -/** - * Batch read DAY buckets for several cumulative types in one round - * trip. Eliminates the per-type chunked-findMany loop in - * `/api/analytics` A2 for the five highest-row-count metrics on - * Marc's tenant. - * - * Returns a Map keyed on `MeasurementType` so the caller can route - * each type's rows back into the per-metric branch without scanning - * the flat list. - */ -export async function readCumulativeDaySumsBatch( - userId: string, - types: readonly CumulativeType[], - since: Date, -): Promise> { - if (types.length === 0) return new Map(); - const rows = await prisma.measurementRollup.findMany({ - where: { - userId, - type: { in: types as unknown as MeasurementType[] }, - granularity: "DAY", - bucketStart: { gte: since }, - }, - orderBy: [{ type: "asc" }, { bucketStart: "asc" }], - select: { - type: true, - bucketStart: true, - sumValue: true, - count: true, - mean: true, - }, - }); - const out = new Map(); - for (const t of types) out.set(t, []); - for (const row of rows) { - const bucket = out.get(row.type as CumulativeType); - if (!bucket) continue; - bucket.push({ - bucketStart: row.bucketStart, - sumValue: row.sumValue, - count: row.count, - mean: row.mean, - }); - } - return out; -} - /** * Resolve a per-bucket cumulative total. Reads `sumValue` when the * v1.4.39 writer has populated it; falls back to `mean * count` for