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.
React Query keeps the last successful data after a failed refetch, so an
earlier true kept the entry visible. Require a non-error query per tier,
and cover the real query path with a mocked API.
Uplift Approvals appears in a new APPROVALS group only when GET
uplifts/can-approve is true for tier 1 or tier 2, the same rule the
approve/reject API enforces. Services is linked from a DATA MANAGEMENT
group for every user. Both entries highlight on their routes.
The completed-date cell editor had no Clear control. It now offers Clear
when a date is set and the row is editable, patching completedDate to an
empty value, which the board PATCH persists as null. Completed and
Canceled rows stay locked, matching set/change.
TaskTemplateItemsField owns newItemText locally but stays mounted
across selectTemplate/startNewTemplate (which only call form.reset()),
so a typed draft survived switching templates - the base page cleared
this draft explicitly in both handleSelect and handleNew.
Remount TaskTemplateItemsField on selection change via key={selectedId}
instead of lifting the draft into the editor hook: it's transient
input-only state, not form data, so this keeps the fix local and lets
React's own remount semantics reset it. Confirmed the two new
regression tests fail without the key and pass with it.
The org PR template pre-filled Summary / Validation / Tests / Notes here while
PRs in this repository use Summary / Changes and value / Ticket. A repo template
now overrides the org one, and the review framework gains the description
contract plus a note on the divergence from the org pr-policy workflow, which
is not wired in.
README: the CI badge tracked the retired dev branch; branches come from main,
not dev; the fix/ prefix replaces bug/; staging exists alongside dev; and PRs
now merge through the merge queue.
Cleanup: four PR description drafts under tmp/ were tracked; they are removed
and /tmp/ is ignored.
governance and Build and test are the required checks on main. A merge queue
only counts checks that ran on the merge_group event, so the workflow now
triggers on it. The governance gate reads the merge group's own base SHA
because github.event.before is empty there.
The org window (before 6am on Monday) has produced only one security PR in
this repository since the overlay landed, so the overlay now opens every
weekday morning. The github-actions manager is enabled so the digest-pinned
actions in the workflows follow the org's pinning and grouping rules. A regex
manager tracks the actionlint release installed by the governance job; it is
held for dashboard approval because the SHA256 pin next to it has to be
updated by hand.