mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
Merge pull request #308 from MBombeck/release/v1.16.2
v1.16.2 — cap the due-context fallback
This commit is contained in:
2 files changed
+44
No files matched your search
@@ -459,3 +459,26 @@ describe("reconstructDoseHistory", () => {
|
||||
expect(times).toEqual([...times].sort((a, b) => a - b));
|
||||
});
|
||||
});
|
||||
|
||||
describe("suggestNearestSlot fallback cap", () => {
|
||||
it("omits due-context when the nearest anchor sits days away", async () => {
|
||||
const { suggestNearestSlot } = await import("../dose-history");
|
||||
const mk = (iso: string) => {
|
||||
const at = new Date(iso);
|
||||
return {
|
||||
at,
|
||||
timeOfDay: "09:00",
|
||||
onTimeStart: new Date(at.getTime() - 60 * 60_000),
|
||||
onTimeEnd: new Date(at.getTime() + 60 * 60_000),
|
||||
overdueEnd: new Date(at.getTime() + 4 * 60 * 60_000),
|
||||
} as never;
|
||||
};
|
||||
// First minted slot is 2026-05-31 (startsOn); the take predates it by 6 days.
|
||||
const bands = [mk("2026-05-31T07:00:00Z"), mk("2026-06-01T07:00:00Z")];
|
||||
const far = suggestNearestSlot(new Date("2026-05-25T09:26:00Z"), bands, () => false);
|
||||
expect(far).toBeNull();
|
||||
// A take inside the suggestion zone still gets its context.
|
||||
const near = suggestNearestSlot(new Date("2026-05-31T08:30:00Z"), bands, () => false);
|
||||
expect(near?.timeOfDay).toBe("09:00");
|
||||
});
|
||||
});
|
||||
@@ -314,6 +314,27 @@ export function suggestNearestSlot(
|
||||
}
|
||||
}
|
||||
|
||||
// The nearest-anchor fallback only makes sense as due-context when the
|
||||
// anchor sits within one cadence step of the take. A take recorded before
|
||||
// the schedule's first minted slot (e.g. history predating startsOn) would
|
||||
// otherwise pair with a slot days or weeks away and the history row would
|
||||
// read "due 09:00 (-1904 h)" — meaningless. Cap the fallback at the band's
|
||||
// own capture reach plus one inter-slot gap; beyond that, no due-context.
|
||||
if (bestAny && bestSuggest === null) {
|
||||
const b = bestAny.band;
|
||||
const reach = b.overdueEnd.getTime() - b.onTimeStart.getTime();
|
||||
const idx = sorted.indexOf(b);
|
||||
const gapMs =
|
||||
sorted.length > 1
|
||||
? Math.abs(
|
||||
(sorted[Math.min(idx + 1, sorted.length - 1)].at.getTime() ||
|
||||
b.at.getTime()) -
|
||||
(sorted[Math.max(idx - 1, 0)].at.getTime() || b.at.getTime()),
|
||||
) / Math.max(1, Math.min(idx + 1, sorted.length - 1) - Math.max(idx - 1, 0))
|
||||
: reach;
|
||||
if (bestAny.dist > reach + gapMs) return null;
|
||||
}
|
||||
|
||||
const pick = bestSuggest ?? bestAny;
|
||||
if (!pick) return null;
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user