Commit graph

466 commits

Author SHA1 Message Date
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
Alexandre Brandizzi
782165a4cf
Merge pull request #133 from Sea-Haven-Industries/feat/ab/sh-348-dashboard-region
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
SH-348: Add dashboard region metrics
2026-09-17 01:36:09 -03:00
Alexandre Brandizzi
7e06d1c51b
Merge branch 'dev' into feat/ab/sh-348-dashboard-region 2026-09-17 01:30:08 -03:00
Alexandre Brandizzi
e07f04a6af
Merge pull request #131 from Sea-Haven-Industries/feat/ab/sh-187-service-picker
SH-187: Connect work-order service selection to the registry
2026-09-17 01:28:09 -03:00
Alexandre Brandizzi
b10956d731
Merge branch 'dev' into feat/ab/sh-348-dashboard-region 2026-09-17 01:24:07 -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
da80595321
Merge pull request #125 from Sea-Haven-Industries/feat/ab/sh-303-services-registry
SH-303: Add the global Services registry API
2026-09-17 01:20:08 -03:00
Alexandre Brandizzi
2e983b1f6a
Merge branch 'dev' into feat/ab/sh-303-services-registry 2026-09-17 01:12:07 -03:00
Alexandre Brandizzi
65b04687bc fix(work-orders): honor edited service labels 2026-09-16 22:30:32 -03:00
Alexandre Brandizzi
b3e9a2eec3 fix(services): allow admins to reactivate services 2026-09-16 22:30:32 -03:00
Alexandre Brandizzi
162bb4d80e merge: reconcile dashboard review updates 2026-09-16 22:24:20 -03:00
Alexandre Brandizzi
dab39e78be Merge remote-tracking branch 'origin/dev' into feat/ab/sh-348-dashboard-region 2026-09-16 22:06:49 -03:00
Alexandre Brandizzi
6edcd2a463
Merge pull request #138 from Sea-Haven-Industries/feat/ab/sh-353-dashboard-kpis-stacked
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
SH-353: Expose dashboard KPI counts
2026-09-16 22:02:17 -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
a3a4ddde2a
Merge pull request #143 from Sea-Haven-Industries/feat/ab/sh-330-sites-list
SH-330: support site registry queries
2026-09-16 21:54:24 -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
Alexandre Brandizzi
9bf45d65ff
Merge branch 'dev' into feat/ab/sh-330-sites-list 2026-09-16 20:58:16 -03:00
Alexandre Brandizzi
db9a94f335
Merge pull request #132 from Sea-Haven-Industries/feat/ab/sh-328-permission-overrides
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
SH-328: expose per-person permission overrides
2026-09-16 20:52: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
1c0865ae15
Merge pull request #136 from Sea-Haven-Industries/feat/ab/sh-350-dashboard-trend
SH-350: Add dashboard trend metrics
2026-09-16 20:42:14 -03:00
Alexandre Brandizzi
63bda30595
Merge branch 'dev' into feat/ab/sh-328-permission-overrides 2026-09-16 20:36:19 -03:00
Alexandre Brandizzi
c605ceefae
Merge branch 'dev' into feat/ab/sh-348-dashboard-region 2026-09-16 20:36:16 -03:00
Alexandre Brandizzi
0bda64efc4
Merge branch 'dev' into feat/ab/sh-350-dashboard-trend 2026-09-16 20:36:14 -03:00
Alexandre Brandizzi
452d666547
Merge pull request #142 from Sea-Haven-Industries/fix/ab/sh-374-getworkorderbyid-binding
SH-374: return the work order from GetWorkorderById?id=
2026-09-16 20:34:16 -03:00
Alexandre Brandizzi
af441894d7 fix(permissions): clean up overrides on user delete and converge concurrent override writes (SH-328)
DeleteUserWithCascadeAsync never removed UserPermissionOverrides rows, and
the FK on UserId is Restrict. Once an override was saved for a member, the
admin hard-delete (DeleteUserAsync -> DeleteUserWithCascadeAsync) failed the
foreign key inside the transaction and the controller surfaced it as a 400,
so the user was never deleted. Add an explicit ExecuteDelete on
UserPermissionOverrides before the user is removed, matching how UserRoles is
already cleared in the same method (no schema change).

SetOverrideAsync was check-then-insert on the composite key with no
DbUpdateException handling, so two concurrent PUTs for the same
(UserId, PermissionKey) let the loser violate PK_UserPermissionOverrides and
return 500. Catch the conflict, detach the pending insert, and converge by
updating the persisted row to the caller's requested state.
2026-09-16 20:27:26 -03:00
Alexandre Brandizzi
e8feed1d1b
Merge branch 'dev' into feat/ab/sh-348-dashboard-region 2026-09-16 20:26:26 -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
93ecbbd410 test(dashboard): guard Stats wire object for KPI counts (SH-353)
The added service test asserts DashboardStatsDTO, which already carried
ScheduledTomorrow, PendingUplifts and AvetaPending, so it does not guard
the regression that was actually shipped: the DashboardController Stats
anonymous response dropping those keys and leaving the tiles empty.

Add DashboardControllerTests.GetStats_SerialisesKpiCountsOnWireObject,
which drives the controller and asserts the three keys are present on the
serialised wire object, so re-dropping any of them fails a test.

Also reword the pending-uplifts comment in DashboardServiceTests: the
Pending-only-vs-ChangesRequested exclusion is the behaviour the code
ships today, an open product call, not a settled review decision.
2026-09-16 20:25:45 -03:00
Alexandre Brandizzi
7bdcc61651 fix(work-orders): bind GetWorkorderById id from the query string (SH-374) 2026-09-16 20:15:30 -03:00
Alexandre Brandizzi
22308f21f6 fix(dashboard): resolve region zones from full state names (SH-348)
Locations store State as either a two-letter postal code or a full state
name (the location list filter expands codes to both forms via
UsStateCodes.ExpandStorageValues, and dev fixtures carry State = "indiana").
DashboardRegions.Resolve only matched the two-letter key, so every location
stored as a full name fell into Unmapped/Other and the East/Central/West/
California bars undercounted.

Normalise the stored value through a new UsStateCodes.ToCode, which accepts a
code or a full name and returns the canonical postal code, before the zone
lookup. Extend the region test with full-name storage forms and add an
invariant asserting every US state and its full-name form resolves to a
canonical bucket.
2026-09-16 20:15:20 -03:00
Alexandre Brandizzi
104439c239 fix(dashboard): serialise KPI counts in Stats response (SH-353)
GetKpiCountsAsync computes ScheduledTomorrow, PendingUplifts and
AvetaPending and DashboardStatsDTO carries them, but the Stats
endpoint's anonymous wire object never serialised them, so the tiles
had nothing to read. Add scheduledTomorrow, pendingUplifts and
avetaPending to the response.

Add a DashboardServiceTests case covering GetKpiCountsAsync end to end:
it asserts all three counts and pins the pendingUplifts semantics to
Status "Pending" only, excluding "ChangesRequested" (which is back with
the vendor, not awaiting an approval decision).
2026-09-16 20:07:31 -03:00
Alexandre Brandizzi
5877f7817f fix(dashboard): bucket trend by calendar ScheduledDate (SH-350)
ScheduledDate is persisted as a midnight calendar value (board create writes
request.ScheduledDate.Value.Date; board patch writes the parsed .Date into a
datetime2 column with no offset). GetTrendAsync treated it as a UTC instant and
converted to America/New_York, so midnight became 19:00/20:00 the previous day
and every board-scheduled work order fell into the prior bucket: a job scheduled
today read as yesterday and overdue, and the Today bucket showed zero.

Bucket by DateOnly.FromDateTime(scheduled.Date) with no conversion, matching
DashboardMetrics and WorkOrderDerivedFields, so Trend and Stats agree on the
same rows. Rewrite the daily and yearly trend tests to assert calendar-date
classification (the removed conversion had encoded the shift into their
expectations) and add a regression test that a midnight-today work order stays
in the Today bucket and is not overdue.
2026-09-16 19:57:09 -03:00
Alexandre Brandizzi
7947e2e77d feat(dashboard): expose KPI counts (SH-353) 2026-09-16 19:23:53 -03:00
Alexandre Brandizzi
9d7efa34a6 feat(dashboard): add trend metrics (SH-350) 2026-09-16 18:42:26 -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
d6c3cd2e24 feat(permissions): add team member permission policy foundation (SH-327) 2026-09-16 17:48:37 -03:00
Alexandre Brandizzi
9b39d0e5ec feat(dashboard): add dispatcher workload (SH-346) 2026-09-16 17:43:49 -03:00
Alexandre Brandizzi
dec8b15278 fix(services): translate duplicate name races 2026-09-16 17:31:21 -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
d204536215
Merge pull request #121 from Sea-Haven-Industries/feat/ab/sh-278-vendor-area
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
SH-278: add admin-assigned vendor company Area
2026-09-16 17:05:57 -03:00
Alexandre Brandizzi
3047c2ba59
Merge branch 'dev' into feat/ab/sh-278-vendor-area 2026-09-16 17:00:27 -03:00