From ffe5545032735a1b9d15154cb56adde1d82c03bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 1 Aug 2026 19:54:08 +0200 Subject: [PATCH] =?UTF-8?q?chore(release):=20v1.35.3=20=E2=80=94=20an=20EC?= =?UTF-8?q?G=20arrives=20on=20its=20own,=20and=20only=20once?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple Watch ECG recordings reach the record straight from the app instead of only through an export archive. One recording per request, gated by the same switches that already govern reading them. A recording is now identified by what it is rather than by what a source calls it, so the same strip arriving through both doors converges on one row. The migration that adds the constraint resolves the duplicates already stored: it keeps the row holding the waveform over one holding only a verdict, and moves a removed row's event link onto the row that is kept. The losing rows are deleted. --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ docs/api/openapi.yaml | 2 +- package.json | 2 +- public/sw.js | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50fdb12c5..981f8f156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ ## [Unreleased] +## [1.35.3] — 2026-08-01 + +### Added + +- Apple Watch ECG recordings can now be sent directly by the iOS app, through a + new endpoint at `POST /api/insights/ecg`, instead of only arriving inside an + export archive. One recording travels per request, and the endpoint is gated + by the same module and status switches that already govern reading ECGs, so an + account with the surface switched off is unaffected. + +### Changed + +- A recording carries its own identity, so sending the same one again resolves + to the same record. A strip that arrives once inside an export archive and + again from the app ends up as a single entry rather than a duplicate or an + error. + +### Migration + +- This release removes duplicate ECG recordings. An existing database can hold + more than one row for the same recording, because the export archive and a + live client name the same strip differently. A uniqueness rule now prevents + that, and the migration resolves what is already stored before applying it. + Where two rows describe the same recording, it keeps the one holding the actual + waveform over one holding only a verdict, and it carries a removed row's link + to its rhythm event onto the row that is kept, so resolving a duplicate never + costs the recording its place in the timeline. Rows that lose are deleted, and + they cannot be recovered. Back up the database before deploying if that matters + for your instance. + ## [1.35.2] — 2026-08-01 ### Added diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index 17a7f0cc2..01bb4b8d6 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.35.2 + version: 1.35.3 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 328052eaf..96e4eeb1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "healthlog", - "version": "1.35.2", + "version": "1.35.3", "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 7bc9df343..23a1b22c7 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.35.2"; + /* @sw-version-fallback */ "v1.35.3"; 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/*`