Keep the last saved row per work order so a queued panel save does not depend
on the board-detail cache, and pass the completion-doc row as a fallback so
saving a completion document works after the order leaves the list.
A save from the detail panel left the cached detail on the pre-save version
until its refetch settled, so a quick second save, Cancel WO or Complete could
conflict. The saved row's version now updates the detail cache before the patch
queue releases, and panel patches read their base at run time.
The board patch read the work order version from the loaded list only. Once a
save moved the order out of that list (e.g. to another week), the next save,
Cancel or Complete from the open panel failed for lack of a version. The panel
now passes its server row as the fallback patch base.
The UI dropped manual POC edits before they reached the API: the patch
mapper listed pocName/pocPhone/pocNotes as local-only keys and the
slide-over draft excluded them from Save, so the optimistic edit vanished
on refetch and the completion freeze captured the Site contact instead.
- Emit one composite POC op from table patches and route it through a new
workOrdersApi.updatePoc (PATCH workorders/{id}/poc), reusing the board
patch row/error contract (409 conflict with currentState, 422 validation).
- Include POC scalars in slide-over edit keys so dirty state and Save carry
them; site dialog and slide-over now both persist POC edits.
Generating or uploading the completion document now moves a closable work
order to Completed without the manual confirmation, as SH-115 requires. The
SH-114 closability gate is evaluated on the row the server returned after the
document save; Save draft, Not required, Past Due, Completed and Canceled rows
are never auto-completed. The follow-up status patch uses that row's
rowVersion so it does not conflict with the document save.
Scope vendor and save toasts to successful assigned-vendor and slide-over saves.
Bind patch success callbacks per operation instead of shared mutate observers.