Add collection pool nearby sort spec

This commit is contained in:
SJCoetz 2026-07-10 00:30:14 +02:00
parent e5285e67df
commit 8d742e5e87

View file

@ -0,0 +1,92 @@
# 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 `sortMode` flips from `operational` to `nearby`. Today there's no test for this; a row's `clusterSortKey` can 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:
```ts
.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
Even when supplier coordinates are absent, the two sort modes should be *visibly different* in the row order. The fix: when the user picks `Nearby` and a row has no `clusterSortKey`, demote the row to the END of the list (rather than the start, where `"zzz"` currently sorts it). This way:
- Rows with coordinates group by cluster at the top (the existing behavior).
- Rows without coordinates go to the bottom in a single "no coordinates" tail.
- Operational sort stays exactly the same.
The smallest change: when `sortMode === "nearby"` and a row's `clusterSortKey` is missing, treat its sort key as `"\uffff"` (a character that sorts after all printable text). Rows with coordinates bubble to the top; rows without sink to the bottom. The `localeCompare` order is deterministic.
### 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:
1. **Operational sort** is stable on the same input regardless of `readyFilter`.
2. **Nearby sort** groups rows by `clusterSortKey` ascending.
3. **Nearby sort** with mixed present/missing `clusterSortKey` puts rows without coordinates at the END of the list.
Run:
```bash
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:
1. Open the Collection Pool page on `All`. Click `Nearby suppliers`. Rows with coordinates should reorder; rows without coordinates should sink to the bottom.
2. Switch to `Ready to collect`. Sort should still work.
3. Switch to `Pending`. Sort should still work.
4. Switch back to `Operational`. Sort should match the previous behavior (assignment state + updated).
## Acceptance Criteria
- `Nearby` sort produces a visibly different order from `Operational` on every filter tab.
- Rows without supplier coordinates consistently land at the end of the list under `Nearby` sort.
- 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.