docs(measurements): label EXTERNAL and update the guide and contract

The measurements list already badges any row whose source is not MANUAL and
already builds its source filter from the shared enum, so both pick the new
value up on their own. What it needs is a name: `EXTERNAL` reads as a leaked
enum constant, and it is the only new value a user is expected to operate,
since it is an option in the filter and a badge on every bridged row.

Both label catalogues gain an entry. They are keyed by the enum, so a new
source without a label is a type error and the coverage guard fails the
suite — which is exactly what happened here, and is the reason this carries
a settings label too even though EXTERNAL sits on no priority ladder and so
never renders there.

The settings card's scope note and the Home Assistant guide both claimed
readings arrive "as if you had entered them by hand", which is no longer
true. Both now say the rows are marked as coming from an external device and
are still yours to correct, and the guide spells out that the payload must
not name a source at all.

The changelog entries go under Unreleased as Changed: v1.38.1 shipped the
token, so these describe a change to something people already have. They say
what that means in practice — rows written before this keep the old label
and cannot be sorted out afterwards, a batch re-push can duplicate because
the dedup key now carries the source, and an automation sending an explicit
`source` field has to drop it.
This commit is contained in:
Antiheld86 authored and Marc-André Bombeck committed 2026-09-25 06:55:17 +02:00
1 parent 112a029443
commit 9fc1413181
14 files changed
+238 -41

No files matched your search

+144 -13
View File
@@ -2823,11 +2823,15 @@ paths:
the only place it ever exists; it is stored as an HMAC and no path re-reveals it.
**What it can do.** `POST /api/measurements` and `POST /api/measurements/batch`, on its owner's own record,
attributing `source: MANUAL`. An entry naming `APPLE_HEALTH` is refused 422 rather than relabelled: that source
is half a dedup key the phone also writes into, it participates in the cross-source merge, and it is what
**What it can do.** `POST /api/measurements` and `POST /api/measurements/batch`, on its owner's own record. Rows
it writes carry `source: EXTERNAL`, resolved from the credential rather than taken from the body, so a reading
pushed by a bridge stays distinguishable from one typed in by hand and can be picked out with the source filter.
A body naming ANY source is refused 422 rather than relabelled — honouring it would defeat the label, overriding
it silently would hand the caller rows it did not ask for. `APPLE_HEALTH` is the one that would do real damage:
it is half a dedup key the phone also writes into, it participates in the cross-source merge, and it is what
decides the Apple Health card may claim a sync happened. For the same reason a write through this credential
does not move the native client's sync checkpoint.
does not move the native client's sync checkpoint. The rows stay editable by their owner, unlike a connected
provider's — the hardware behind the token is the user's own.
**What it cannot do.** Everything else, including the measurement reads on the same paths, the edit and delete
@@ -3705,6 +3709,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
- in: query
name: valueMin
schema:
@@ -3748,9 +3753,11 @@ paths:
Also reachable with a narrow `measurements:write` Bearer, which is the supported way to push readings from a
scale, a watch bridge or a home-automation rule. That credential is confined to its owner's own record — a
request carrying the account selector is refused 403 before any sharing grant is read, however the record is
actually shared — and to `MANUAL` attribution, so an explicit `APPLE_HEALTH` source is refused 422
(`measurement.create.source_not_permitted`). The GET on this same path, and the PUT and DELETE beside it, name
no scope and so refuse it.
actually shared — and it may not attribute a source at all: rows it writes carry `source: EXTERNAL`, resolved
from the credential, so a bridged reading stays distinguishable from a hand-typed one. A body naming ANY source,
`MANUAL` included, is refused 422 (`measurement.create.source_not_permitted`). The GET on this same path, and
the PUT and DELETE beside it, name no scope and so refuse it — though the rows themselves stay editable by their
owner, unlike a connected provider's.
parameters:
- *a6
requestBody:
@@ -3781,8 +3788,8 @@ paths:
$ref: "#/components/schemas/ErrorEnvelope"
"422":
description: Validation failed, or (`measurement.create.source_not_permitted`) a narrow `measurements:write` credential
named `APPLE_HEALTH` as the source. Refused rather than relabelled, so the caller can fix the payload
instead of discovering rows it did not ask for.
named a source — any source. Refused rather than relabelled, so the caller can fix the payload instead of
discovering rows it did not ask for.
content:
application/json:
schema:
@@ -3914,8 +3921,10 @@ paths:
Also reachable with a narrow `measurements:write` Bearer, for a bridge that is not the phone. Such a credential
writes only on its owner's own record; its entries are attributed `MANUAL` whatever they omit, an entry naming
`APPLE_HEALTH` is refused 422 (`measurement.batch.source_not_permitted`), and the call does not advance the
writes only on its owner's own record; its entries are attributed `EXTERNAL` and it may not name a source
itself, so an entry carrying one — `MANUAL` and `APPLE_HEALTH` alike — is refused 422
(`measurement.batch.source_not_permitted`). `EXTERNAL` also gives those writes their own `(userId, type, source,
externalId)` namespace, so a bridge's ids can never collide with the phone's. The call does not advance the
native sync checkpoint — `lastSyncedAt` means the CLIENT delivered what it was holding, and a third-party push
is not that.
parameters:
@@ -3937,7 +3946,7 @@ paths:
"409": *a7
"422":
description: The batch exceeded the 500-entry limit (`measurement.batch.too_large`), failed validation, or
(`measurement.batch.source_not_permitted`) carried an entry naming `APPLE_HEALTH` under a narrow
(`measurement.batch.source_not_permitted`) carried an entry naming a source — any source — under a narrow
`measurements:write` credential. Nothing was written in any of the three cases.
content:
application/json:
@@ -6820,6 +6829,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -6840,6 +6850,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -6860,6 +6871,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -6880,6 +6892,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -6900,6 +6913,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -6920,6 +6934,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -6940,6 +6955,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -6960,6 +6976,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -6980,6 +6997,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -7000,6 +7018,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -7020,6 +7039,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -7040,6 +7060,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -7060,6 +7081,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -7080,6 +7102,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -7100,6 +7123,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -7120,6 +7144,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -7140,6 +7165,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -7160,6 +7186,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -7180,6 +7207,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
metricPriority:
type: object
properties:
@@ -7203,6 +7231,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -7223,6 +7252,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -7243,6 +7273,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -7263,6 +7294,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -7283,6 +7315,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -7303,6 +7336,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -7323,6 +7357,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -7343,6 +7378,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -7363,6 +7399,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -7383,6 +7420,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -7403,6 +7441,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -7423,6 +7462,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -7443,6 +7483,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -7463,6 +7504,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -7483,6 +7525,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -7503,6 +7546,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -7523,6 +7567,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -7543,6 +7588,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -7563,6 +7609,7 @@ paths:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
deviceTypePriority:
type: object
properties:
@@ -32676,6 +32723,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
notes:
anyOf:
- type: string
@@ -33954,6 +34002,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
externalId:
anyOf:
- type: string
@@ -34638,6 +34687,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
externalId:
anyOf:
- type: string
@@ -36558,6 +36608,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
externalId:
anyOf:
- type: string
@@ -36739,6 +36790,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
externalRecordingId:
type: string
minLength: 1
@@ -38832,7 +38884,10 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
description: Origin of the measurement. v1.4.23 added APPLE_HEALTH for the iOS HealthKit batch ingest path.
- EXTERNAL
description: Origin of the measurement. v1.4.23 added APPLE_HEALTH for the iOS HealthKit batch ingest path. v1.38.x
added EXTERNAL for rows pushed in under a narrow `measurements:write` Bearer — a scale, a watch bridge, a
home-automation rule. No client may name that value on a write; the server resolves it from the credential.
SyncMeasurementTombstone:
type: object
properties:
@@ -45386,6 +45441,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -45406,6 +45462,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -45426,6 +45483,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -45446,6 +45504,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -45466,6 +45525,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -45486,6 +45546,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -45506,6 +45567,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -45526,6 +45588,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -45546,6 +45609,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -45566,6 +45630,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -45586,6 +45651,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -45606,6 +45672,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -45626,6 +45693,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -45646,6 +45714,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -45666,6 +45735,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -45686,6 +45756,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -45706,6 +45777,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -45726,6 +45798,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -45746,6 +45819,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
metricPriority:
type: object
properties:
@@ -45769,6 +45843,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -45789,6 +45864,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -45809,6 +45885,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -45829,6 +45906,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -45849,6 +45927,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -45869,6 +45948,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -45889,6 +45969,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -45909,6 +45990,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -45929,6 +46011,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -45949,6 +46032,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -45969,6 +46053,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -45989,6 +46074,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -46009,6 +46095,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -46029,6 +46116,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -46049,6 +46137,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -46069,6 +46158,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -46089,6 +46179,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -46109,6 +46200,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -46129,6 +46221,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
additionalProperties: false
deviceTypePriority:
type: object
@@ -46198,6 +46291,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -46218,6 +46312,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -46238,6 +46333,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -46258,6 +46354,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -46278,6 +46375,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -46298,6 +46396,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -46318,6 +46417,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -46338,6 +46438,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -46358,6 +46459,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -46378,6 +46480,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -46398,6 +46501,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -46418,6 +46522,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -46438,6 +46543,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -46458,6 +46564,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -46478,6 +46585,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -46498,6 +46606,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -46518,6 +46627,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -46538,6 +46648,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -46558,6 +46669,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
metricPriority:
type: object
properties:
@@ -46581,6 +46693,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
activeEnergy:
maxItems: 8
type: array
@@ -46601,6 +46714,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
walkingRunningDistance:
maxItems: 8
type: array
@@ -46621,6 +46735,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
flightsClimbed:
maxItems: 8
type: array
@@ -46641,6 +46756,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleep:
maxItems: 8
type: array
@@ -46661,6 +46777,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
weight:
maxItems: 8
type: array
@@ -46681,6 +46798,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bloodPressure:
maxItems: 8
type: array
@@ -46701,6 +46819,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
pulse:
maxItems: 8
type: array
@@ -46721,6 +46840,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyFat:
maxItems: 8
type: array
@@ -46741,6 +46861,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
bodyTemperature:
maxItems: 8
type: array
@@ -46761,6 +46882,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
spo2:
maxItems: 8
type: array
@@ -46781,6 +46903,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
hrv:
maxItems: 8
type: array
@@ -46801,6 +46924,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
restingHeartRate:
maxItems: 8
type: array
@@ -46821,6 +46945,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
vo2Max:
maxItems: 8
type: array
@@ -46841,6 +46966,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
skinTemperature:
maxItems: 8
type: array
@@ -46861,6 +46987,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
respiratoryRate:
maxItems: 8
type: array
@@ -46881,6 +47008,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
recovery:
maxItems: 8
type: array
@@ -46901,6 +47029,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
stress:
maxItems: 8
type: array
@@ -46921,6 +47050,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
sleepDebt:
maxItems: 8
type: array
@@ -46941,6 +47071,7 @@ components:
- MCP
- GOOGLE_HEALTH
- STRAVA
- EXTERNAL
additionalProperties: false
deviceTypePriority:
type: object