mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
chore(glucose,berlin-day): drop unreferenced mmolToMgdl and berlinDayKey exports
The glucose UI only converts canonical mg/dL into mmol/L for display via convertGlucose; the reverse helper had no caller outside its own test. The Berlin-only day-key helper was already superseded by userDayKey(date, tz) in v1.4.38 for every read path that consumed it; its remaining presence as a tested module was dead weight.
This commit is contained in:
1 parent
b1469c4626
commit
f3a4da50f6
6 files changed
+9
-95
No files matched your search
@@ -208,12 +208,9 @@ async function buildAnalyticsResponse(user: AuthedUser) {
|
||||
// cost flat across the three branches.
|
||||
const coverage = await probeRollupCoverage(user.id);
|
||||
|
||||
// v1.4.25 W7b — every day-bucket call inside this route now honours
|
||||
// the user's display timezone. The legacy `berlinDayKey()` import
|
||||
// remains for sleep-stage and correlation paths that share their
|
||||
// helper signature with non-tz-aware code (`computeSleepStageBreakdown`
|
||||
// is called with a userId only); the per-call sites below all pass
|
||||
// `userTz` through `userDayKey()`.
|
||||
// v1.4.25 W7b — every day-bucket call inside this route honours the
|
||||
// user's display timezone via `userDayKey(date, userTz)` (the legacy
|
||||
// `berlinDayKey()` helper was retired in v1.4.40).
|
||||
const userTz = user.timezone ?? DEFAULT_TIMEZONE;
|
||||
|
||||
// Derived from canonical enum so a new measurement type is auto-summarised
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
mgdlToMmol,
|
||||
mmolToMgdl,
|
||||
convertGlucose,
|
||||
resolveGlucoseUnit,
|
||||
thresholdMetricForContext,
|
||||
@@ -14,18 +13,6 @@ describe("glucose conversion", () => {
|
||||
expect(mgdlToMmol(70)).toBeCloseTo(3.9, 1); // hypoglycemia threshold
|
||||
});
|
||||
|
||||
it("converts mmol/L to mg/dL rounded to integer", () => {
|
||||
expect(mmolToMgdl(5.5)).toBe(99);
|
||||
expect(mmolToMgdl(7.0)).toBe(126);
|
||||
});
|
||||
|
||||
it("roundtrips within 1 mg/dL", () => {
|
||||
for (const mgdl of [70, 99, 100, 126, 140, 200, 300]) {
|
||||
const back = mmolToMgdl(mgdlToMmol(mgdl));
|
||||
expect(Math.abs(back - mgdl)).toBeLessThanOrEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
it("convertGlucose dispatches to the right unit", () => {
|
||||
expect(convertGlucose(100, "mg/dL")).toBe(100);
|
||||
expect(convertGlucose(100, "mmol/L")).toBe(5.5);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { berlinDayKey } from "../berlin-day";
|
||||
|
||||
/**
|
||||
* v1.4.22 W5 reconcile (Code-MED-3) — pin that the helper buckets a
|
||||
* 23:30-Berlin reading on Tuesday into the Tuesday key, regardless of
|
||||
* UTC offset (CET / CEST, DST).
|
||||
*/
|
||||
describe("berlinDayKey", () => {
|
||||
it("buckets a 23:30-Berlin reading on Tuesday into Tuesday's key (CEST)", () => {
|
||||
// 2025-10-25T21:30:00Z = 2025-10-25T23:30 CEST (Saturday before DST end)
|
||||
expect(berlinDayKey(new Date("2025-10-25T21:30:00Z"))).toBe("2025-10-25");
|
||||
});
|
||||
|
||||
it("buckets a 23:30-Berlin reading after DST end into the right Berlin day", () => {
|
||||
// 2025-10-26 is the DST end day in Europe/Berlin (CET takes over).
|
||||
// 2025-10-26T22:30:00Z = 2025-10-26T23:30 CET — still Sunday in Berlin.
|
||||
expect(berlinDayKey(new Date("2025-10-26T22:30:00Z"))).toBe("2025-10-26");
|
||||
});
|
||||
|
||||
it("crosses the UTC-midnight boundary in Berlin's favour", () => {
|
||||
// 2026-05-09T22:30:00Z falls on 2026-05-10T00:30 CEST — Berlin says
|
||||
// Sunday, UTC says Saturday. The helper must follow Berlin.
|
||||
expect(berlinDayKey(new Date("2026-05-09T22:30:00Z"))).toBe("2026-05-10");
|
||||
});
|
||||
|
||||
it("returns YYYY-MM-DD format (sortable, padded)", () => {
|
||||
expect(berlinDayKey(new Date("2026-01-09T12:00:00Z"))).toBe("2026-01-09");
|
||||
expect(berlinDayKey(new Date("2026-12-09T12:00:00Z"))).toBe("2026-12-09");
|
||||
});
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* v1.4.22 W5 reconcile (Code-MED-1) — shared Berlin-day-key helper.
|
||||
*
|
||||
* The CLAUDE.md timezone convention is "Europe/Berlin for display,
|
||||
* UTC in database". The dashboard analytics route used a private
|
||||
* `berlinDayKey()` (defined in `src/app/api/analytics/route.ts:330`)
|
||||
* to bucket measurements by Berlin calendar day. The targets route's
|
||||
* `sparklinePoints()` was bucketing by UTC `YYYY-MM-DD` — a 23:30
|
||||
* Berlin reading on Tuesday landed in Wednesday's bucket, drifting
|
||||
* the sparkline 1 day on cross-DST boundaries.
|
||||
*
|
||||
* Lift the helper into `src/lib/analytics/` so every display surface
|
||||
* shares the same bucket contract.
|
||||
*/
|
||||
|
||||
const BERLIN_DATE_PARTS = new Intl.DateTimeFormat("en-CA", {
|
||||
timeZone: "Europe/Berlin",
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
});
|
||||
|
||||
/**
|
||||
* Format a `Date` as a `YYYY-MM-DD` string anchored to Europe/Berlin
|
||||
* calendar day. Used as a stable key for daily aggregation so a
|
||||
* 23:30-Berlin reading on Tuesday lands in Tuesday's bucket
|
||||
* regardless of UTC offset (CET / CEST, DST).
|
||||
*/
|
||||
export function berlinDayKey(d: Date): string {
|
||||
const parts = BERLIN_DATE_PARTS.formatToParts(d);
|
||||
const y = parts.find((p) => p.type === "year")?.value ?? "1970";
|
||||
const m = parts.find((p) => p.type === "month")?.value ?? "01";
|
||||
const day = parts.find((p) => p.type === "day")?.value ?? "01";
|
||||
return `${y}-${m}-${day}`;
|
||||
}
|
||||
@@ -15,10 +15,6 @@ export function mgdlToMmol(mgdl: number): number {
|
||||
return Math.round((mgdl / MGDL_PER_MMOL) * 10) / 10;
|
||||
}
|
||||
|
||||
export function mmolToMgdl(mmol: number): number {
|
||||
return Math.round(mmol * MGDL_PER_MMOL);
|
||||
}
|
||||
|
||||
export function convertGlucose(value: number, to: GlucoseUnit): number {
|
||||
return to === "mmol/L" ? mgdlToMmol(value) : Math.round(value);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ export type FormatInUserTzShape =
|
||||
* `DISPLAY_TIMEZONE`.
|
||||
*
|
||||
* - "date" — `2026-05-11` (ISO date in the user's zone). Used as a
|
||||
* day-bucket key parallel to the legacy `berlinDayKey()`.
|
||||
* stable day-bucket key for per-user aggregation.
|
||||
*/
|
||||
export function formatInUserTz(
|
||||
date: Date,
|
||||
@@ -151,11 +151,11 @@ export function formatInUserTz(
|
||||
}
|
||||
|
||||
/**
|
||||
* Day-bucket key in the user's timezone. Mirrors `berlinDayKey()` but
|
||||
* parameterised. Used as a stable Map key for daily aggregation so a
|
||||
* 23:30-local reading lands on today's bucket regardless of UTC
|
||||
* offset. The legacy `berlinDayKey()` stays for surfaces that are
|
||||
* not yet user-scoped (admin tables, audit log viewer).
|
||||
* Day-bucket key in the user's timezone. Used as a stable Map key for
|
||||
* daily aggregation so a 23:30-local reading lands on today's bucket
|
||||
* regardless of UTC offset. Every display surface in v1.4.40 anchors
|
||||
* here — the legacy Berlin-only `berlinDayKey()` was retired in that
|
||||
* release.
|
||||
*/
|
||||
export function userDayKey(date: Date, tz: string): string {
|
||||
return formatInUserTz(date, tz, "date");
|
||||
|
||||
Reference in new issue
Block a user