Arthur Bassi
31d4352a23
fix(work-orders): accept a scanned uplift evidence file (SH-388)
...
Dispatchers can attach one evidence file, and create links it only
after that document has passed scanning.
2026-09-24 14:34:07 -03:00
Arthur Bassi
073d4df963
Merge branch 'dev' into feat/SH-191-completion-freeze
2026-09-14 09:47:22 -03:00
Arthur Bassi
deeb29b512
fix(work-orders): allow Complete without a linked site
...
Snapshot whatever Site/Vendor/POC data exists instead of gating completion on Locations.
2026-09-10 17:56:00 -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
Alexandre Brandizzi
af6faf77e3
Merge branch 'dev' into fix/SH-337-completion-doc-allowlist
2026-09-10 14:38:06 -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
Alexandre Brandizzi
7e4db749d0
fix(work-orders): enforce a file allowlist on completion-doc upload (SH-337)
...
The completion-document endpoint persisted whatever file it received: the
only checks were non-null, non-empty, and a 30 MB request limit. Its sibling
media endpoint has enforced a MIME allowlist, MIME-to-extension pairing, and
a magic-byte signature check since SH-116.
Validate before the file reaches storage, so a rejected upload leaves nothing
behind. An undetermined content type is accepted only alongside a .pdf name
and a %PDF- signature, because the browser leaves File.type empty when the OS
cannot classify the file and the completion-doc dialog already allows that.
2026-09-08 21:24:10 -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
ae9122243d
feat(work-orders): run schedule status side-effects on board field mutations
2026-09-08 16:22:11 -03:00
Arthur Bassi
e12b3ea54b
feat(work-orders): apply schedule lifecycle promote and demote
2026-09-08 16:21:14 -03:00
Arthur Bassi
335390f746
feat(work-orders): derive Scheduled from date without assignee
2026-09-08 16:19:50 -03:00
Arthur Bassi
b4f2c8b763
feat(work-orders): authorize WO media content reads
2026-09-08 11:19:41 -03:00
Arthur Bassi
bb651bb547
feat(work-orders): add file storage OpenRead port
2026-09-08 11:08:26 -03:00
Arthur Bassi
47022c7761
feat(work-orders): allow Extra Docs PDF/DOC by category
2026-09-08 11:02:40 -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
aa2c571d1e
docs(work-orders): drop ticket key from primary dispatch status comment
2026-08-20 13:43:42 -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