Admins may revoke only admin-approved uplifts. The Work Order Uplifts
dialog showed Revoke to whoever requested an auto-approved uplift, so an
admin requester saw it and was sent into the optional-reason revoke flow.
Both the template preview and a work order's completion document render
through the shared frame, which now splits the letterhead and blocks into
A4-sized sheets with the brand bars on every sheet and shows Page X of Y
in the preview pill.
Overdue maps to work order type 8 on create, inline correction, board
reads and the type filter, instead of the Other enum and the past-due
flag. It lists the PM service catalog and never sends a severity. Past
Due moves to its own toggle in the advanced filter Status section and
narrows the other filters.
/workorders?ids=101,205,318 opens the board on exactly those work orders
through board/search's ids filter. The id set replaces every other
drill-down filter, a chip reads "Showing N selected work orders" and
clearing it returns to the weekly board. buildWorkOrderIdsHref builds
the link for alerts and linked-work-order lists.
Persisted HEIC files and local files with an empty or octet-stream type
were classified as "other", so they did not count toward the 10 photo /
3 video limit. Both classifiers now recognise them by extension.
The Photos & Videos uploader and Extra Docs ignore a new selection while
the previous one is still being screened, and the vendor portal drops an
earlier pick whose video check finishes after a newer pick.
Also removes ticket keys from source comments.
The review contract bars Jira keys in source comments and test names;
ticket identity lives in the PR, commit and branch. The previous commit
cleaned the source files; this strips the six (SH-391) suffixes the
branch added to test names and a test comment, keeping the behavioural
wording.
Extra Docs advertised the 90-second limit but only checked type and size.
Both dispatcher surfaces now share one screening step (type, size, count,
duration), and the Completion Doc media tab and Extra Docs count the whole
work order's photos and videos rather than only their own tab's share.
Failed local uploads no longer count toward the limit.
With no range selected, or with Unscheduled, the board search adds only
open undated work orders; completed and canceled ones without a date are
never unscheduled. The board page kept them. It now applies the same rule,
so both return the same rows.
A foreign declared type (e.g. video/3gpp on a .jpg) gave the file the video
size allowance in the browser while the server sizes it as a photo. Use the
same rule as the server: an allowlisted type decides, otherwise the extension.
A week-only row that still carries a scheduled date outside the range
passed the board search (its target week overlaps) but failed the
on-page filter, which judged it by the date alone. Both now accept a row
dated in the range or a week-only row whose target week overlaps it.
Photos up to 10 MB (JPG/PNG/HEIC), videos up to 100 MB and 90 s (MP4/MOV),
at most 10 photos and 3 videos per work order, pre-validated with stable
generic messages on the Photos & Videos modal, the Completion Doc media tab,
Extra Docs and the vendor portal. Video duration is read from metadata when
the browser can; unreadable metadata never blocks. Mobile MIME variants
(empty type, octet-stream with a video extension, QuickTime) stay accepted.
The signed completion PDF keeps its 50 MB cap.
The Advanced Filters default was This week, and that value doubled as no
range, so an explicit This week searched every week. Other ranges passed
every undated WO through on the server. No range is now its own state
(nothing selected, like the prototype; clicking a selected range clears it).
It searches every week with undated rows, via includeDateless. Any selected
range narrows strictly. The pinned Unassigned queue and the WO# duplicate
lookup keep spanning every week.
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.
Re-apply the requested slide-over tab on every open via an open counter, so a
second comment/mention notification for the work order already on screen still
switches to Comments and re-scrolls to the highlighted comment. Treat a board
comment's mentions id array (plain @Name text) as a mention alongside encoded
@[id:name] tokens so mention items highlight and comment items exclude them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
computeIsPastDue and the day view's todayKey derived today from
toISOString() (UTC). West of UTC that rolls over hours early, so work
scheduled for today showed as Past Due every evening. Both now use the
local todayIso() helper the board already uses; regression tests pin
23:30 and 00:30 in America/Sao_Paulo with fake Date.
Test stability:
- adv-search page sync: scope pagination queries with within() instead of
scanning ~330 buttons / 3000 nodes on every waitFor poll
- pm-schedules-list-actions: static import of the edit page so module
transform does not count against the 5s test budget
- vendor create modal / detail drawer: userEvent.setup({ delay: null });
15s describe budget for full MUI dialog renders under parallel load
The inline status control no longer offers the automatic Incomplete and
Scheduled states or the work order's current status. Inline create keeps its
explicit Incomplete/Pending/Scheduled creation list.
Audit Log entries now show date and time for every entry instead of a
time-only stamp for manual changes. Type and Severity entries read
'Changed Type from X to Y', a severity cleared by a type correction reads
'from SEV N to —', and the generic fallback no longer renders a raw
FieldChanged action name.
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.