Files
HealthLog/tests/integration/__golden__/backup-parity/schema-issues.json
T
Marc-André Bombeck e2ba86b12f feat(garmin): sync Garmin Connect through the Personal API
Garmin Connect now offers a Personal API: a person creates a key for
their own account and any client can buy short-lived tokens with it.
HealthLog takes that key in a new Garmin card, checks it with Garmin
before storing it sealed on the user row, and polls every hour.

- Transport: key exchange with a per-process token cache keyed on the
  key, one re-exchange on a refused token and then reauth_required, the
  429 Retry-After carried to the caller, the China host tried when the
  global one does not know the key, answers read with a byte cap, all
  egress through safeFetch to the two fixed hosts.
- Sync: daily summaries, sleep summaries, HRV, weigh-ins and the
  activity search, chunked to each resource's documented range, read one
  after another and stopped at the first rate limit; today's menstrual
  cycle summary adds logged period days the person has not logged.
- Backfill: a resumable walk through the shared admission lane that
  learns where the history starts from the daily summaries and the
  activities, waits out Garmin's rate limit and stamps its marker.
- Types: GARMIN source; BODY_BATTERY and STRESS_LEVEL for Garmin's own
  day scores, kept apart from the computed STRESS_SCORE; TRAINING_READINESS
  and ACUTE_TRAINING_LOAD for figures a bridge pushes through the ingest
  token. All four chart on the recovery page and sit on the ladders,
  units, ranges, labels and report groups like the device-native scores.
- Key expiry: learned from a token capped short of a day, else estimated
  from the validity picked at connect; the card warns a week ahead and
  asks for a new key once Garmin refuses the old one.
- Ledger, health, freshness, watchdog, backup classes, wipe plan,
  encrypted-column registry, rotation script, OpenAPI and all ten
  locales carry the new integration. The old "no Garmin connector" note
  is gone.
2026-11-04 10:14:10 +01:00

456 lines
10 KiB
JSON

{
"everySectionWrong": [
{
"code": "custom",
"path": [
"exportedAt"
],
"message": "Expected ISO-8601 date-time string"
},
{
"origin": "string",
"code": "too_small",
"minimum": 1,
"inclusive": true,
"path": [
"userId"
],
"message": "Too small: expected string to have >=1 characters"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"accountSettings",
"heightCm"
],
"message": "Invalid input: expected number, received string"
},
{
"expected": "boolean",
"code": "invalid_type",
"path": [
"accountSettings",
"hasDiabetes"
],
"message": "Invalid input: expected boolean, received string"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"measurements",
0,
"value"
],
"message": "Invalid input: expected number, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"measurements",
0,
"unit"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"measurements",
0,
"measuredAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"medications",
0,
"name"
],
"message": "Invalid input: expected string, received number"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"medications",
0,
"dose"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "array",
"code": "invalid_type",
"path": [
"medications",
0,
"schedules"
],
"message": "Invalid input: expected array, received string"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"moodEntries",
0,
"score"
],
"message": "Invalid input: expected number, received string"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"moodEntries",
0,
"loggedAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"labResults",
0,
"analyte"
],
"message": "Invalid input: expected string, received null"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"labResults",
0,
"unit"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"labResults",
0,
"takenAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"labResults",
0,
"source"
],
"message": "Invalid input: expected string, received undefined"
},
{
"code": "invalid_value",
"values": [
"DOCTOR_REPORT",
"DISCHARGE_LETTER",
"LAB_RESULT",
"IMAGING",
"PRESCRIPTION",
"REFERRAL",
"INSURANCE",
"VACCINATION",
"SICK_NOTE",
"OTHER"
],
"path": [
"documents",
0,
"kind"
],
"message": "Invalid option: expected one of \"DOCTOR_REPORT\"|\"DISCHARGE_LETTER\"|\"LAB_RESULT\"|\"IMAGING\"|\"PRESCRIPTION\"|\"REFERRAL\"|\"INSURANCE\"|\"VACCINATION\"|\"SICK_NOTE\"|\"OTHER\""
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"documents",
0,
"mimeType"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"documents",
0,
"byteSize"
],
"message": "Invalid input: expected number, received undefined"
},
{
"code": "invalid_value",
"values": [
"STORED",
"EXTRACTING",
"EXTRACTED",
"FAILED",
"CONFIRMED",
"DISCARDED"
],
"path": [
"documents",
0,
"status"
],
"message": "Invalid option: expected one of \"STORED\"|\"EXTRACTING\"|\"EXTRACTED\"|\"FAILED\"|\"CONFIRMED\"|\"DISCARDED\""
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"vaccinations",
0,
"occurredAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"vaccinations",
0,
"createdAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"vaccinations",
0,
"updatedAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "boolean",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"documentScoped"
],
"message": "Invalid input: expected boolean, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"createdAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"updatedAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"messages",
0,
"id"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"messages",
0,
"role"
],
"message": "Invalid input: expected string, received number"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"coachConversations",
0,
"messages",
0,
"createdAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"environmentContexts",
0,
"date"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"environmentContexts",
0,
"lat"
],
"message": "Invalid input: expected number, received undefined"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"environmentContexts",
0,
"lon"
],
"message": "Invalid input: expected number, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"environmentContexts",
0,
"locationLabel"
],
"message": "Invalid input: expected string, received undefined"
},
{
"code": "invalid_value",
"values": [
"HOME",
"TRAVEL",
"DEVICE"
],
"path": [
"environmentContexts",
0,
"source"
],
"message": "Invalid option: expected one of \"HOME\"|\"TRAVEL\"|\"DEVICE\""
},
{
"code": "invalid_value",
"values": [
"MANUAL",
"WITHINGS",
"IMPORT",
"APPLE_HEALTH",
"COMPUTED",
"WHOOP",
"FITBIT",
"NIGHTSCOUT",
"POLAR",
"OURA",
"TELEGRAM",
"MCP",
"GOOGLE_HEALTH",
"STRAVA",
"EXTERNAL",
"HEALTH_CONNECT",
"GARMIN"
],
"path": [
"ecgRecordings",
0,
"source"
],
"message": "Invalid option: expected one of \"MANUAL\"|\"WITHINGS\"|\"IMPORT\"|\"APPLE_HEALTH\"|\"COMPUTED\"|\"WHOOP\"|\"FITBIT\"|\"NIGHTSCOUT\"|\"POLAR\"|\"OURA\"|\"TELEGRAM\"|\"MCP\"|\"GOOGLE_HEALTH\"|\"STRAVA\"|\"EXTERNAL\"|\"HEALTH_CONNECT\"|\"GARMIN\""
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"externalRecordingId"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"recordedAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"samplingFrequency"
],
"message": "Invalid input: expected number, received undefined"
},
{
"expected": "number",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"sampleCount"
],
"message": "Invalid input: expected number, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"createdAt"
],
"message": "Invalid input: expected string, received undefined"
},
{
"expected": "string",
"code": "invalid_type",
"path": [
"ecgRecordings",
0,
"updatedAt"
],
"message": "Invalid input: expected string, received undefined"
}
]
}