Skip to content

Commit 722f8d4

Browse files
chore(OUT-3686): condense getCustomerByEmail rationale comment
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ec3aef3 commit 722f8d4

1 file changed

Lines changed: 5 additions & 22 deletions

File tree

src/utils/intuitAPI.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -296,28 +296,11 @@ export default class IntuitAPI {
296296
return CustomerQueryResponseSchema.parse(qbCustomers.Customer[0])
297297
}
298298

299-
// QBO's query parser silently mishandles certain special characters (confirmed
300-
// for '+', and '=' / 'LIKE' literal both fail) when filtering on
301-
// PrimaryEmailAddr, returning 0 results even when a matching customer exists.
302-
// To stay correct for any RFC-legal email, we never put the email in the WHERE
303-
// clause: page through customers and match client-side instead.
304-
//
305-
// sanitizedCompanyName disambiguates customers sharing the same email across
306-
// companies (one Copilot client can be enrolled in multiple companies). The
307-
// CompanyName comparison uses the same `(value || undefined)` normalisation
308-
// as the post-filter in customer.service.ts so the two layers cannot disagree.
309-
//
310-
// ORDERBY Id ASC pins the cursor to a stable, append-only key. QBO's default
311-
// ordering is MetaData.LastUpdatedTime DESC — under that ordering, a customer
312-
// updated mid-walk shifts to the front and can push an unscanned row past
313-
// our STARTPOSITION cursor (false negative). Id is monotonic and immutable,
314-
// so concurrent updates do not move rows and any customer created during the
315-
// walk lands at the end of the cursor where we'll still encounter it.
316-
//
317-
// Tradeoff vs. CreateTime DESC: newly-created customers land on the LAST
318-
// page rather than page 1, so drift recovery for a fresh customer in a 10k
319-
// realm walks all pages (~5s) instead of hitting on page 1 (~500ms). The
320-
// perf cost is bounded and acceptable; full stability is the priority.
299+
// QBO's parser mishandles special chars on PrimaryEmailAddr filters, so we
300+
// page and match client-side. sanitizedCompanyName disambiguates the same
301+
// email across companies; normalisation matches customer.service.ts.
302+
// ORDERBY Id ASC pins a stable cursor — QBO's default (LastUpdatedTime DESC)
303+
// lets a mid-walk update shift a row past STARTPOSITION (false negative).
321304
async _getCustomerByEmail(
322305
email: string,
323306
sanitizedCompanyName?: string,

0 commit comments

Comments
 (0)