- npm run typecheck failed on the 0-arg vi.fn<() => void>() because
mock.calls[0] became an empty tuple, so calls[0][2] (the URL arg)
was typed as undefined.
- Constrain the mock to the real (state, unused, url?) signature so
mock.calls[0] is a 3-tuple and [2] is string-or-URL-or-null. Drops
the as-string cast at every callsite.
- readClaimId: URLSearchParams.get returns '' for ?claim=, not null.
Normalize to null so the contract matches the JSDoc and consumers
can treat empty as absent.
- Tests: regression for ?claim= → null; open/close preserves other
query params (?foo=bar survives open/close unchanged).
- Tighten pushStateMock/replaceStateMock typing to vi.fn<() => void>()
per code-review nit (drops the verbose ReturnType<typeof vi.fn>).
The previous static key={c.id} let React reuse the same <TableRow>
element across refetches, so animate-row-flash only played on
initial mount and on the first render of a brand-new claim_id.
Updated rows whose claim_id was unchanged never re-flashed.
Re-keying on `${c.id}-${dataUpdatedAt}` re-mounts the row on
every refetch (initial load, filter change, parse invalidation),
so the 1.2s accent-tint flash replays each time.
Also: README's 'Frontend unit tests (when added)' is stale — npm
test now exists and runs 3 passing tests.
hooks: add dataUpdatedAt: 0 to the !isConfigured fallback return
so the pages type-check.