diff --git a/src/app/api/cron/garmin-sync/route.test.ts b/src/app/api/cron/garmin-sync/route.test.ts index 27db71a..7d62cdf 100644 --- a/src/app/api/cron/garmin-sync/route.test.ts +++ b/src/app/api/cron/garmin-sync/route.test.ts @@ -414,15 +414,18 @@ describe("POST /api/cron/garmin-sync", () => { ); }); - it("sets date to today's date string", async () => { + it("sets date to today's ISO date string", async () => { mockUsers = [createMockUser()]; - const today = new Date().toISOString().split("T")[0]; + // Full ISO format for consistent date comparison in queries + const todayDate = new Date(); + todayDate.setUTCHours(0, 0, 0, 0); + const todayISO = todayDate.toISOString(); await POST(createMockRequest(`Bearer ${validSecret}`)); expect(mockPbCreate).toHaveBeenCalledWith( expect.objectContaining({ - date: today, + date: todayISO, }), ); }); diff --git a/src/app/api/cron/garmin-sync/route.ts b/src/app/api/cron/garmin-sync/route.ts index 6bed67c..adbaf74 100644 --- a/src/app/api/cron/garmin-sync/route.ts +++ b/src/app/api/cron/garmin-sync/route.ts @@ -91,7 +91,13 @@ export async function POST(request: Request) { (u) => u.garminConnected && u.garminTokenExpiresAt && u.lastPeriodDate, ); + // YYYY-MM-DD format for Garmin API calls const today = new Date().toISOString().split("T")[0]; + // Full ISO format for PocketBase date field storage + // This ensures consistent date comparison in queries + const todayDate = new Date(); + todayDate.setUTCHours(0, 0, 0, 0); + const todayISO = todayDate.toISOString(); for (const user of users) { const userSyncStartTime = Date.now(); @@ -208,9 +214,10 @@ export async function POST(request: Request) { // Store default value 100 for body battery when Garmin returns null. // This prevents PocketBase's number field null-to-0 coercion from // causing the dashboard to display 0 instead of a meaningful value. + // Use full ISO date format for consistent date comparison in queries await pb.collection("dailyLogs").create({ user: user.id, - date: today, + date: todayISO, cycleDay, phase, bodyBatteryCurrent: bodyBattery.current ?? 100, diff --git a/src/app/api/today/route.ts b/src/app/api/today/route.ts index 6659292..67f1f21 100644 --- a/src/app/api/today/route.ts +++ b/src/app/api/today/route.ts @@ -74,13 +74,24 @@ export const GET = withAuth(async (_request, user, pb) => { // Sort by created DESC to get the most recent record if multiple exist let biometrics = { ...DEFAULT_BIOMETRICS, phaseLimit }; try { - const today = new Date().toISOString().split("T")[0]; - logger.info({ userId: user.id, today }, "Fetching dailyLog"); + // Use date range query for proper date field comparison + // PocketBase date fields need >= and < operators, not string contains + const todayStart = new Date(); + todayStart.setUTCHours(0, 0, 0, 0); + const tomorrowStart = new Date(todayStart.getTime() + 86400000); + const todayISO = todayStart.toISOString(); + const tomorrowISO = tomorrowStart.toISOString(); + + logger.info( + { userId: user.id, todayISO, tomorrowISO }, + "Fetching dailyLog", + ); const dailyLog = await pb .collection("dailyLogs") - .getFirstListItem(`user="${user.id}" && date~"${today}"`, { - sort: "-created", - }); + .getFirstListItem( + `user="${user.id}" && date>="${todayISO}" && date<"${tomorrowISO}"`, + { sort: "-created" }, + ); logger.info( { diff --git a/src/lib/garmin.test.ts b/src/lib/garmin.test.ts index c9f12af..88485fd 100644 --- a/src/lib/garmin.test.ts +++ b/src/lib/garmin.test.ts @@ -193,9 +193,7 @@ describe("fetchGarminData", () => { json: () => Promise.resolve(mockResponse), }); - const result = await fetchGarminData("/wellness/daily/123", { - oauth2Token: "test-token", - }); + const result = await fetchGarminData("/wellness/daily/123", "test-token"); expect(result).toEqual(mockResponse); });