From d4f78811d94e6180270a0cba5af4290b57f2415b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 18 Jul 2026 11:59:38 +0200 Subject: [PATCH] =?UTF-8?q?chore(release):=20v1.30.8=20=E2=80=94=20harden?= =?UTF-8?q?=20aggregated=20heart-rate=20bucket=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +++++++++ docs/api/openapi.yaml | 2 +- package.json | 2 +- public/sw.js | 2 +- .../batch/__tests__/aggregated-hr-wire.test.ts | 10 ++++++---- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6fc9d1cb..60eab6f09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## [Unreleased] +## [1.30.8] — 2026-07-18 + +Hardening for the new heart-rate upload validation. + +- **A malformed bucket timestamp is rejected, not silently misfiled.** A bucket whose time rolled over (a 24:00, an impossible day) is now refused rather than stored under a non-standard key, where it would have failed to merge with a re-post and could land on the wrong day. +- **The per-window low/high is sanity-checked before it counts.** A window's low and high are kept only when they are in a plausible range and sit either side of the average; a glitched reading no longer skews the day's high/low band. The average is always kept. + +No migration. No breaking changes. + ## [1.30.7] — 2026-07-18 Groundwork for a tidier heart-rate history. diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 6e239e93b..a9ae1a496 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: HealthLog API - version: 1.30.7 + version: 1.30.8 description: >- Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest. diff --git a/package.json b/package.json index 9005d5e30..eacf041a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "healthlog", - "version": "1.30.7", + "version": "1.30.8", "description": "Self-hosted personal-health-tracking PWA with Withings integration, AI insights, and doctor-report PDF export.", "license": "PolyForm-Noncommercial-1.0.0", "homepage": "https://healthlog.dev", diff --git a/public/sw.js b/public/sw.js index b9fb25a34..0ebc4d602 100644 --- a/public/sw.js +++ b/public/sw.js @@ -36,7 +36,7 @@ try { // v1.4.38.4 → v1.4.42. Do not hand-edit; bump `package.json` and rebuild. const CACHE_VERSION = (typeof self !== "undefined" && self.__APP_VERSION__) || - /* @sw-version-fallback */ "v1.30.7"; + /* @sw-version-fallback */ "v1.30.8"; const STATIC_CACHE = `healthlog-static-${CACHE_VERSION}`; const PAGE_CACHE = `healthlog-pages-${CACHE_VERSION}`; // v1.18.6 — read-only data cache for a curated allowlist of safe GET `/api/*` diff --git a/src/app/api/measurements/batch/__tests__/aggregated-hr-wire.test.ts b/src/app/api/measurements/batch/__tests__/aggregated-hr-wire.test.ts index be4f79dd3..79f28b182 100644 --- a/src/app/api/measurements/batch/__tests__/aggregated-hr-wire.test.ts +++ b/src/app/api/measurements/batch/__tests__/aggregated-hr-wire.test.ts @@ -1,12 +1,14 @@ /** - * v1.19.0 (iOS #34) — go-forward aggregated heart-rate wire contract on - * `POST /api/measurements/batch`. + * v1.30.7/v1.30.8 (iOS #34) — go-forward aggregated 10-min heart-rate wire + * contract on `POST /api/measurements/batch`. * * Asserts: - * - a fresh 10-min HR bucket inserts; + * - a fresh 10-min HR bucket inserts, with its per-bucket min/max spread; * - a re-post of the same bucket OVERWRITES (status `updated`, not a * duplicate row); - * - a malformed aggregated HR bucket externalId is `skipped`; + * - a malformed / off-grid aggregated HR bucket externalId is `skipped`; + * - v1.30.8: an out-of-range or mis-ordered spread is dropped to null while + * the trustworthy average survives; * - the per-sample uuid HR path is unaffected (immutable duplicate); * - the existing per-day step `stats:` overwrite path is unaffected. */