feat(apple-health): ingest RMSSD heart-rate variability from iOS 27

iOS and watchOS 27 add `HKQuantityTypeIdentifierHeartRateVariabilityRMSSD`
(Apple's symbol `c:@HKQuantityTypeIdentifierHeartRateVariabilityRMSSD`,
available from 27.0). The live batch and the export.zip import now store it
as `HRV_RMSSD`, the type WHOOP, Oura and Polar already write, in
milliseconds, mean-aggregated and flagged privacy-sensitive like SDNN. The
accepted range is 1 to 300 ms.

RMSSD ranks on its own `hrvRmssd` ladder in the SQL source collapse, so a
day holding it from Apple Health and a strap resolves to one source
instead of a name tiebreak.

SDNN and RMSSD are different statistics and are kept apart once one
account holds both. The HRV page charts each on its own, titled with its
measure, instead of hiding RMSSD behind SDNN. The Coach's HRV section
carries one timeline per measure under `byMeasure` (same section key, so
every reader still finds it) rather than one daily series averaging the
two; the budget pass condenses and sheds each measure's timeline like a
glucose context.
This commit is contained in:
Marc-André Bombeck committed 2026-10-08 09:37:04 +02:00
1 parent 2731c46399
commit 370270bbc1
14 files changed
+618 -58

No files matched your search

+5 -1
View File
@@ -15,7 +15,9 @@ import { EcgCrossLink } from "@/components/insights/ecg-cross-link";
* SDNN as millisecond `HEART_RATE_VARIABILITY` rows; Oura / Polar / WHOOP
* store nightly RMSSD as `HRV_RMSSD`. The page renders SDNN when present
* and falls back to the RMSSD series (labelled "RMSSD") otherwise, so a
* ring / strap user's stored HRV always surfaces.
* ring / strap user's stored HRV always surfaces. Since iOS 27 an Apple
* Watch writes both (#1110); with rows of both the page charts each on its
* own, labelled, because the two are not one measure.
*/
export default function InsightsHrvPage() {
return (
@@ -23,6 +25,8 @@ export default function InsightsHrvPage() {
measurementType="HEART_RATE_VARIABILITY"
fallbackMeasurementType="HRV_RMSSD"
fallbackMeasureLabel="RMSSD"
primaryMeasureLabel="SDNN"
fallbackColor="var(--chart-2)"
statusMetric="HEART_RATE_VARIABILITY"
insightMetric="HEART_RATE_VARIABILITY"
chartKey="hrv"