From 620a36af5475deb5f5d8ad6815443caa8879b9eb Mon Sep 17 00:00:00 2001 From: Arthur Bassi Date: Fri, 24 Jul 2026 18:12:03 -0300 Subject: [PATCH] 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 Co-authored-by: Alexandre Brandizzi --- .../WorkOrderControllerSearchTests.cs | 14 + .../Controllers/WorkOrderBoardController.cs | 2 + .../Auth/ApplicationDbContext.cs | 6 +- .../Helpers/WorkOrderBoardQueryFilters.cs | 50 ++- .../Helpers/WorkOrderBoardSearchFilter.cs | 88 ++++- .../WorkOrderAdvancedSearchDataService.cs | 4 +- .../WorkOrderBoardDataService.cs | 2 +- .../WorkOrderAdvancedSearchModels.cs | 1 + .../Interfaces/WorkOrderBoardModels.cs | 1 + SeaHaven.Services.Tests/PagedResultTests.cs | 23 +- SeaHaven.Services/DTOs/ContactDTOs.cs | 15 +- SeaHaven.Services/DTOs/WorkOrderBoardDTOs.cs | 2 + .../DTOs/WorkOrderBoardRequestDTOs.cs | 4 +- .../Helpers/WorkOrderBoardSortFields.cs | 29 ++ .../WorkOrderSearchDateRangeResolver.cs | 6 +- .../WorkOrderAdvancedSearchService.cs | 12 +- .../Implementation/WorkOrderBoardService.cs | 1 + .../Implementation/WorkOrderCommentService.cs | 63 ++- .../Interfaces/IWorkOrderCommentService.cs | 8 +- .../WorkOrderBoardSearchTests.cs | 372 +++++++++++++++++- .../WorkOrderBoardServiceTests.cs | 3 + .../WorkOrderPhase6Tests.cs | 3 +- 22 files changed, 675 insertions(+), 34 deletions(-) create mode 100644 SeaHaven.Services/Helpers/WorkOrderBoardSortFields.cs diff --git a/Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs b/Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs index 10ac872..c2a11aa 100644 --- a/Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs +++ b/Api.SeaHavenIndustries.Tests/WorkOrderControllerSearchTests.cs @@ -4,6 +4,7 @@ using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Moq; +using SeaHaven.DataServices.Implementation; using SeaHaven.DataServices.Interfaces; using SeaHaven.Services.DTOs; using SeaHaven.Services.Helpers; @@ -60,4 +61,17 @@ public class WorkOrderControllerSearchTests body.Status.Should().Be("Error"); body.Message.Should().Contain("dateFrom"); } + + [Fact] + public async Task GetBoard_WhenWeekEndBeforeWeekStart_ReturnsBadRequest() + { + var controller = NewController(Mock.Of()); + + var result = await controller.GetBoard( + new DateOnly(2026, 6, 22), + new DateOnly(2026, 6, 15)); + + var badRequest = result.Should().BeOfType().Subject; + badRequest.Value.Should().BeOfType().Which.Should().Contain("weekEnd"); + } } diff --git a/Api.SeaHavenIndustries/Controllers/WorkOrderBoardController.cs b/Api.SeaHavenIndustries/Controllers/WorkOrderBoardController.cs index 204b742..85f6698 100644 --- a/Api.SeaHavenIndustries/Controllers/WorkOrderBoardController.cs +++ b/Api.SeaHavenIndustries/Controllers/WorkOrderBoardController.cs @@ -53,6 +53,7 @@ namespace Api.SeaHavenIndustries.Controllers [FromQuery] List? dispatchers = null, [FromQuery] bool myWorkOrders = false, [FromQuery] List? types = null, + [FromQuery] bool overdue = false, [FromQuery] string? search = null) { var resolvedWeekEnd = weekEnd ?? weekStart.AddDays(4); @@ -70,6 +71,7 @@ namespace Api.SeaHavenIndustries.Controllers Dispatchers = dispatchers, MyWorkOrders = myWorkOrders, Types = types, + Overdue = overdue, Search = search }; diff --git a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs index 48c34fe..2e214bb 100644 --- a/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs +++ b/Data.SeaHavenIndustries/Auth/ApplicationDbContext.cs @@ -206,7 +206,7 @@ namespace Data.SeaHavenIndustries return bytes; } - + } public class ApplicationUser : IdentityUser { @@ -222,8 +222,8 @@ namespace Data.SeaHavenIndustries public string? Initials { get; set; } public string? Color { get; set; } public int? Type { get; set; } // 1 for users 0 for admin - public ICollection