fix(fitbit): hold the sync verdict when a token is dead or a write fails

A revoked or expired Fitbit refresh token used to fail the cycle's status
ledger and then stamp the same cycle a success: the connection flipped back
to connected, the watermark advanced, and after a reconnect the 24h overlap
could no longer reach the missed days. getValidToken's three null-return
paths (credentials missing, refresh failure, vanished connection) now register
on the per-cycle hard-fail ledger, so the cycle's verdict fails, the park at
error_reauth holds, and lastSyncedAt does not move. The two measurement write
catches do the same, so fetched-but-unwritten rows are re-fetched next tick
instead of aging out of the overlap.

syncUserFitbit now returns { imported, failed }; the manual-sync route, the
poll cohort adapter, and the backfill consume the new shape. The backfill
stamps backfillCompletedAt only after a clean full-history walk: a parked
connection returns without stamping, and a failed verdict throws so pg-boss
retries on the already-configured retry budget.
This commit is contained in:
Marc-André Bombeck committed 2026-07-24 12:47:27 +02:00
1 parent 6a0bec7553
commit 25b7ada8bf
4 files changed
+103 -17

No files matched your search

+1 -1
View File
@@ -58,6 +58,6 @@ export const POST = apiHandler(async (request: NextRequest) => {
}
}
const imported = await syncUserFitbit(user.id, { fullSync });
const { imported } = await syncUserFitbit(user.id, { fullSync });
return apiSuccess({ imported, fullSync });
});