@@ -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