From ae17b304d7da07ce4124e54ae138f3409564c118 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Sun, 28 Jun 2026 13:42:41 +0200 Subject: [PATCH] fix(import): add stable .order() to account-sync chart paging (#790, #791 follow-up) (#812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `syncMappedAccounts` pages the company's full chart via `fetchAllRows` to avoid the silent 1000-row PostgREST cap, but the query had no `.order()`. Like the report queries fixed in #811, PostgREST `.range()` paging is only correct with a stable total order — without it, a chart larger than one page could duplicate or skip accounts across page boundaries, corrupting the existing-account Map and causing spurious create/update churn on import. Order on the unique `account_number` (stable total order; the result is read into a Map so the order is invisible to callers). Extend the test mock's query chain to include `.order()`. Co-authored-by: Claude Opus 4.8 (1M context) --- lib/import/__tests__/account-sync.test.ts | 4 ++++ lib/import/account-sync.ts | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/lib/import/__tests__/account-sync.test.ts b/lib/import/__tests__/account-sync.test.ts index 1b801f1b..bcc30b85 100644 --- a/lib/import/__tests__/account-sync.test.ts +++ b/lib/import/__tests__/account-sync.test.ts @@ -46,6 +46,9 @@ function buildCapturingSupabase(opts?: { return { select: () => ({ eq: () => ({ + // Mirrors the stable `.order('account_number')` the sync query now + // chains before `.range()` for paging stability. + order: () => ({ range: (from: number, to: number) => ({ then: ( resolve: (v: { @@ -60,6 +63,7 @@ function buildCapturingSupabase(opts?: { resolve({ data: existing.slice(from, to + 1), error: null }) }, }), + }), }), }), insert: (rows: Array>) => { diff --git a/lib/import/account-sync.ts b/lib/import/account-sync.ts index f259da1f..d94c4775 100644 --- a/lib/import/account-sync.ts +++ b/lib/import/account-sync.ts @@ -154,6 +154,11 @@ export async function syncMappedAccounts( .from('chart_of_accounts') .select('account_number, account_name') .eq('company_id', companyId) + // Stable total order on the unique account_number — paging is only + // correct with a deterministic order, else rows duplicate/skip across + // pages (see fetch-all.ts ordering invariant). The result is read into + // a Map below, so this order is invisible to callers. + .order('account_number', { ascending: true }) .range(from, to) ) existingByNumber = new Map(