mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
fix(withings): keep the plan re-probe date on a run that only narrowed
A run that skipped remembered types and met one more refusal restamped the leg's checkedAt, pushing the weekly re-probe of the remembered types out on every such run. Only a re-probe, or a leg with nothing remembered yet, now starts the week again.
This commit is contained in:
1 parent
6feaf6849a
commit
c7164be0d3
4 files changed
+51
-2
No files matched your search
@@ -384,6 +384,35 @@ describe("syncUserMeasurements inside the Withings API plan", () => {
|
||||
expect(runs[1]!.startdates.every((s) => s === fromLastGood)).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the remembered date when a run that is not the re-probe finds one more refusal", async () => {
|
||||
const remembered = new Date(Date.now() - 3 * 86_400_000).toISOString();
|
||||
vi.mocked(prisma.withingsConnection.findUnique).mockResolvedValue(
|
||||
connection({
|
||||
version: 1,
|
||||
measures: {
|
||||
unavailable: [...WITHINGS_ADVANCED_MEASTYPES],
|
||||
checkedAt: remembered,
|
||||
},
|
||||
}) as never,
|
||||
);
|
||||
// The plan starts refusing fat ratio too.
|
||||
refused = new Set([...WITHINGS_ADVANCED_MEASTYPES, 6]);
|
||||
|
||||
await syncUserMeasurements("user-1");
|
||||
|
||||
expect(persistedLegs()).toEqual([
|
||||
{
|
||||
leg: "measures",
|
||||
value: {
|
||||
unavailable: [6, ...WITHINGS_ADVANCED_MEASTYPES].sort(
|
||||
(a, b) => a - b,
|
||||
),
|
||||
checkedAt: remembered,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("reads the whole gap since the last good sync", async () => {
|
||||
await syncUserMeasurements("user-1");
|
||||
|
||||
|
||||
@@ -297,6 +297,24 @@ export function planSkipFor<K>(
|
||||
return leg.unavailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `checkedAt` to store with a run's outcome. Only a re-probe asked for the
|
||||
* full set, so only a re-probe (or a leg with nothing remembered yet) starts
|
||||
* the week again. A run that skipped remembered keys and found one more
|
||||
* refusal keeps the old date: moving it would push the re-probe of the keys it
|
||||
* never asked for further out on every such run.
|
||||
*/
|
||||
export function planCheckedAtFor<K>(
|
||||
leg: WithingsPlanLegState<K> | undefined,
|
||||
reprobed: boolean,
|
||||
now: Date,
|
||||
): string {
|
||||
if (reprobed || !leg || leg.unavailable.length === 0) {
|
||||
return now.toISOString();
|
||||
}
|
||||
return leg.checkedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write one leg of the plan state. A single statement merges the leg into the
|
||||
* stored object, so the measures, sleep and ECG legs (separate crons, separate
|
||||
|
||||
@@ -65,6 +65,7 @@ import {
|
||||
isPlanReprobeDue,
|
||||
parseWithingsApiPlanState,
|
||||
persistWithingsPlanLeg,
|
||||
planCheckedAtFor,
|
||||
planSkipFor,
|
||||
requestWithinPlan,
|
||||
shouldPersistPlanLeg,
|
||||
@@ -575,7 +576,7 @@ export async function syncUserSleep(
|
||||
) {
|
||||
await persistWithingsPlanLeg(userId, "sleepSummary", {
|
||||
unavailable: [...skip, ...plan.unavailable],
|
||||
checkedAt: now.toISOString(),
|
||||
checkedAt: planCheckedAtFor(sleepPlan, reprobed, now),
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
isPlanReprobeDue,
|
||||
parseWithingsApiPlanState,
|
||||
persistWithingsPlanLeg,
|
||||
planCheckedAtFor,
|
||||
planSkipFor,
|
||||
requestWithinPlan,
|
||||
shouldPersistPlanLeg,
|
||||
@@ -284,7 +285,7 @@ export async function syncUserMeasurements(
|
||||
try {
|
||||
await persistWithingsPlanLeg(userId, "measures", {
|
||||
unavailable: [...skip, ...plan.unavailable].sort((a, b) => a - b),
|
||||
checkedAt: now.toISOString(),
|
||||
checkedAt: planCheckedAtFor(planState.measures, reprobed, now),
|
||||
});
|
||||
} catch (err) {
|
||||
// Losing the memory only costs a refused round trip next run.
|
||||
|
||||
Reference in new issue
Block a user