mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
fix(withings): widen incremental overlap from 60s to 10 min
Withings backdates some readings and lastSyncedAt advances on every success (including a healthy 200-with-0 cycle), so a reading landing more than 60s before the next cycle's now() could be missed. Widen the poll catch-up overlap to 10 minutes — the upserts are idempotent, so re-touching a handful of rows is harmless.
This commit is contained in:
1 parent
4c158f6abc
commit
9eadd0755f
2 files changed
+34
-2
No files matched your search
@@ -1,5 +1,21 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { getWithingsWebhookCallbackUrl } from "../sync";
|
||||
import {
|
||||
getWithingsWebhookCallbackUrl,
|
||||
WITHINGS_INCREMENTAL_OVERLAP_MS,
|
||||
} from "../sync";
|
||||
|
||||
/**
|
||||
* F-SYNC-5 — the incremental overlap must stay comfortably wider than the old
|
||||
* 60s so a backdated Withings reading landing just before the next cycle's
|
||||
* `now()` is not missed (compounded by `lastSyncedAt` advancing on a healthy
|
||||
* 200-with-0 cycle). The upserts are idempotent, so a wider overlap is safe.
|
||||
*/
|
||||
describe("WITHINGS_INCREMENTAL_OVERLAP_MS", () => {
|
||||
it("is at least a few minutes (not the old 60s)", () => {
|
||||
expect(WITHINGS_INCREMENTAL_OVERLAP_MS).toBeGreaterThanOrEqual(5 * 60_000);
|
||||
expect(WITHINGS_INCREMENTAL_OVERLAP_MS).toBeGreaterThan(60_000);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* v1.4.25 W17a — Withings webhook callback URL must put the shared
|
||||
|
||||
@@ -131,6 +131,20 @@ export async function getValidToken(userId: string): Promise<{
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Incremental overlap window (ms). Withings backdates some readings (a scale
|
||||
* step syncs to the cloud minutes after the reading's timestamp), and
|
||||
* `lastSyncedAt` advances on every success — including a healthy 200-with-0
|
||||
* cycle (F-SYNC-1). A too-tight overlap let a reading that landed just before
|
||||
* the next cycle's `now()` slip through the gap. 10 minutes is comfortably wider
|
||||
* than the observed backdating skew while staying far short of a full re-scan;
|
||||
* the upserts are idempotent, so a wider overlap only re-touches a handful of
|
||||
* rows. (Still narrower than Google's 24h / Oura's 7-day because Withings is
|
||||
* webhook-primary — this overlap is the poll-catch-up safety net, not the main
|
||||
* path.)
|
||||
*/
|
||||
export const WITHINGS_INCREMENTAL_OVERLAP_MS = 10 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Sync measurements from Withings for a given user.
|
||||
* Fetches data since last sync (or last 30 days if first sync).
|
||||
@@ -172,7 +186,9 @@ export async function syncUserMeasurements(
|
||||
const startDate = opts.fullSync
|
||||
? undefined
|
||||
: connection.lastSyncedAt
|
||||
? new Date(connection.lastSyncedAt.getTime() - 60 * 1000) // overlap 1 min to avoid gaps
|
||||
? new Date(
|
||||
connection.lastSyncedAt.getTime() - WITHINGS_INCREMENTAL_OVERLAP_MS,
|
||||
)
|
||||
: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000); // 30 days back
|
||||
|
||||
let measures: Awaited<ReturnType<typeof fetchMeasurements>>;
|
||||
|
||||
Reference in new issue
Block a user