Commit graph

101 commits

Author SHA1 Message Date
Alexandre Brandizzi
5ecb377613
fix: align vendor document API with frontend (#37)
Some checks are pending
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-07-28 13:57:45 -03:00
Alexandre Brandizzi
f701899a83 fix(work-orders): satisfy producer contract review 2026-07-27 16:33:06 -03:00
Alexandre Brandizzi
27bf81b7f8 fix(work-orders): address procurement review findings 2026-07-27 14:40:17 -03:00
Alexandre Brandizzi
8a2e260177 test: prove SH-133 webhook and admin boundaries 2026-07-25 15:45:52 -03:00
Alexandre Brandizzi
e3c37e54b4 feat: complete SH-133 procurement reconciliation 2026-07-24 22:13:25 -03:00
Alexandre Brandizzi
bdffe77e42 feat: ingest signed procurement work-order webhooks 2026-07-24 21:03:50 -03:00
Arthur Bassi
8f492c0faf
feat(work-orders): allow comment edit and resolve author audit display names (#24)
* feat(work-orders): enrich board search overdue filters and 0-based paging

* fix(work-orders): align stacked services with CI build

* fix(tests): pass userDataService in comment service unit test

* fix(work-orders): use dedicated overdue query flag

Stop treating WorkOrderType.Other as an overdue sentinel. Board and advanced search now accept overdue=true while types=Other filters real Other rows; combining both uses OR.

* feat(work-orders): allow comment edit and resolve author audit display names

Add PATCH comment for author/Admin, return authorName, and resolve
AssignTo audit values to user display names.

* fix(work-orders): enforce author-only comment edits per SH-122

Remove the undocumented Admin override so only the original comment author can edit, matching the ticket acceptance criteria.

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>
Co-authored-by: Alexandre Brandizzi <alex_brandizzi@hotmail.com>
2026-07-24 21:28:44 +00:00
Arthur Bassi
620a36af54
feat(work-orders): enrich board search overdue filters and 0-based paging (#23)
* feat(work-orders): enrich board search overdue filters and 0-based paging

* fix(work-orders): align stacked services with CI build

* fix(tests): pass userDataService in comment service unit test

* fix(work-orders): use dedicated overdue query flag

Stop treating WorkOrderType.Other as an overdue sentinel. Board and advanced search now accept overdue=true while types=Other filters real Other rows; combining both uses OR.

* test(work-orders): cover overdue date/status boundary and Other type-filter

Lock the PR #23 overdue regression boundary through the public advanced
search service. Prove overdue filtering is driven by past-due date plus
non-terminal status, not by the WorkOrderType.Other sentinel:
- Other + future/not-completed excluded from overdue
- past-due + Scheduled included; past-due + Completed/Canceled excluded
- types=[PM, Other] keeps real Other rows and does not pull past-due rows
- assert 0-based paging (Page=0) is preserved alongside overdue/type filters

---------

Co-authored-by: Arthur Bassi <arthur.winiarski.ranger@outlook.com>
Co-authored-by: Alexandre Brandizzi <alex_brandizzi@hotmail.com>
2026-07-24 21:12:03 +00:00
Alexandre Brandizzi
7d245eb717
refactor: enforce backend boundaries and optimize dispatch (#30)
* refactor(api): enforce service and data-service boundaries

* refactor(api): complete feature service boundaries

* refactor(identity): enforce service and data boundaries

* refactor(vendors): enforce service and data boundaries

* refactor(workorders): enforce service and data boundaries

* refactor(backend): enforce architecture and optimize dispatch

* style(backend): format changed architecture files

* fix(architecture): address backend review follow-ups

* fix(backend): sanitize exception disclosure in changed API endpoints

Replace raw exception-message disclosure (ex.Message) returned to API
callers with a stable sanitized public message plus correlated structured
internal logging, across the endpoints changed in this PR.

- Add SanitizedErrors helper: logs the original exception at Error with a
  generated correlation id and returns a stable public message referencing
  it so support can trace without exposing internals.
- Inject ILogger<T> into the 14 changed controllers and route every
  ex.Message/dbex.Message disclosure through the helper, preserving status
  codes, response shapes, and business data (e.g. OpenWorkOrders).
- Leave FluentValidation (vex.Errors) and existing fixed-message catches
  untouched; out-of-scope controllers (Account/Contact/Employee/Asset/
  PMSchedule) are unchanged.
- Add focused tests proving internal exception text is not returned and
  that Error logging carrying the original exception is invoked.

* fix(architecture): abstract job run state access

* style: format board update service

* test: use collection assertion idiom
2026-07-24 17:35:34 -03:00
Alexandre Brandizzi
e5cf4cec09 merge: integrate origin/dev into PR #22 flag-color base
Brings in dev's Phase 5 (PR #17) + vendor PRs (#25/#28/#29) atop the
Phase 6/7 + flagColor base (PR #22). Preserves dev Phase 1-5 behavior and
PR #22 Phase 6/7 + flagColor behavior.

Conflict resolutions (16 files):
- Migrations Phase4_SearchIndexes/.Designer + Phase5_DomainEvents/.Designer:
  take dev (Phase4 incl. SQL Server SiteCode/InternalWONumber index-compat
  shrink fix; Phase5 identical). ModelSnapshot union: Vendor CompanyId index
  + Phase7 ServiceNotes/ExternalWorkOrderId index.
- ApplicationDbContext: keep dev SiteCode/InternalWONumber MaxLength (Phase1-5
  + unguarded model test) + HEAD CompletionDocTemplate/ExternalWorkOrderId.
- WorkOrderAuditService: unify on dev async staging API; convert Phase6
  CompletionService 2 call sites to await StageFieldChangedAsync (drops
  HEAD sync duplicate; only callers, no test refs).
- Hosted services: take HEAD (retry-on-failure, coherent with Phase7
  WorkOrderJobRunStateAccessor/OpsHealth). Program.cs keeps dev vendor DI
  (ClamAV/VendorDocumentScanWorker/ArgumentExceptionFilter) + HEAD Phase7.
- WorkOrderController: keep HEAD Phase6/7 service params + dev doc comment.
- VendorController/WorkOrderBoardCreateService/QueryFilters/appsettings:
  union / dev-correct.
- WorkOrderBoardUpdateServiceTests: union of HEAD (Phase6/7+flagColor) and
  dev (Phase1-5) test methods.

Verified WorkOrderType.Other (enum 99) is a legit category, not an overdue
sentinel; overdue uses dedicated OperationalFlags.PastDue + IsPastDue, and
'Overdue' is rejected as a WorkOrderType (no PR #23 import needed).

Removed dev duplicate Api.Options.WorkOrderJobRunState (HEAD defines it in
Services.Implementation alongside the Accessor; Services cannot reference Api).
2026-07-24 14:20:16 -03:00
Alexandre Brandizzi
5fa9b4e344 merge: integrate origin/dev into work-orders-phase-5
Brings in merged PR #16 and vendor/Phase 1-4 work from origin/dev into the
Phase 5 (WeekRolled) head. Only conflict was ApplicationDbContextModelSnapshot.cs
(EF model snapshot touched by both sides); resolved by taking dev's latest
snapshot (matches migration 20260723220614) and grafting the
WorkOrderWeekRolledLedger entity + relationship blocks, matching the Phase5
migration Designer exactly. Migration ordering unchanged: Phase5 (20260709)
runs before vendor migrations (20260720-20260723).
2026-07-24 13:51:41 -03:00
Alexandre Brandizzi
a9dee0bb84 merge: integrate origin/dev into work-orders-phase-4
Merge origin/dev (vendor roadmap PRs #28/#29, phases 1-3 PRs #13-15)
into work-orders-phase-4. Conflict in WorkOrderController.cs resolved by
keeping both the Phase 4 board/search endpoint and the dev-side XML doc
comment on GetDispatcherLookups (both additions at the same site).

Migration timestamps remain monotonic and non-overlapping. Phase 4 global
advanced search, search index migrations, and the cross-platform LocalDB
test guard are preserved alongside the merged vendor roadmap and phases 1-3.

Validation (Docker .NET 8 SDK): build 0 errors; 191 tests pass across
all three test projects (64 + 18 + 109).
2026-07-24 13:38:20 -03:00
Alexandre Brandizzi
8192da7790
Merge pull request #15 from Sea-Haven-Industries/feat/work-orders-phase-3
Feat/work orders Phase 3 board create and soft cancel
2026-07-24 13:34:39 -03:00
Alexandre Brandizzi
df828cf48c
Merge pull request #14 from Sea-Haven-Industries/feat/work-orders-phase-2
Feat/work orders phase 2
2026-07-24 13:32:25 -03:00
Alexandre Brandizzi
3bd0268129
Merge pull request #13 from Sea-Haven-Industries/feat/work-orders-phase-1-board
Feat/work orders phase 1 board
2026-07-24 13:29:09 -03:00
Alexandre Brandizzi
b1421de0b5 fix(vendors): address roadmap review findings 2026-07-24 11:49:57 -03:00
Arthur Bassi
7459dca3c6 feat(work-orders): add Phase 5 scheduled domain events (WeekRolled)
Introduce in-process WeekRolled job with idempotent ledger to increment carriedOver for the SHOC board, plus optional PastDue cache and admin reprocess endpoints while keeping isPastDue derived on-read.
2026-07-24 10:13:17 -03:00
Arthur Bassi
edcdc10395 fix(work-orders): return 400 for invalid advanced-search custom date range
Map ArgumentException from datePreset=custom without dates to BadRequest so the endpoint matches the Phase 4 contract.
2026-07-24 10:01:11 -03:00
Arthur Bassi
11fed06f03 feat(work-orders): add Phase 4 board search and advanced search API
Harden contextual search on the weekly board and expose paginated cross-week GET /board/search with date presets, FE filter params, SQL indexes, and unit tests.
2026-07-24 09:58:39 -03:00
Alexandre Brandizzi
4863d1fdaf feat(vendors): complete operations roadmap backend 2026-07-23 19:18:06 -03:00
Alexandre Brandizzi
8cf49afc2c feat(vendors): complete core vendor workflows 2026-07-23 17:02:40 -03:00
Arthur Bassi
385812c5c3 merge: sync phase 3 with updated phase 2 base
Reconcile migration/docs deletions from phase 2, adopt async audit staging and ApptTime lock contracts, and keep phase 3 create/cancel transactional behavior.
2026-07-23 13:28:54 -03:00
Alexandre Brandizzi
1162c68596
feat(vendors): add directory filters and details API (#25)
* feat(vendors): add directory filters and details API

* fix(vendors): preserve omitted status

* fix(vendors): align facet filtering

* fix(vendors): address directory review findings
2026-07-23 15:55:47 +00:00
Arthur Bassi
75969a1e3d docs(work-orders): clarify board filter precedence and dispatcher lookup
Document myWorkOrders overriding dispatchers, weekend dayGroup null contract, and that dispatcher lookups currently return all users. Map service ArgumentException to 400 for consistency.
2026-07-21 09:33:24 -03:00
Arthur Bassi
f3d2a5cfe7 fix(work-orders): address PR13 phase-1 review feedback 2026-07-17 14:51:56 -03:00
Arthur Bassi
4bd11dcf6b fix(work-orders): address stacked PR review feedback 2026-07-17 14:31:08 -03:00
Arthur Bassi
3983f7667d feat(locations): add sites options endpoint and vendor contactName
Expose GET /api/locations/sites for the WO create wizard and include
vendor contactName on dropdown responses.
2026-07-17 10:36:32 -03:00
Arthur Bassi
5d2a2d0ed0 chore(config): document Phase 7 feature flags in appsettings and .env.example 2026-07-13 13:23:54 -03:00
Arthur Bassi
64ca9e0bdf feat(work-orders): add legacy deprecation middleware and Blazor WO sunset guard 2026-07-13 13:22:53 -03:00
Arthur Bassi
89cb520db9 feat(work-orders): add Sync kill-switch and ops health coexistence endpoints 2026-07-13 13:22:12 -03:00
Arthur Bassi
1074ed860b feat(work-orders): add work order ingest API with X-Ingest-Key 2026-07-13 13:22:11 -03:00
Arthur Bassi
af84001bf1 feat(work-orders): add Phase 6 slide-over detail comments audit and media API 2026-07-13 13:13:00 -03:00
Arthur Bassi
812a5e994c merge: integrate Phase 4 into Phase 5 and add DomainEvents Designer metadata
Resolve snapshot conflict by keeping Phase 4 search indexes and Phase 5 ledger model. Add missing Phase5_DomainEvents.Designer.cs so EF discovers the WorkOrderWeekRolledLedgers migration.
2026-07-10 11:53:29 -03:00
Arthur Bassi
dd2a805c24 fix(work-orders): return 400 for invalid advanced-search custom date range
Map ArgumentException from datePreset=custom without dates to BadRequest so the endpoint matches the Phase 4 contract.
2026-07-10 10:56:18 -03:00
Arthur Bassi
88f9245fbf merge: sync Phase 1 board review fixes into Phase 2
Resolve conflicts in WorkOrderController and WorkOrderBoardService so Phase 2 merges cleanly into the Phase 1 base.
2026-07-10 10:41:36 -03:00
Arthur Bassi
8c33eb7f9a feat(work-orders): add Phase 5 scheduled domain events (WeekRolled)
Introduce in-process WeekRolled job with idempotent ledger to increment carriedOver for the SHOC board, plus optional PastDue cache and admin reprocess endpoints while keeping isPastDue derived on-read.
2026-07-09 14:08:48 -03:00
Arthur Bassi
c2d0bd45e3 fix(work-orders): address PR #13 review feedback
Return BadRequest for invalid board week window, remove duplicate unused board types, fix POC null guard, and document appt precedence and UTC Phase 1 assumptions.
2026-07-09 10:06:36 -03:00
Arthur Bassi
83272e4957 Revert "fix(work-orders): address PR #14 board PATCH review feedback"
This reverts commit eb64c2f55c.
2026-07-09 09:59:41 -03:00
Arthur Bassi
88caede86a fix(work-orders): address PR #14 board PATCH review feedback
Reuse field-lock DB checks during staged audits, defer dispatch creation to the final save, and return 404 for missing work orders.
2026-07-09 09:58:41 -03:00
Arthur Bassi
eb64c2f55c fix(work-orders): address PR #14 board PATCH review feedback
Reuse field-lock DB checks during staged audits, defer dispatch creation to the final save, and return 404 for missing work orders.
2026-07-09 09:54:53 -03:00
Arthur Bassi
4617e8ba83 feat(work-orders): add Phase 4 board search and advanced search API
Harden contextual search on the weekly board and expose paginated cross-week GET /board/search with date presets, FE filter params, SQL indexes, and unit tests.
2026-07-08 14:58:59 -03:00
Arthur Bassi
e5bda0714a feat(work-orders): add Phase 3 board create and soft cancel API
Expose POST /api/workorders/board and POST /api/workorders/{id}/cancel for SHOC wizard/inline creation and soft cancel, with field locks, WO# normalization, and Admin-only hard delete.
2026-07-08 10:17:31 -03:00
Arthur Bassi
91122d753d merge: integrate Phase 1 board API into Phase 2 branch
Combine the reviewed Phase 1 read-only board endpoints with Phase 2 inline edit and optimistic concurrency, resolving shared foundation conflicts while preserving both feature sets.
2026-07-07 13:59:22 -03:00
Arthur Bassi
673bc3b5a9 fix(work-orders): align phase 2 status/type contract to SHOC frontend
Expand LifecycleStatus (EnRoute, OnSite, Rescheduled, Pending, PendingQuote) and WorkOrderType (Reactive, AddOn) to match the frontend prototype. Add FE label round-trip via LifecycleStatusMapper/WorkOrderTypeMapper, update derived fields, mutation rules and board unscheduled filter, and reactivate [Authorize] on WorkOrderController. Fix pre-existing dayGroup test expectation.
2026-07-07 13:11:22 -03:00
Arthur Bassi
d040832b87 feat(work-orders): isolate phase 2 inline edit with optimistic concurrency
Deliver PATCH board field updates and drop phases 3-7 code from the branch while keeping phase 0/1 dependencies required to build and test.
2026-07-07 11:26:13 -03:00
Arthur Bassi
ff53cb9fa6 feat(work-orders): add weekly board read API (Phase 1)
- GET /api/workorders/board with week window, Unscheduled section, and X of Y counts
- GET /api/workorders/lookups/dispatchers for SHOC filter avatars
- Board projection via WorkOrderBoardDataService with vendor/dispatch join and derived isPastDue
- Phase1_BoardIndexes migration (IX_workOrders_ScheduledDate)
- 5 board unit tests
2026-07-07 10:10:06 -03:00
Arthur Bassi
623810da45 feat(phase-0): finalize foundation — authorize, concurrency filter, isolated build 2026-07-02 09:19:28 -03:00
Arthur Bassi
4f697f257a wip: work orders phases 1-7 (isolated from phase 0 foundation) 2026-06-30 10:09:48 -03:00
Adam Moussa
1f3972ae49
Add calendar/events backend API (#8)
* Align EntityFrameworkCore.SqlServer and Tools to 8.0.8

* Add calendar/events backend API

Cherry-picked from main-backup (19994ef); scratch notes file removed.

* Require authentication on CalendarController

Security review found [Authorize] commented out, leaving all 6 calendar
endpoints anonymous. Enforce auth to match the API convention (17/23
controllers).

* Add CalendarController unit tests (xUnit + EF InMemory)
2026-06-22 18:46:46 -04:00
c887d6d9d8 fix(security): remove hardcoded secrets from source
Replace all hardcoded credentials with configuration-injected values:
- SQL Server connection strings -> ${CONNECTION_STRING} env-var placeholders (4 appsettings files)
- SendGrid API keys -> ${SENDGRID_API_KEY} (incl. commented copies in SendMessage.cs)
- JWT signing secret -> ${JWT_SECRET} (3 appsettings files)
- AWS access key pair in UploadFileHp.cs -> DI-injected IAmazonS3 (SDK default credential chain)
- Google Maps API keys in App.razor / Home.razor -> IConfiguration lookup
- Legacy SMTP credentials in SendMessage.cs comments -> placeholders

Add .env.example documenting required environment variables and a
Configuration & Secrets section in BACKEND_ARCHITECTURE.md.

All exposed credentials were rotated 2026-06-05 prior to this scrub.
Source: github-audit-report.md Criticals 1-2 (Agent A4).
Verified: dotnet build 0 errors; secret-pattern grep clean.
2026-06-05 11:56:54 -04:00