Commit graph

131 commits

Author SHA1 Message Date
Alexandre Brandizzi
f40ad7c1ef fix(uplifts): pending exposure header sums the row deltas
The approvals header summed the whole RequestedNTE for work-order-path
requests, while each Pending row shows RequestedNTE - CurrentNTE. When a
work order already had an NTE the header overstated exposure by that NTE.

The header now sums the same Delta the rows display, over the same rows
the Pending tab lists (non-deleted request on a non-deleted dispatch).
The unused duplicate aggregate is removed so one definition remains.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 02:10:41 -03:00
Alexandre Brandizzi
7b7df4463e
Merge pull request #174 from Sea-Haven-Industries/fix/ab/sh-393-uplift-scope
Some checks are pending
Backend CI / Build and test (push) Waiting to run
Backend CI / architecture (push) Waiting to run
Backend CI / review (push) Waiting to run
Backend CI / ci-complete (push) Blocked by required conditions
fix(uplifts): uplifts created from a work order show on that work order (SH-393)
2026-09-25 00:54:42 +00:00
Alexandre Brandizzi
89376e99e4 fix(uplifts): resolve work-order uplifts through owned dispatches (SH-393)
Board create left the new primary dispatch with no WorkOrderId, so uplifts
created on those work orders were written to a dispatch the work order's
uplift reads never resolve: not listed, allowance never consumed, queue WO
number blank. The same orphan made ApptDate/vendor patches fail with
"A primary dispatch is required".

- Board create backfills Dispatch.WorkOrderId after the first save.
- Uplift create resolves its dispatch through the read-side scope
  (non-deleted, owned or linked); otherwise the stable
  "no primary dispatch" error.
- Data-only migration assigns existing orphaned primaries to the single
  work order naming them primary; idempotent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 21:22:13 -03:00
Alexandre Brandizzi
3b626cca58 fix: make team member creation atomic 2026-09-23 03:35:23 -03:00
Alexandre Brandizzi
d282799127 Fix SH-387 uplift creation without primary dispatch 2026-09-22 16:44:31 -03:00
Adam Moussa
019eb86894
Merge branch 'main' into feat/ab/sh-288-event-notifications 2026-09-18 19:11:15 -04:00
Alexandre Brandizzi
e1ce3e439b
Merge pull request #149 from Sea-Haven-Industries/feat/ab/sh-292-notification-center
SH-292: Notification Center feed endpoint
2026-09-18 22:54:54 +00:00
Alexandre Brandizzi
cbecc7b4ea fix(workorders): persist manual POC override with audit and site-follow (SH-379)
Editing a work order's POC never reached the backend: no update path wrote
PocName/PocPhone/PocNotes, so the optimistic UI edit was lost on refetch and
the completion freeze captured the Site contact instead of the manual value,
and nothing was audited.

- Add tenant-scoped PATCH api/workorders/{id}/poc via new WorkOrderPocService
  + WorkOrderPocDataService: persists the override, stages FieldChanged audit
  entries (which also write field locks so sync never overwrites a manual POC),
  and enforces row-version concurrency and terminal-status read-only rules.
- Lock semantics (SH-190): a manual POC away from the Site's live contacts is
  stored WO-level; an edit equal to a live Site contact (or blanking name+phone)
  stores nothing so the WO follows the Site. PocCustomized exposes the state.
- Board projection, completion freeze and create now share one Site-contact
  fallback (first non-deleted contact by SiteContactOrder) so a never-overridden
  WO keeps following the Site, including at create when the wizard prefills it.
- Route contract baseline gains PATCH {id:int}/poc.
2026-09-18 14:30:54 -03:00
Alexandre Brandizzi
e668e13912 feat(notifications): feed assignments, comments, mentions and uplift decisions to the user they concern
Adds the personal producers behind GET /api/notifications without changing its shape:
new assignments (SH-288), unanswered comments on work the user takes part in (SH-289),
@mentions, and decisions on uplifts the user requested (SH-215).
2026-09-18 13:15:33 -03:00
Alexandre Brandizzi
da0b29f769 feat(notifications): serve the Notification Center feed grouped by reason
Adds GET /api/notifications, a per-user read model derived from live
work-order state: Unassigned (grouped, High), No Vendor and Aveta Missing
(per work order, Medium) and Vendor Conflict, account-scoped from claims
and ordered by section severity with a fixed reason tie-break.
2026-09-18 12:40:37 -03:00
Adam Moussa
b9bcaea9f3
Merge branch 'dev' into feat/ab/sh-207-uplift-queue-flags 2026-09-17 13:17:04 -04:00
Alexandre Brandizzi
bc88ef0577 Merge remote-tracking branch 'origin/dev' into feat/ab/sh-326-team-member 2026-09-17 13:49:21 -03:00
Adam Moussa
1f905fc7dd
Merge branch 'dev' into feat/ab/sh-329-account-owner 2026-09-17 12:36:26 -04:00
Alexandre Brandizzi
41957d52a7 merge: rebase queue flags onto SH-210 decisions, drop duplicated contract fields
#144 branched from the SH-210 decision-actions commit before the SH-207/SH-208
read-contract corrections landed, so it re-implemented workOrderClosed,
attachmentCount, decidedByName, and pendingExposureTotal with stale semantics:
it projected WorkerOrderNumber (the CRM external id) instead of InternalWONumber
(what the board renders) and summed raw RequestedNTE, which double-counts the new
NTE total on vendor-portal rows across sequential approvals.

Merge origin/feat/ab/sh-210-uplift-decisions (#141, what lands) in and resolve
every conflict in #141's favour, so those fields and their granted-amount
exposure math now come from #141 rather than being duplicated here. Keep only the
two deltas #144 actually adds on top of #141:

- attachmentCount counts non-deleted UpliftEvidence documents on the dispatch,
  not every completion document, so completion photos no longer inflate the chip;
- the queue read resolves the effective work order via the primary-plus-linked
  (DispatchWorkOrders) convention the sibling reads use, so a dispatch linked only
  through that table surfaces its WO context, closed flag, and exposure. Covered
  by an in-memory test and a SQLite relational test that proves the fallback
  translates to SQL.

Drop the superseded attachment-count test that asserted completion documents
count, and align the relational test to seed InternalWONumber.
2026-09-17 12:52:13 -03:00
Alexandre Brandizzi
679822733a
Merge branch 'dev' into feat/ab/sh-210-uplift-decisions 2026-09-17 12:44:12 -03:00
Alexandre Brandizzi
1eadb82f28
Merge branch 'dev' into feat/ab/sh-210-uplift-decisions 2026-09-17 12:30:20 -03:00
Alexandre Brandizzi
5c93e4ecec Merge remote-tracking branch 'origin/dev' into feat/ab/sh-348-region-filter
# Conflicts:
#	SeaHaven.Services/Helpers/DashboardRegions.cs
2026-09-17 02:20:44 -03:00
Adam Moussa
7d728d9101
Merge branch 'dev' into feat/ab/sh-187-service-picker 2026-09-17 00:20:59 -04:00
Alexandre Brandizzi
2e983b1f6a
Merge branch 'dev' into feat/ab/sh-303-services-registry 2026-09-17 01:12:07 -03:00
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
bd98ea5629 merge: carry approval queue contract fields into decisions 2026-09-16 22:32:35 -03:00
Alexandre Brandizzi
e0e45d5ed3 feat(uplifts): expose approval queue contract fields (SH-208) 2026-09-16 22:32:23 -03:00
Alexandre Brandizzi
8acc580c5b
Merge branch 'dev' into feat/ab/sh-353-dashboard-kpis-stacked 2026-09-16 21:56:23 -03:00
Alexandre Brandizzi
b9c916cb22 feat(team-members): add member detail editing (SH-326) 2026-09-16 21:41:55 -03:00
Alexandre Brandizzi
8a00476d38 feat(team-members): support pending member creation (SH-325) 2026-09-16 21:41:55 -03:00
Alexandre Brandizzi
69798b3e86 feat(permissions): protect configured account owner (SH-329) 2026-09-16 21:40:22 -03:00
Alexandre Brandizzi
738c9eaf45 feat(work-orders): add region filtering (SH-348) 2026-09-16 21:27:05 -03:00
Adam Moussa
f6bd779fe0
Merge branch 'dev' into feat/ab/sh-353-dashboard-kpis-stacked 2026-09-16 20:00:32 -04:00
Adam Moussa
e7e196caba
Merge branch 'dev' into feat/ab/sh-329-account-owner 2026-09-16 20:00:18 -04:00
Alexandre Brandizzi
9bf45d65ff
Merge branch 'dev' into feat/ab/sh-330-sites-list 2026-09-16 20:58:16 -03:00
Alexandre Brandizzi
660ebac628 feat(locations): support site registry queries (SH-330) 2026-09-16 20:45:15 -03:00
Alexandre Brandizzi
21b7083160
Merge branch 'dev' into feat/ab/sh-328-permission-overrides 2026-09-16 20:44:20 -03:00
Alexandre Brandizzi
fed45f423e
Merge branch 'dev' into feat/ab/sh-350-dashboard-trend 2026-09-16 20:26:23 -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
7947e2e77d feat(dashboard): expose KPI counts (SH-353) 2026-09-16 19:23:53 -03:00
Alexandre Brandizzi
ca4d4833ff feat(permissions): protect configured account owner (SH-329) 2026-09-16 18:26:20 -03:00
Alexandre Brandizzi
3358ea5058 feat(dashboard): add vendor insights (SH-349) 2026-09-16 18:10:42 -03:00
Alexandre Brandizzi
d4afcced87 feat(dashboard): add regional work order metrics (SH-348) 2026-09-16 18:03:38 -03:00
Alexandre Brandizzi
33f517620b feat(work-orders): link service selections to registry 2026-09-16 18:02:57 -03:00
Alexandre Brandizzi
441735d39d feat(permissions): expose team member permission overrides (SH-328) 2026-09-16 18:02:02 -03:00
Alexandre Brandizzi
0194748e3b feat(dashboard): add dispatcher performance (SH-347) 2026-09-16 17:58:08 -03:00
Alexandre Brandizzi
9b39d0e5ec feat(dashboard): add dispatcher workload (SH-346) 2026-09-16 17:43:49 -03:00
Alexandre Brandizzi
a2e749c72d feat(dashboard): add core dashboard metrics (SH-343) 2026-09-16 17:28:21 -03:00
Alexandre Brandizzi
45f98e8154 Merge remote-tracking branch 'origin/dev' into feat/ab/sh-303-services-registry
# Conflicts:
#	Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs
2026-09-16 17:15:38 -03:00
Alexandre Brandizzi
efd13b6f60 fix(dashboard): scope stats to authenticated accounts (SH-336) 2026-09-16 17:12:03 -03:00
Alexandre Brandizzi
06f9450485 feat(services): add global services registry 2026-09-16 17:07:59 -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)
Some checks are pending
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