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.
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.
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).
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).
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).
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.
Restore FlagColor model/API/tests here after the parent structured-notes PR dropped them, so this PR remains the coherent home for the FlagColor column and palette.
Remove FlagColor model/API/tests from this PR so schema and EF model stay aligned with the structured-fields migration. FlagColor remains in the follow-on PR that adds its migration.
Persist primary/extra services, service notes, free-text POC, and
tech/vendor notes on create/patch/board/detail instead of embedding
them in description.
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.
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.
- 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
Introduces DispatchUpliftRequest entity and tier-gated approval flow:
vendors request a new NTE from the portal, dispatchers approve or deny
in SHOC, and requests above a configurable threshold require a higher
role. Adds DispatchController for PO-centric list/detail used by the
new Vendor POs page. Seeds Dispatcher and Manager roles.
- VendorAccessToken model + unique-index migration; TokenLifetimeDays config
- VendorPortalTokenService: CSPRNG token generation, rotation, revocation
- VendorPortalController: public portal API guarded by X-Vendor-Token header;
dispatches list/detail, accept, vendor status transitions, cancel request,
checklist updates, signoffs (vendor + customer), comments with dispatcher
attribution via AspNetUsers join
- VendorController: portal-token admin endpoints (get / rotate / revoke)
- WorkOrderController: dispatch email now uses vendor portal URL and HTML-encodes
user fields; AddDispatchComment now stores CommentType='dispatcher' with the
SHOC user's name so portal can attribute the author
- DispatchPublicController: deprecated per-dispatch GET accept flow returns a
static 'link no longer active' page (no state mutation)