- Ya
- 20 Agosti 2026, 23:34 UTC
- Mwandishi
- kamo
- Ahadi ya
- 96494f1
The grid fetched every lead in the org and narrowed it in a ~300-line useMemo. Measured on production 2026-08-20: 1,427 leads fetched so seven could be shown, 23.3 s a load — because the server also writes one PHI audit row per lead RETURNED, one transaction each. Filtering in the browser is what made that volume proportional to tenant size. leadGridQuery.ts maps the filter bar onto the query string. The split is deliberate: the server filters on values, the client resolves catalogues into them — which statuses a market's sales type allows, which vendor records share a display name, which statuses are children of a parent. Those live in reference data the grid already holds, and a second copy in Java would be free to disagree with the one the grid draws. Kept pure and tested, because the failure mode of this migration is not an error, it is a filter that quietly stops narrowing: an unresolvable vendor, a status the market forbids and an empty Selected tab all send a value that matches nothing rather than no parameter at all. The three text boxes each become their own search term. Joining them into one string would have searched for the concatenation and matched nothing. Paging is server-driven. AG Grid's own pager counts the rows it holds, which is now one page, so it would read '1 to 50 of 50' however many leads matched; the range and page count come from the server's COUNT over the same predicates. (AG Grid Community has no server-side row model, and the infinite model would break selection, quick filter and the realtime path for no scalability gain.) Two things the old model made safe and this one does not: - A realtime event for a row not on the page used to be prepended, and the filter memo dropped it if it did not match. With one server-filtered page there is nothing left to make that judgement, so it refetches instead — debounced, so an import firing hundreds collapses into one request. - fetch does not cancel on unmount, so a grid request kept running (and kept auditing) after the member had already clicked into a lead, which is what the detail page then queued behind. Every superseded request is now aborted. onConnected no longer reloads per connect event. A flapping socket fired one full load per flap; that is what stacked four whole-organisation loads back to back into 93 seconds of continuous audit writes.