albrand
dfd248cfcb
feat(uplifts): expose queue closed flag, attachments, decider, pending exposure (SH-207, SH-208)
...
The approvals queue frontend needs four list-contract additions the read
contract PRs do not carry yet: workOrderClosed so the Approved tab can
disable Revoke on terminal work orders (mirroring the SH-196 revoke
guard), attachmentCount from non-deleted UpliftEvidence documents so the
+N chip renders, decidedByName for the Approved By column, and the
queue-wide pendingExposureTotal for the header total.
2026-09-16 22:48:47 -03:00
Alexandre Brandizzi
d366f319e9
feat(uplifts): add approval decision actions (SH-210)
2026-09-16 20:11:26 -03:00
Alexandre Brandizzi
3cb1e3e3f3
feat(uplifts): add approval queue read contract (SH-207)
2026-09-16 20:03:35 -03:00
Alexandre Brandizzi
3047c2ba59
Merge branch 'dev' into feat/ab/sh-278-vendor-area
2026-09-16 17:00:27 -03:00
Alexandre Brandizzi
4b772c8db3
fix(work-orders): keep SH placeholder WO numbers and block downgrades ( #123 )
...
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
SH-320: the WO number normalizer stripped every non-digit, so a manually
entered SH placeholder (e.g. SH00001) was saved as 00000000001 on both
create and patch. Keep the SH prefix, and reject replacing a saved real
APM number with an SH placeholder.
2026-09-16 15:01:10 -03:00
Alexandre Brandizzi
caba84ea08
fix(work-orders): reject forged automatic lifecycle statuses on board patch (SH-357, SH-358) ( #120 )
...
Incomplete and Scheduled are derived by the server. A direct lifecycleStatus
PATCH may only restate the status derivation already produced; any other
request to move a work order into an automatic state returns the stable
AutomaticLifecycleStatus validation error and leaves status and audit untouched.
2026-09-16 14:41:23 -03:00
Alexandre Brandizzi
8515676f4d
feat(vendors): add admin-assigned vendor company Area
...
Seed an organization-wide Area catalogue (East, Central, West, California)
with stable ids, add a nullable AreaId to VendorCompany, allow only Admins
to change it through the roster endpoints, expose areas facet metadata and
an areas[n] company-directory filter with the __unassigned__ sentinel.
2026-09-16 11:34:45 -03:00
Alexandre Brandizzi
4872fe5ba1
feat(locations): manage ordered site contacts
2026-09-15 19:03:54 -03:00
Alexandre Brandizzi
802b7a414e
SH-338: filter unscheduled work orders before pagination ( #116 )
...
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
* fix(work-orders): filter unscheduled search server-side
* fix(work-orders): preserve unscheduled status scope
2026-09-15 16:46:40 -03:00
Alexandre Brandizzi
1a6edd255a
feat(locations): filter sites by state ( #117 )
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
2026-09-15 16:32:30 -03:00
Alexandre Brandizzi
67089c2135
SH-281: group vendor directory by company ( #115 )
...
* feat(vendors): group directory by company
* style(vendors): format company directory query
* fix(vendors): preserve technician list contract
2026-09-15 16:02:44 -03:00
Arthur Bassi
e0139d4601
feat(work-orders): capture Site/Vendor/POC snapshot on Completed
...
Freeze effective live values on first Completed transition and project them on GET.
2026-09-10 15:46:25 -03:00
Arthur Bassi
1e37fb486c
Merge remote-tracking branch 'origin/dev' into feat/SH-186-status-auto-derivation
2026-09-09 17:34:00 -03:00
Arthur Bassi
3454125d2d
fix(work-orders): address document review feedback
2026-09-09 17:09:26 -03:00
Arthur Bassi
cd34a23e78
Merge remote-tracking branch 'origin/dev' into feat/SH-186-status-auto-derivation
2026-09-09 10:24:15 -03:00
Arthur Bassi
8b4aec300f
feat(work-orders): re-derive lifecycle when board status is patched
...
Scheduled still requires a concrete date, and Incomplete/Pending with a date must promote even when only lifecycleStatus is sent.
2026-09-09 10:23:22 -03:00
Arthur Bassi
a0fdd19934
fix(work-orders): accept image/jpg MIME and expose board MediaCount ( #107 )
...
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions
Co-authored-by: Alexandre Brandizzi <alex_brandizzi@hotmail.com>
2026-09-09 00:10:52 +00:00
Arthur Bassi
f3f9ac1b58
feat(work-orders): derive lifecycle on board create and schedule PATCH
2026-09-08 16:23:13 -03:00
Arthur Bassi
b4f2c8b763
feat(work-orders): authorize WO media content reads
2026-09-08 11:19:41 -03:00
Arthur Bassi
9a0d3fb74c
fix(work-orders): copy persisted severity onto GET detail
...
EOF
2026-09-07 12:02:23 -03:00
Arthur Bassi
7a0b91bcd6
feat(work-orders): persist board severity on create, patch, and search
2026-09-07 11:46:13 -03:00
Arthur Bassi
b7df5ef629
feat(work-orders): persist board create lifecycleStatus from the client
2026-09-03 13:36:22 -03:00
Arthur Bassi
f15dde8b30
Merge branch 'fix/sh-296-vendor-invalid-dispatch' of https://github.com/Sea-Haven-Industries/shoc-backend into fix/sh-296-vendor-invalid-dispatch
2026-09-01 09:43:14 -03:00
Arthur Bassi
03c069d10d
fix(work-orders): detach shared dispatch on vendor fork
...
Keep same-vendor saves idempotent and drop stale DispatchWorkOrders so listing and uplift follow the new primary.
2026-09-01 09:42:41 -03:00
Arthur Bassi
af27186527
Merge branch 'dev' into fix/sh-296-vendor-invalid-dispatch
2026-09-01 09:35:00 -03:00
Arthur Bassi
ca0404272e
fix(work-orders): accept linked primary dispatch on vendor board patch
...
Vendor PATCH treated a GET-echoed id as foreign when belong-check used only WorkOrderId.
2026-08-31 15:48:33 -03:00
Arthur Bassi
dcb757b404
fix(work-orders): persist empty apptTime as null scheduled instants
...
EOF
2026-08-31 10:49:54 -03:00
Alexandre Brandizzi
31a4af7da3
fix: omit unmapped sites from work order options ( #89 )
Validate and deploy dev / Validate deployable source bundle (push) Waiting to run
Validate and deploy dev / Deploy shoc-backend to Elastic Beanstalk dev (push) Blocked by required conditions
2026-08-26 16:39:25 -04:00
Arthur Bassi
0f2e0dacc7
fix(locations): authorize location owner on every board update
...
Reject account-scoped updates of foreign or orphan locations even when accountId is omitted, matching fail-closed tenant scope.
2026-08-26 14:38:34 -03:00
Arthur Bassi
2718fdd294
fix(locations): gate account assignment by scope and active accounts
...
Reject soft-deleted accounts and stop account-scoped callers from assigning or stealing locations across tenants.
2026-08-26 14:16:59 -03:00
Arthur Bassi
2be36d4eac
feat(locations): persist accountId on create and update
...
Allow location CRUD to stamp Locations.AccountId after account existence checks so board create can resolve tenant scope.
2026-08-26 14:03:12 -03:00
Arthur Bassi
2e56ec7678
fix(work-orders): keep location account server-owned and forward create cancellation
...
Stop client writes from changing Locations.AccountId, make the SH-221 migration discoverable, and thread the board-create CancellationToken through lookup and persistence.
2026-08-26 10:00:02 -03:00
Arthur Bassi
61923b2a7d
feat(work-orders): stamp board create account from location
...
Org-wide create no longer depends on customer name. POST /workorders/board requires locationId and stamps WorkOrder.AccountId from Location.AccountId.
2026-08-26 09:12:48 -03:00
Alexandre Brandizzi
5857f8483a
fix(vendors): complete directory contact fallbacks ( #86 )
...
Validate and deploy dev / Validate deployable source bundle (push) Waiting to run
Validate and deploy dev / Deploy shoc-backend to Elastic Beanstalk dev (push) Blocked by required conditions
* fix(vendors): complete directory contact fallbacks
* fix(vendors): normalize location labels
* fix(vendors): keep company location authoritative
2026-08-25 19:33:47 -04:00
Arthur Bassi
14b85c64a8
Merge branch 'dev' into feat/sh-117-aveta-required
2026-08-25 17:19:30 -03:00
Arthur Bassi
7c7c6bc525
feat(work-orders): persist Aveta Extra Docs media category
...
Round-trip category 5 on media POST/PATCH/GET and project hasAvetaDocument so pending vs attached survives reopen.
2026-08-25 15:10:45 -03:00
Arthur Bassi
04958e6121
fix(work-orders): keep GET /board to scheduled-in-week rows only (SH-165)
2026-08-24 18:29:18 -03:00
Arthur Bassi
15315edf08
feat(work-orders): persist avetaRequired on board create, patch, and search
...
Expose avetaRequired and originalDate on list rows so the frontend can round-trip the Aveta checkbox and Reschedule hover.
2026-08-24 15:14:31 -03:00
Arthur Bassi
4b8a08fb10
fix(work-orders): block comment creation on canceled work orders
2026-08-24 09:59:13 -03:00
Arthur Bassi
f47264ec4d
feat(work-orders): allow selective mutations on completed work orders
...
Permit flagColor, comments, and Extra media after completion while keeping Canceled fully locked.
2026-08-24 09:31:30 -03:00
Alexandre Brandizzi
518d856334
fix(vendors): enforce notes length limit
2026-08-20 18:17:48 -03:00
Arthur Bassi
c9c4d74194
Merge branch 'dev' into fix/sh-183-vendor-patch-new-dispatch
2026-08-20 15:28:16 -03:00
Arthur Bassi
14443aff18
fix(work-orders): audit and lock vendor when replacing an inactive primary
...
Creating a Pending dispatch now stages VendorId FieldChanged from the previous
assignment so field lock and concurrency checks run like a live vendor PATCH.
2026-08-20 15:09:34 -03:00
Arthur Bassi
af593fe2d2
fix(work-orders): create a new dispatch when patching vendor on an inactive primary
...
Cancelled, Canceled, and Refused primaries are not live company assignments.
VendorId PATCH now inserts a Pending dispatch instead of mutating the refused row.
2026-08-20 14:47:04 -03:00
Alexandre Brandizzi
d16afe3e0b
fix(work-orders): enforce provisional WO numbers (SH-252)
2026-08-20 14:34:08 -03:00
Arthur Bassi
743841d93e
fix(work-orders): map primary dispatch status on detail (SH-183)
2026-08-20 13:41:42 -03:00
Arthur Bassi
75d337df0f
fix(work-orders): omit inactive primary vendor from board rows (SH-183)
...
Do not project VendorId/VendorName for Cancelled, Canceled, or Refused primary dispatches, and expose PrimaryDispatchStatus on the board DTO.
2026-08-20 13:22:12 -03:00
Alexandre Brandizzi
6fffc1b591
Merge branch 'dev' into feat/sh-254-be-confirm-deactivation
2026-08-20 10:58:23 -03:00
Alexandre Brandizzi
6c16ce7047
feat(vendors): record deactivations confirmed past open work orders
...
SH-44's user story is about not silently orphaning active work. The
confirmation dialog tells the operator, but nothing told the system, so
a deactivation that left work orders open was indistinguishable from one
that had none.
VendorService now takes an ILogger and writes a warning naming the
vendor, the user and the number of work orders left open whenever the
guard is cleared by confirmation. Both the update and delete paths are
covered; nothing is logged when there was nothing to leave open.
2026-08-19 13:48:30 -03:00
Alexandre Brandizzi
7a0856ddf7
feat(vendors): confirm-to-deactivate with open work orders (SH-254)
...
SH-44 and SH-82 both left "blocks, or requires explicit confirmation" to
be decided with the team, and the implementation took the blocking
branch. SH-254 settles it the other way: the approved design offers
"Deactivate anyway" beside the list of open work orders.
Deactivation with open work orders is now permitted, but only when the
caller says it has shown them: ConfirmOpenWorkOrders on the update DTO
and a confirmOpenWorkOrders query parameter on the delete route. Absent
the flag the existing guard still throws, so nothing deactivates by
accident and no caller loses the check by omission.
confirmOpenWorkOrders is a required parameter on DeleteVendorAsync
rather than an optional one, so every call site states its intent.
2026-08-19 13:31:16 -03:00