| name | mtp-react-query-optimistic | ||
|---|---|---|---|
| description | All mutating UI actions in mtp-web go through TanStack Query useMutation with onMutate/onError/onSettled. No local state overrides on top of query data. | ||
| metadata |
|
Every UI action that mutates server state in mtp-web goes through a TanStack Query useMutation hook with proper optimistic-update primitives:
onMutate— snapshot existing cache (queryClient.getQueryData(key)), apply optimistic update viasetQueryData. Return the snapshot incontext.onError(err, vars, ctx)— restore the snapshot fromctx.onSettled—invalidateQueries({ queryKey })to reconcile with the server.
Why: The user asked on 2026-05-28 whether we were using react-query optimistic updates. Answer was no — Adjustments used a local Record<string, AdjStatus> state override on top of the query result. That works for the mock layer but doesn't give automatic rollback on error, doesn't reconcile cleanly with the live API, and bloats the page component. The [[mtp-mws-to-real-api-breeze]] criterion requires the live swap to touch only the network layer.
How to apply:
- Every mutating action button (Submit, Post, Cancel, Reverse, Approve, Reconcile, Match, Bulk-*, etc.) is wired through a mutation hook, not a setState in the page.
- Mock handlers return realistic responses (success with optional payload, occasional 4xx for testing rollback).
- Cache keys come from the typed
financeKeysfactory; mutations invalidate the relevant infinite-query key by spreading the key constant. - No
statusOverrides/ local override maps in pages — if you see one, refactor it touseMutation. - The mutation hook lives next to the read hook in the same
data/<feature>.ts. - For optimistic updates against infinite queries:
setQueryDatawalkspages[].rows[]to mutate the matching row.