Commit graph

103 commits

Author SHA1 Message Date
Arthur Bassi
244a489fb2 fix(tests): create ephemeral LocalDB database before migration apply 2026-08-26 10:20:14 -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
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
f17f8562e8 test(work-orders): cover unassigned inline board and global search 2026-08-25 11:15:35 -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
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
0b246724d9 fix: align vendor trades with confirmed taxonomy 2026-08-20 11:44:07 -03:00
arthur.bassi
2222d04fcb Merge remote-tracking branch 'origin/dev' into feature/sh-218-additional-contacts 2026-08-18 20:52:34 -03:00
Alexandre Brandizzi
5386d6129d
Merge branch 'dev' into feature/sh-196-wo-uplifts 2026-08-18 17:46:38 -03:00
Alexandre Brandizzi
d843ac221d
Merge branch 'dev' into feature/sh-218-additional-contacts 2026-08-18 17:46:36 -03:00
arthur.bassi
8c44fa746e merge origin/feature/sh-196-wo-uplifts 2026-08-18 17:44:40 -03:00
Alexandre Brandizzi
2327097d5e fix(work-orders): symmetric NTE release, terminal guard, serialized cancel (SH-196)
Three contract gaps found reviewing the frontend consumer:

- Revoking an auto-approved uplift never restored the dispatch NTE. Create
  raises NTE for both auto-approved and approved requests, but revoke restored
  it only for Approved, so the allowance was freed while the NTE stayed raised
  and every create -> auto-approve -> revoke cycle compounded the inflation.
  Revoke now compensates for NoApprovalRequired symmetrically.
- Revoke and cancel had no work-order lifecycle check, so a direct API call
  could still mutate uplifts on a Completed or Canceled work order; the board
  dialog's read-only state is UX only. Both now reject terminal work orders in
  the service.
- WorkOrderBoardCancelService read the pending-uplift list outside any gate, so
  an in-flight create could commit after that read and leave a pending uplift on
  a Canceled work order. The cancel flow now runs inside the same per-work-order
  gate as create, so the pending read, withdrawal and status audit serialize
  against it.
2026-08-18 17:41:14 -03:00
arthur.bassi
5ea5a1d702 fix(work-orders): restore NTE on auto-approved revoke and serialize cancel 2026-08-18 17:39:11 -03:00
Alexandre Brandizzi
577b7add31 feat(vendors): server-owned canonical trades vocabulary for SH-249 2026-08-18 12:11:13 -03:00
Arthur Bassi
92a3b3f045 chore(work-orders): merge origin/dev into SH-218 additional contacts
Keep IsAddOn create tests from dev alongside additional-contacts coverage.
2026-08-18 11:53:26 -03:00
arthur.bassi
aeface594a fix(work-orders): serialize uplift create and atomic cancel (SH-196) 2026-08-18 10:20:05 -03:00
Arthur Bassi
3609365939 fix(work-orders): map additionalContacts on detail GET (SH-218)
Copy contacts into MapInfo so slide-over round-trips create/PATCH, and require name plus phone on retained entries while dropping blank placeholders.
2026-08-18 10:03:12 -03:00
Arthur Bassi
4760f3fdd7 fix(work-orders): name Schedule On in PastDueStatusBlocked and register SH-121 no-op
The 422 still told dispatchers to update Due Date. Point the remedy at Schedule On and make the SH-121 successor visible to EF so G6 lineage is complete.
2026-08-18 09:19:27 -03:00
Arthur Bassi
c9a80f5c79 fix(work-orders): restore SH-185 Schedule On Past Due and assert IsAddOn audit
Past Due follows ScheduledDate so Due Date alone cannot set or clear it. Auto-schedule and reschedule tests now expect the third IsAddOn audit field.
2026-08-17 10:36:03 -03:00
Arthur Bassi
fa05b22df6 chore(work-orders): merge SH-121 facets and keep SH-184 IsAddOn migration 2026-08-17 10:28:03 -03:00
arthur.bassi
4c15669aff fix(work-orders): enforce SH-196 cumulative allowance and one pending per WO
Auto-approval now uses the WO-scoped $500/$5,000 Emergency cap instead of dispatch NTE, rejects a second open request across dispatches, and cancelling a WO withdraws pending uplifts with audit.
2026-08-14 10:36:35 -03:00
Arthur Bassi
17c2e968cd feat(work-orders): board search facets for SH-121/SH-196 2026-08-13 16:34:21 -03:00
Arthur Bassi
36ef0b00f5 feat(work-orders): persist additionalContacts on create, board GET and PATCH (SH-218)
Add JSON column, DTO/mapper, create + PATCH field, board projection, FluentValidation,
and regression tests for additional POC contacts round-trip.
2026-08-13 16:11:36 -03:00
arthur.bassi
b81cfbb005 feat(work-orders): WO-scoped uplift endpoints and board summary (SH-196)
Expose workorders/{id}/uplifts list/create/cancel/revoke for the SH-196 dialog, aggregate upliftSummary on board rows, and add service/controller regression tests.
2026-08-13 14:49:56 -03:00
arthur.bassi
1283bf7349 fix(tests): align IsAddOn board tests with account-scoped dev APIs
Pass ClaimsPrincipal and account resolver args required after rebase onto dev.
2026-08-13 13:45:25 -03:00
Arthur Bassi
97e042f552 feat(work-orders): persist IsAddOn frozen at create (SH-126)
Add set-once IsAddOn with server cutoff at create, board DTO exposure, legacy type-7 backfill, and Types=AddOn search compat. Aligns with FE PR #61 frozen contract.
2026-08-13 13:30:09 -03:00
Arthur Bassi
f7ce2ee25d fix(work-orders): align Overdue type rejection test with dueDate message 2026-08-13 13:28:25 -03:00
Arthur Bassi
05dd262e80 fix(work-orders): derive Past Due from DueDate instead of ScheduledDate
Past Due must track the deadline (Due Date), not Schedule On. Keep dueDate and scheduledDate PATCH mutations independent so rescheduling alone does not clear Past Due.
2026-08-13 13:28:25 -03:00
Arthur Bassi
29dec00790 fix(work-orders): keep pendingUpliftCount on detail and exclude deleted dispatches
Map board PendingUpliftCount through WorkOrderDetailService.MapInfo and ignore soft-deleted dispatches in the aggregate so SH-188 gating is authoritative for board/search/detail.
2026-08-12 11:50:56 -03:00
Arthur Bassi
aaeeb90f1a feat(work-orders): expose pendingUpliftCount on board rows (SH-188)
Aggregate Pending uplift requests across all dispatches tied to a work
order so the board/search/detail contract can drive the Completed gate.
2026-08-12 09:43:10 -03:00
Arthur Bassi
de0f6da8fb fix(work-orders): scope legacy GET GetComments by account [SH-221]
Pass ClaimsPrincipal into GetCommentsAsync and filter via
GetAllForAccountAsync so account-scoped callers cannot enumerate
cross-tenant comments. ADR + cross-account tests updated.
2026-08-11 15:18:29 -03:00
Arthur Bassi
3c090e2757 fix(work-orders): scope comments and completion-doc by account [SH-221]
Close the remaining SH-221 bypass: board/legacy comments and completion-doc now enforce server-derived account scope, authorize before blob storage, and cover cross-account regressions.
2026-08-11 14:52:02 -03:00
Arthur Bassi
62a4828e2f fix(work-orders): scope legacy list/detail GETs by account [SH-221]
Close the remaining SH-221 read gap so Getworkorders, filtered lists, and GetWorkorderById enforce the same server-derived account boundary as board/media.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 11:57:37 -03:00
Arthur Bassi
bca2e0d50d test(work-orders): fix sync/webhook/recon fixtures for AccountId stamp [SH-221]
Seed resolvable Customer accounts and mock account resolution so create-path CI tests match fail-closed account scope.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 10:54:23 -03:00
Arthur Bassi
1edcf479ae fix(work-orders): apply account scope across create and reads [SH-221]
Stamp WorkOrder.AccountId on all create paths and filter board/list/search/detail by server-derived account claims so scoped callers cannot cross accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 10:45:37 -03:00
Arthur Bassi
ea2dedf579 !fix(work-orders): fail-closed media account scope with org_scope claim [SH-221] 2026-08-06 10:26:04 -03:00
Arthur Bassi
fdc315d8fe !feat(work-orders): enforce media account scope and AddMedia freshness [SH-221] 2026-08-06 09:47:34 -03:00
Arthur Bassi
e572786b1c ~docs(work-orders): demote ADR 0001 to Proposed pending CODEOWNERS [SH-116] 2026-08-05 09:57:14 -03:00
Arthur Bassi
8ff4ab1742 fix(work-orders): document single-org media scope (ADR 0001)
Clarify SH-116 tenant scope as board-aligned ApplyBaseScope + claims, and add out-of-org-scope GET/mutation tests for deleted/template/missing WOs.
2026-08-04 16:07:26 -03:00
Arthur Bassi
6b18327d6b fix(work-orders): authorize GET media and forward cancellation
Enforce claims-derived read scope on media list and thread CancellationToken through detail data reads so HTTP cancel stops EF work.
2026-08-04 14:14:37 -03:00