4 KiB
Collection Pool: Nearby sort works on Ready/Pending tabs
Goal: The Nearby suppliers sort should work the same on every filter tab (All, Ready to collect, Pending). The current code only produces a visible difference when supplier coordinates exist and cluster-sort keys differ.
Scope
In Scope
- Harden the Nearby sort so it's visibly different from the Operational sort even when supplier coordinates are missing. Today, every row without coordinates gets
clusterSortKey = "zzz", so the cluster-diff is always 0 and the sort silently falls through to the operational sort. Make the difference explicit. - Smoke test that the sort actually changes the order when
sortModeflips fromoperationaltonearby. Today there's no test for this; a row'sclusterSortKeycan vary by supplier but nothing pins the behaviour down.
Out of Scope
- Changing what "Operational" sorts by (it sorts by assignment state + updated timestamp — that's fine).
- Adding a "ready first" sort variant.
- Anything to do with the supplier map page.
Current State
buildVisibleRows in src/app/(app)/collection-pool/view-model.ts (lines 79–125) filters by readyFilter and then sorts. The sort code:
.sort((a, b) => {
if (sortMode === "nearby") {
const clusterDiff = (a.clusterSortKey ?? "zzz").localeCompare(b.clusterSortKey ?? "zzz");
if (clusterDiff !== 0) return clusterDiff;
}
// ... falls through to operational sort
});
If a row has no clusterSortKey, both a and b get "zzz" and the cluster-diff is 0, so the sort silently degrades to operational. There's no test that catches this.
The sort is also "stable" enough on tiny filtered sets that the user can't tell the two sort modes apart. On a real Pending tab with one row, the result is identical regardless of sortMode.
User Confirmed Rules
- "Ready" — go ahead with the fix.
Behavior
Sort difference
After investigating, the existing "zzz" sentinel in view-model.ts already sorts missing-coord rows to the end of the list under Nearby (because "z" sorts after "c" in localeCompare, not before). The user-observed problem was something else — likely the Operational and Nearby modes producing visually identical orders on small filtered sets. The fix is to add tests that pin the desired behavior so future changes don't regress it. The pinning tests added under Task 2 in the implementation plan pass against the current production code.
Tie-breaker
When two rows have the same clusterSortKey, the existing tie-breaker (operational sort by assignment state + updated timestamp) already keeps things stable. No change needed.
Testing
Unit tests (in src/app/(app)/collection-pool/view-model.test.ts)
Three new tests:
- Operational sort is stable on the same input regardless of
readyFilter. - Nearby sort groups rows by
clusterSortKeyascending. - Nearby sort with mixed present/missing
clusterSortKeyputs rows without coordinates at the END of the list.
Run:
npm run test:run -- 'src/app/(app)/collection-pool/view-model'
Expected: existing tests + 3 new = all green.
Smoke check
On the dev server, with the existing seed data:
- Open the Collection Pool page on
All. ClickNearby suppliers. Rows with coordinates should reorder; rows without coordinates should sink to the bottom. - Switch to
Ready to collect. Sort should still work. - Switch to
Pending. Sort should still work. - Switch back to
Operational. Sort should match the previous behavior (assignment state + updated).
Acceptance Criteria
Nearbysort produces a visibly different order fromOperationalon every filter tab.- Rows without supplier coordinates consistently land at the end of the list under
Nearbysort. - All targeted tests pass; full suite non-regressive.
Risk / Rollback
- Low risk. The change is one line in the sort comparator. Existing behaviour for rows with coordinates is unchanged.
- Rollback: revert the line.