fix(ops): stop the distance repair losing its rollup tail in silence

The rollups and the cached status insights are recomputed after the
transaction, so a throw there left the rows repaired and every chart on
the pre-repair numbers — and no later run would notice, because the
audit row makes the account skip from then on.

The tail is wrapped now. The audit row is written with
`rollupsRefreshed: false` and only flipped once the recompute returned,
so a re-run can tell "repaired, rollups pending" from "done" and says so.
A run that could not finish the tail names the account, prints the
backfill to re-run — `scripts/backfill-rollups.ts --user <userId>` — and
exits non-zero.

Review finding M2.
This commit is contained in:
Marc-André Bombeck committed 2026-09-10 00:37:15 +02:00
1 parent 69e4ba7b8a
commit 610083aa4d
4 files changed
+166 -22

No files matched your search

@@ -155,7 +155,17 @@ describe("Apple Health export distance repair — integration", () => {
factor: 1000,
rows: 2,
issue: 944,
// Flipped only after the rollup tail returned. A run that repaired the
// rows and lost the tail leaves this false, and the account is skipped
// from here on — so it is the only place the gap can still be seen.
rollupsRefreshed: true,
});
expect(outcome.rollupsPending).toBe(false);
const second = await planAppleHealthDistanceRepair(prisma, {
archiveUnit: "km",
});
expect(second[0].rollupsPending).toBe(false);
});
it("is idempotent — a second run finds nothing to repair", async () => {