mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(backup): carry the aggregation provenance through backup and restore
The disaster-recovery backup selected every Measurement scalar except the aggregation fields, so a restore brought every `stats:` aggregate back with no provenance and the Apple Health authority ladder came back flat: an export.xml source-day estimate could then overwrite a native HealthKit statistic. `aggregationProvenance` now rides the select, the disaster-recovery serialization, the payload schema and the restore mapping, following `externalSourceVersion` exactly — including staying out of the reduced portable shape, which carries the human-readable subset only. The schema field is optional, so every backup written before this parses unchanged. Restoring one of those older backups no longer recreates the ambiguity migration 0263 repaired: an Apple Health row under a `stats:` identity with no provenance comes back as LEGACY_UNKNOWN, the sentinel the cumulative drain already writes in that situation, so a native sync or archive reprocess can repair it. The gate is scoped as 0263 scoped its backfill — other providers mint `stats:` identities for their cumulative dailies and have never carried provenance, and ordinary point rows keep NULL.
This commit is contained in:
1 parent
f8f460bb66
commit
2a396dd23e
6 files changed
+242
-3
No files matched your search
@@ -407,6 +407,25 @@ const handler = apiHandler(
|
||||
: decodeEncryptedBytes(measurement.notesEncrypted),
|
||||
externalId: measurement.externalId ?? null,
|
||||
externalSourceVersion: measurement.externalSourceVersion ?? null,
|
||||
// Authority of an Apple Health `stats:` aggregate. A backup
|
||||
// written before this field rode the payload carries nothing, and
|
||||
// restoring NULL would flatten the authority ladder: an export.xml
|
||||
// source-day estimate could then overwrite a native HealthKit
|
||||
// statistic, which is the ambiguity migration 0263 already
|
||||
// repaired once. Such a row is exactly the case LEGACY_UNKNOWN
|
||||
// exists for, so it comes back repairable instead of ambiguous.
|
||||
//
|
||||
// The gate is scoped exactly as 0263 scoped its backfill and as
|
||||
// the cumulative drain scopes its own LEGACY_UNKNOWN writes:
|
||||
// Apple Health rows only. Other providers mint `stats:` ids for
|
||||
// their cumulative dailies too (Fitbit, Google Health) and have
|
||||
// never carried provenance — marking those would invent a state
|
||||
// they were never in. Ordinary point rows keep NULL honestly.
|
||||
aggregationProvenance: (measurement.aggregationProvenance ??
|
||||
(measurement.source === "APPLE_HEALTH" &&
|
||||
measurement.externalId?.startsWith("stats:")
|
||||
? "LEGACY_UNKNOWN"
|
||||
: null)) as never,
|
||||
glucoseContext: (measurement.glucoseContext ?? null) as never,
|
||||
sleepStage: (measurement.sleepStage ?? null) as never,
|
||||
rhythmClassification: (measurement.rhythmClassification ??
|
||||
|
||||
Reference in new issue
Block a user