refactor(tz): consolidate startOfUtcDay into src/lib/tz/start-of-utc-day.ts

The mood-rollup and measurement-rollup writers carried byte-identical
copies of the helper that could drift independently. Promote one
canonical export under src/lib/tz/ so both writers — and any future
rollup table — import the same UTC-anchored truncation.
This commit is contained in:
Marc-André Bombeck committed 2026-05-21 12:10:42 +02:00
1 parent e26e27b5ff
commit 79c86a0652
3 files changed
+22 -23

No files matched your search

+1 -11
View File
@@ -31,6 +31,7 @@
import { prisma } from "@/lib/db";
import { getGlobalBoss } from "@/lib/jobs/boss-instance";
import { annotate } from "@/lib/logging/context";
import { startOfUtcDay } from "@/lib/tz/start-of-utc-day";
import type {
MeasurementType,
RollupGranularity,
@@ -518,17 +519,6 @@ async function persistRollupRows(
return touched;
}
/**
* Truncate a `Date` to the start of its UTC day. The rollup table
* stores TIMESTAMPTZ values so we anchor on UTC to keep the bucket
* key deterministic across timezone-shifting consumers.
*/
function startOfUtcDay(d: Date): Date {
return new Date(
Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0, 0),
);
}
/**
* Span of the bucket containing `measuredAt` at the given granularity.
* Postgres `date_trunc` is the canonical truncator; we mirror its
+1 -12
View File
@@ -40,6 +40,7 @@
import { prisma } from "@/lib/db";
import { getGlobalBoss } from "@/lib/jobs/boss-instance";
import { annotate } from "@/lib/logging/context";
import { startOfUtcDay } from "@/lib/tz/start-of-utc-day";
import type {
Prisma,
PrismaClient,
@@ -611,18 +612,6 @@ async function persistMoodRollupRows(
return touched;
}
/**
* Truncate a `Date` to the start of its UTC day. The rollup table
* stores TIMESTAMPTZ values so we anchor on UTC to keep the bucket
* key deterministic across timezone-shifting consumers — same
* convention as `measurement-rollups`.
*/
function startOfUtcDay(d: Date): Date {
return new Date(
Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0, 0),
);
}
/**
* Span of the bucket containing `moodLoggedAt` at the given
* granularity. Mirrors `measurement-rollups` so the WEEK / MONTH /
+20
View File
@@ -0,0 +1,20 @@
/**
* UTC-anchored start-of-day truncation shared by the measurement +
* mood rollup writers.
*
* Both rollup tables store TIMESTAMPTZ bucket starts. Anchoring on the
* UTC calendar day (rather than the user's local day) keeps the bucket
* key deterministic across timezone-shifting consumers — the same
* convention `date_trunc('day', measured_at AT TIME ZONE 'UTC')` would
* produce on the read side. The display surfaces re-bucket into the
* user's timezone via `userDayKey()` from `./format`.
*
* v1.4.40 W-GHOSTS consolidated two byte-identical local copies
* (`src/lib/measurements/rollups.ts` + `src/lib/mood/rollups.ts`) into
* this module so future writers cannot drift independently.
*/
export function startOfUtcDay(d: Date): Date {
return new Date(
Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0, 0),
);
}