diff --git a/docs/integrations/fitbit.md b/docs/integrations/fitbit.md index c9eb2eae5..3d58c2c41 100644 --- a/docs/integrations/fitbit.md +++ b/docs/integrations/fitbit.md @@ -1,7 +1,9 @@ # Fitbit integration (Fitbit & Pixel) -> **Experimental.** Field mapping is still being verified against live accounts, -> so some values may be missing or change in a future update. +> **Ended.** Google turned the classic Fitbit Web API off on 30 October 2026. +> HealthLog no longer calls it; existing connections and what they imported +> stay. Fitbit and Pixel Watch data now come through +> [Google Health](google-health.md). HealthLog reads Fitbit and Pixel Watch data through the **classic Fitbit Web API** (`api.fitbit.com`). The OAuth app is a **Fitbit developer app registered @@ -16,13 +18,13 @@ Settings. The internal integration key is `fitbit`. > consent screen with `unauthorized_client — Invalid client_id`, because Fitbit > and Google Cloud are separate client registries. -> **The classic Fitbit Web API is turned off on 30 October 2026.** Google -> ended support for it on 30 September 2026 and turns it off on +> **The classic Fitbit Web API was turned off on 30 October 2026.** Google +> ended support for it on 30 September 2026 and turned it off on > **30 October 2026**, after which it "will no longer function or sync data" > ([Google's migration guide](https://developers.google.com/health/migration)). -> New app registrations at `dev.fitbit.com/apps/new` are already closed. +> New app registrations at `dev.fitbit.com/apps/new` are closed. > -> From that day HealthLog stops calling the Web API for every Fitbit +> Since that day HealthLog no longer calls the Web API for any Fitbit > connection: no hourly sync, no backfill, no token refresh, and no new > connection. Nothing is deleted. The connection and every reading it imported > stay, and the Fitbit card explains the move instead of asking for a @@ -30,10 +32,10 @@ Settings. The internal integration key is `fitbit`. > [Google Health integration](google-health.md). It reads the same devices, > but Google asks for consent once more: Fitbit tokens cannot be carried over. > -> Both integrations can run side by side while you move. Where both deliver the -> same day, the source-priority ladder keeps one of them per day (Fitbit ranks -> just above Google Health by default), so steps, sleep and the other daily -> values are not counted twice. After the turndown only Google Health delivers. +> Where a day imported from Fitbit before the turndown also comes in through +> Google Health, the source-priority ladder keeps one of them per day (Fitbit +> ranks just above Google Health by default), so steps, sleep and the other +> daily values are not counted twice. ## 1. Use an existing Fitbit developer app diff --git a/src/app/api/insights/presence/route.ts b/src/app/api/insights/presence/route.ts index 541ca3d9c..2bb66db73 100644 --- a/src/app/api/insights/presence/route.ts +++ b/src/app/api/insights/presence/route.ts @@ -1,5 +1,5 @@ /** - * GET /api/insights/presence — which Insights pages have something to show. + * GET /api/insights/presence: which Insights pages have something to show. * * The tab strip on every Insights page gates its pills on this answer alone: * the reading count per measurement type, and whether the record has mood diff --git a/src/lib/insights/derived/__tests__/coach-read-drivers-cache.test.ts b/src/lib/insights/derived/__tests__/coach-read-drivers-cache.test.ts index b4c2a1ed4..a44fbd026 100644 --- a/src/lib/insights/derived/__tests__/coach-read-drivers-cache.test.ts +++ b/src/lib/insights/derived/__tests__/coach-read-drivers-cache.test.ts @@ -61,7 +61,7 @@ beforeEach(() => { resolveModuleMap.mockReset().mockResolvedValue({}); }); -describe("coach read — the pattern scan behind the strip", () => { +describe("coach read: the pattern scan behind the strip", () => { it("scans once for two metric pages and picks each page's own driver", async () => { const sleep = await strip("SLEEP_DURATION"); const pulse = await strip("PULSE"); diff --git a/tests/integration/health-status-cache.test.ts b/tests/integration/health-status-cache.test.ts index 42253cf6f..fecdb8a45 100644 --- a/tests/integration/health-status-cache.test.ts +++ b/tests/integration/health-status-cache.test.ts @@ -90,7 +90,7 @@ beforeEach(async () => { __resetAllCachesForTests(); }); -describe("GET /api/insights/health-status — the cached answer", () => { +describe("GET /api/insights/health-status: the cached answer", () => { it("serves the second open from the cell", async () => { const { user, auth } = await signedInWithFortnight(); const first = await readHealthStatus(auth);