mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
v1.4.15 Phase B2, criterion 2. The Phase B2 status helper (commit4db72a8) defined a markReauthRequired / recordSyncFailure API but nothing called it. A Withings refresh token that had revoked got the same "transient error" treatment as a 503 from the upstream API, scheduled syncs kept hammering the OAuth endpoint, and the Settings UI showed "Connected" until the user manually triggered a sync and read the inline error. This commit wires every sync / OAuth path: - getValidToken() (Withings): refresh failures classified by Withings status code. 100/101/102 (auth failed / invalid token / user gone) and 200..299 (OAuth grant errors) -> error_reauth. Anything else (5xx, network) -> error_transient. Same logic inlined in /api/withings/status so the proactive refresh path parks the row too. - syncUserMeasurements() and syncMoodLogEntries() short-circuit immediately when isReauthRequired() returns true. Scheduled pg-boss jobs no longer burn API quota on a parked connection. - moodLog 401/403 from the upstream -> error_reauth. 5xx / 3xx redirect / network / invalid-JSON / bad-format -> error_transient. SSRF refusal also writes a status row so it surfaces in the UI. - /api/withings/callback calls markReconnected() after writing the new tokens, the next sync runs. - /api/withings/disconnect and DELETE /api/settings/moodlog call markDisconnected() to clear any prior error state. moodLog PUT /api/settings/moodlog (re-save credentials) markReconnected()s for the same reason. The helper writes AuditLog action=integrations.sync.failed on every failure (criterion 4) and dispatches a SYSTEM_ALERT notification to admins after consecutiveFailures >= 3 with a 24h re-alert window (criterion 3). Both paths are covered by the unit + integration test suites that landed in4db72a8— this commit makes them live. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>