Fix body battery showing zeros on dashboard after Garmin sync
All checks were successful
Deploy / deploy (push) Successful in 2m29s

PocketBase coerces null number fields to 0 when reading. When Garmin
API returned no data (null), we stored null, which became 0 on
retrieval. The nullish coalescing (?? 100) in the API route didn't
catch this because 0 is not nullish.

Now store default value 100 when Garmin returns null, matching the
existing pattern used for decision engine calculations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-15 12:47:12 +00:00
parent 3a06bff4d4
commit 7ed827f82c
2 changed files with 12 additions and 5 deletions

View File

@@ -457,7 +457,11 @@ describe("POST /api/cron/garmin-sync", () => {
expect(body.errors).toBe(1);
});
it("handles body battery null values", async () => {
it("stores default value 100 when body battery is null from Garmin", async () => {
// When Garmin API returns null for body battery values (no data available),
// we store the default value 100 instead of null.
// This prevents PocketBase's number field null-to-0 coercion from causing
// the dashboard to display 0 instead of a meaningful value.
mockUsers = [createMockUser()];
mockFetchBodyBattery.mockResolvedValue({
current: null,
@@ -468,8 +472,8 @@ describe("POST /api/cron/garmin-sync", () => {
expect(mockPbCreate).toHaveBeenCalledWith(
expect.objectContaining({
bodyBatteryCurrent: null,
bodyBatteryYesterdayLow: null,
bodyBatteryCurrent: 100,
bodyBatteryYesterdayLow: 100,
}),
);
});

View File

@@ -205,13 +205,16 @@ export async function POST(request: Request) {
);
// Create DailyLog entry
// 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.
await pb.collection("dailyLogs").create({
user: user.id,
date: today,
cycleDay,
phase,
bodyBatteryCurrent: bodyBattery.current,
bodyBatteryYesterdayLow: bodyBattery.yesterdayLow,
bodyBatteryCurrent: bodyBattery.current ?? 100,
bodyBatteryYesterdayLow: bodyBattery.yesterdayLow ?? 100,
hrvStatus,
weekIntensityMinutes,
phaseLimit,