feat(boss-dashboard): add windowRange helper with UTC boundaries
This commit is contained in:
parent
918586b6fb
commit
52b4b1f053
2 changed files with 77 additions and 0 deletions
30
src/lib/server/boss-dashboard-service.test.ts
Normal file
30
src/lib/server/boss-dashboard-service.test.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { describe, it, expect } from "vitest";
|
||||
import { windowRange } from "./boss-dashboard-service";
|
||||
|
||||
describe("windowRange", () => {
|
||||
it("today: start of UTC day to start of next UTC day", () => {
|
||||
const r = windowRange("today", new Date("2026-08-27T14:32:11.000Z"));
|
||||
expect(r.rangeStart).toBe("2026-08-27T00:00:00.000Z");
|
||||
expect(r.rangeEnd).toBe("2026-08-28T00:00:00.000Z");
|
||||
});
|
||||
|
||||
it("week: Monday 00:00 UTC to next Monday 00:00 UTC", () => {
|
||||
// 2026-08-27 is a Thursday. Week starts Mon 2026-08-24.
|
||||
const r = windowRange("week", new Date("2026-08-27T14:32:11.000Z"));
|
||||
expect(r.rangeStart).toBe("2026-08-24T00:00:00.000Z");
|
||||
expect(r.rangeEnd).toBe("2026-08-31T00:00:00.000Z");
|
||||
});
|
||||
|
||||
it("month: first of month to first of next month", () => {
|
||||
const r = windowRange("month", new Date("2026-08-27T14:32:11.000Z"));
|
||||
expect(r.rangeStart).toBe("2026-08-01T00:00:00.000Z");
|
||||
expect(r.rangeEnd).toBe("2026-09-01T00:00:00.000Z");
|
||||
});
|
||||
|
||||
it("week across month boundary: still anchored to Monday", () => {
|
||||
// 2026-09-02 is a Wednesday. Week starts Mon 2026-08-31, ends Mon 2026-09-07.
|
||||
const r = windowRange("week", new Date("2026-09-02T09:00:00.000Z"));
|
||||
expect(r.rangeStart).toBe("2026-08-31T00:00:00.000Z");
|
||||
expect(r.rangeEnd).toBe("2026-09-07T00:00:00.000Z");
|
||||
});
|
||||
});
|
||||
47
src/lib/server/boss-dashboard-service.ts
Normal file
47
src/lib/server/boss-dashboard-service.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
export type BossWindow = "today" | "week" | "month";
|
||||
|
||||
export interface WindowRange {
|
||||
rangeStart: string; // ISO
|
||||
rangeEnd: string; // ISO
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the [start, end) UTC window for a boss-dashboard time tab.
|
||||
* Today: midnight-to-midnight UTC.
|
||||
* Week: Monday 00:00 UTC to next Monday 00:00 UTC.
|
||||
* Month: day-1 00:00 UTC to day-1 of next month.
|
||||
*
|
||||
* All UTC because that's how PocketBase `created` timestamps compare.
|
||||
*/
|
||||
export function windowRange(window: BossWindow, now: Date = new Date()): WindowRange {
|
||||
const start = new Date(now);
|
||||
const end = new Date(now);
|
||||
|
||||
switch (window) {
|
||||
case "today": {
|
||||
start.setUTCHours(0, 0, 0, 0);
|
||||
end.setUTCDate(end.getUTCDate() + 1);
|
||||
end.setUTCHours(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
case "week": {
|
||||
// Monday = 1, Sunday = 0. Shift so Monday is start.
|
||||
const day = start.getUTCDay();
|
||||
const diffToMonday = day === 0 ? -6 : 1 - day;
|
||||
start.setUTCDate(start.getUTCDate() + diffToMonday);
|
||||
start.setUTCHours(0, 0, 0, 0);
|
||||
end.setTime(start.getTime());
|
||||
end.setUTCDate(end.getUTCDate() + 7);
|
||||
break;
|
||||
}
|
||||
case "month": {
|
||||
start.setUTCDate(1);
|
||||
start.setUTCHours(0, 0, 0, 0);
|
||||
end.setUTCMonth(end.getUTCMonth() + 1, 1);
|
||||
end.setUTCHours(0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { rangeStart: start.toISOString(), rangeEnd: end.toISOString() };
|
||||
}
|
||||
Loading…
Reference in a new issue