mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
feat(fitbit): add the Fitbit connection data model and FITBIT measurement source
Lay the data-model foundation for the Fitbit/Pixel integration over the Google Health API, mirroring the WHOOP provider. No OAuth, sync, or UI yet. - Prisma: FitbitConnection (1:1 per user, encrypted access/refresh tokens) and FitbitOAuthState models, two encrypted BYO-credential columns on User, and FITBIT appended to the MeasurementSource enum. Migration 0117_v1120_fitbit_integration is additive only — one enum value plus two tables and two nullable columns, no new MeasurementType (every launch metric maps onto an existing type). - Wire the two new encrypted columns and the FitbitConnection token columns into scripts/rotate-encryption-key.ts. - FITBIT touchpoints: the read measurementSourceEnum (not the writable set), the DEFAULT_SOURCE_PRIORITY and workout-source ladders, the sources-section label map, the IntegrationKey union plus its display name, and a fitbit()/fitbitStatus() query-key pair. The source-rank SQL and read-tier collapse pick FITBIT up from the ladders with no code change. - Add the FITBIT source label to all six locale bundles and regenerate the OpenAPI contract so the source enum carries FITBIT for the iOS decoder.
This commit is contained in:
1 parent
045da70133
commit
86b2774567
18 files changed
+368
-20
No files matched your search
@@ -214,29 +214,35 @@ export type DeviceTypePriority = z.infer<typeof deviceTypePrioritySchema>;
|
||||
* receives the same reading via Withings' Health Mate iOS app).
|
||||
*/
|
||||
export const DEFAULT_SOURCE_PRIORITY: Required<MetricPriority> = {
|
||||
steps: ["APPLE_HEALTH", "WITHINGS", "MANUAL"],
|
||||
activeEnergy: ["APPLE_HEALTH", "WITHINGS", "MANUAL"],
|
||||
walkingRunningDistance: ["APPLE_HEALTH", "WITHINGS", "MANUAL"],
|
||||
flightsClimbed: ["APPLE_HEALTH", "WITHINGS", "MANUAL"],
|
||||
// v1.12.0 — Fitbit/Pixel rides below Apple Health for cumulative metrics:
|
||||
// HealthKit still aggregates the broadest device set, and a Fitbit-only
|
||||
// self-hoster has no Apple stream to compete with anyway.
|
||||
steps: ["APPLE_HEALTH", "WITHINGS", "FITBIT", "MANUAL"],
|
||||
activeEnergy: ["APPLE_HEALTH", "WITHINGS", "FITBIT", "MANUAL"],
|
||||
walkingRunningDistance: ["APPLE_HEALTH", "WITHINGS", "FITBIT", "MANUAL"],
|
||||
flightsClimbed: ["APPLE_HEALTH", "WITHINGS", "FITBIT", "MANUAL"],
|
||||
// v1.11.0 — WHOOP leads the recovery-input ladders (sleep / HRV / RHR):
|
||||
// a worn-all-night strap has higher-resolution overnight sampling than
|
||||
// the iPhone-relayed HealthKit summary or the Withings nightly summary.
|
||||
sleep: ["WHOOP", "APPLE_HEALTH", "WITHINGS"],
|
||||
hrv: ["WHOOP", "APPLE_HEALTH", "WITHINGS"],
|
||||
restingHeartRate: ["WHOOP", "APPLE_HEALTH", "WITHINGS"],
|
||||
// v1.12.0 — Fitbit is a wrist wearable in the same class as WHOOP but with
|
||||
// a lower-fidelity nightly estimate, so it ranks just below it.
|
||||
sleep: ["WHOOP", "FITBIT", "APPLE_HEALTH", "WITHINGS"],
|
||||
hrv: ["WHOOP", "FITBIT", "APPLE_HEALTH", "WITHINGS"],
|
||||
restingHeartRate: ["WHOOP", "FITBIT", "APPLE_HEALTH", "WITHINGS"],
|
||||
// A real scale beats a strap's body-measurement estimate for weight.
|
||||
weight: ["WITHINGS", "APPLE_HEALTH", "MANUAL", "WHOOP"],
|
||||
weight: ["WITHINGS", "APPLE_HEALTH", "MANUAL", "WHOOP", "FITBIT"],
|
||||
bloodPressure: ["WITHINGS", "APPLE_HEALTH", "MANUAL"],
|
||||
pulse: ["WITHINGS", "APPLE_HEALTH", "MANUAL"],
|
||||
bodyFat: ["WITHINGS", "APPLE_HEALTH", "MANUAL"],
|
||||
bodyTemperature: ["WITHINGS", "APPLE_HEALTH", "MANUAL"],
|
||||
// Withings ScanWatch pulse-ox is the primary SpO2 sensor; WHOOP second.
|
||||
spo2: ["WITHINGS", "WHOOP", "APPLE_HEALTH", "MANUAL"],
|
||||
vo2Max: ["WITHINGS", "APPLE_HEALTH", "MANUAL"],
|
||||
pulse: ["WITHINGS", "APPLE_HEALTH", "MANUAL", "FITBIT"],
|
||||
bodyFat: ["WITHINGS", "APPLE_HEALTH", "MANUAL", "FITBIT"],
|
||||
bodyTemperature: ["WITHINGS", "APPLE_HEALTH", "MANUAL", "FITBIT"],
|
||||
// Withings ScanWatch pulse-ox is the primary SpO2 sensor; WHOOP second,
|
||||
// Fitbit third.
|
||||
spo2: ["WITHINGS", "WHOOP", "FITBIT", "APPLE_HEALTH", "MANUAL"],
|
||||
vo2Max: ["WITHINGS", "APPLE_HEALTH", "FITBIT", "MANUAL"],
|
||||
// v1.11.0 — new WHOOP-overlapping keys. ScanWatch dermal reading is the
|
||||
// primary skin-temperature sensor; WHOOP's strap is second.
|
||||
skinTemperature: ["WITHINGS", "WHOOP", "APPLE_HEALTH"],
|
||||
respiratoryRate: ["WHOOP", "APPLE_HEALTH", "WITHINGS"],
|
||||
// primary skin-temperature sensor; WHOOP's strap is second, Fitbit third.
|
||||
skinTemperature: ["WITHINGS", "WHOOP", "FITBIT", "APPLE_HEALTH"],
|
||||
respiratoryRate: ["WHOOP", "FITBIT", "APPLE_HEALTH", "WITHINGS"],
|
||||
// v1.11.0 — native-vs-derived recovery. WHOOP's device-native Recovery
|
||||
// outranks HealthLog's COMPUTED proxy when both exist; the proxy is the
|
||||
// fallback for users without a strap.
|
||||
|
||||
Reference in new issue
Block a user