mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
feat(oura): import workouts and intraday heart rate
Workouts from /v2/usercollection/workout land as Workout rows keyed on the Oura id, with the activity mapped onto the canonical sport set and the raw label, intensity and recording source kept in metadata. Heart rate from /v2/usercollection/heartrate lands as PULSE, streamed page by page and written in bounded batches, first write wins per instant. The hourly window for heart rate is hours, not days: six by default, reaching back to the newest reading after a gap, at most 72. Both collections sit behind their own scopes (workout, heartrate). A grant from before they were requested answers 401 naming the scope; that is recorded as a scope note on the card, never as a failure or a reconnect. Collection refusals carry Retry-After on a 429.
This commit is contained in:
1 parent
9a3523a498
commit
7585994697
24 files changed
+1312
-179
No files matched your search
@@ -62,6 +62,7 @@ const WRITERS: Record<string, Disposition> = {
|
||||
"lib/fitbit/sync-core.ts": { kind: "gate" },
|
||||
"lib/google-health/sync-core.ts": { kind: "gate" },
|
||||
"lib/nightscout/sync.ts": { kind: "gate" },
|
||||
"lib/oura/sync-heart-rate.ts": { kind: "gate" },
|
||||
// The shared identity seam. Polar, Oura, WHOOP, the Withings sleep leg,
|
||||
// the Apple export importer and the batch endpoint all write through it,
|
||||
// so the gate here is what makes a new provider fail closed.
|
||||
|
||||
@@ -61,6 +61,8 @@ const WRITE_SITES: Record<string, string> = {
|
||||
"refolds the touched days and re-warms the touched types at the end of the upsert",
|
||||
"lib/nightscout/sync.ts":
|
||||
"refolds the touched days and re-warms the touched types at the end of the sync",
|
||||
"lib/oura/sync-heart-rate.ts":
|
||||
"collects the days each heart-rate page touched; refolds them and re-warms the type once per window",
|
||||
"lib/withings/sync.ts":
|
||||
"refolds the touched days and re-warms the touched types at the end of the sync",
|
||||
"lib/withings/sync-activity.ts":
|
||||
|
||||
@@ -116,6 +116,15 @@ const PROVIDER_INGESTS: ProviderIngest[] = [
|
||||
writeFile: "lib/import/health-connect/import.ts",
|
||||
metadataKey: "healthConnectExerciseType",
|
||||
},
|
||||
{
|
||||
provider: "Oura",
|
||||
mapper: "mapOuraSportType",
|
||||
mapperFile: "lib/oura/sport-map.ts",
|
||||
captureFile: "lib/oura/sync-workouts.ts",
|
||||
captureField: "w.activity",
|
||||
writeFile: "lib/oura/sync-workouts.ts",
|
||||
metadataKey: "ouraActivity",
|
||||
},
|
||||
{
|
||||
provider: "Fitbit",
|
||||
mapper: "mapFitbitSportType",
|
||||
|
||||
Reference in new issue
Block a user