fix(integrations): increment per-kind bucket on back-fill path

The legacy single-counter column writes { increment: 1 } so the post-write value lands at N+1, but the back-fill seed wrote buckets[kind] = legacyCount (= N) without a compensating +1. Post-write the bucket would read N while the legacy column read N+1; when v1.4.44 drops the legacy column every back-filled row would page exactly one failure too late.

v1.4.43 W10 medium-reconcile — senior-dev M-1.
This commit is contained in:
Marc-André Bombeck committed 2026-05-21 23:05:59 +02:00
1 parent 89071e03d9
commit f1e16bf713
2 files changed
+16 -7

No files matched your search

@@ -662,10 +662,13 @@ describe("recordSyncFailure — v1.4.43 W14 per-kind buckets", () => {
// The 3 legacy failures get bucketed into the CURRENT failure's
// kind (reauth_required) — that's the kind the row was last
// tagged with, and back-filling into a different kind would
// under-count the existing streak.
// under-count the existing streak. v1.4.43 W10 senior-dev M-1 —
// the back-fill branch additionally increments the bucket so the
// post-write bucket count matches the legacy column's post-write
// value (legacy: 3 → 4, bucket: 0 → 3 → 4).
expect(upsertArgs.update.consecutiveFailuresByKind).toEqual({
transient: 0,
reauth_required: 3,
reauth_required: 4,
persistent: 0,
});
});
+11 -5
View File
@@ -381,18 +381,24 @@ export async function recordSyncFailure(
// Increment only the bucket matching this failure's kind.
// The other two buckets stay at their current value so a persistent
// streak isn't reset by an intervening transient hiccup.
//
// v1.4.43 W10 senior-dev M-1 — back-fill branch also increments. The
// legacy column writes `{ increment: 1 }` to advance from N → N+1; the
// back-fill seed sets `buckets[kind] = legacyCount` (= N), so without
// the +1 here the bucket would land at N while the legacy column reads
// N+1. When v1.4.44 drops the legacy column, every back-filled row
// would page exactly one failure too late.
if (startingBuckets) {
// Post-migration row — increment the actual bucket.
buckets[kind] = (buckets[kind] ?? 0) + 1;
} else if (!existing) {
// First-ever write — bucket starts at zero, this failure makes 1.
buckets[kind] = 1;
} else {
// Back-fill path — seeded with the legacy count; this failure is
// the +1 that brings both the legacy column AND the bucket to N+1.
buckets[kind] = (buckets[kind] ?? 0) + 1;
}
// else: back-fill path already seeded `buckets[kind]` with the legacy
// count; the current failure IS counted in that seed so no second
// increment is needed (a row at 4 failures sitting in error_reauth
// back-fills to reauth_required: 4 and this 5th failure makes the
// legacy +1 path bring the bucket to 5 below).
// Track the persistent-streak start so the >24h park check has a
// wall-clock anchor. Only stamped on the FIRST persistent failure of