Files
jdescopingtool/openspec/changes/archive/2026-01-01-implement-search-processing/tasks.md
T
Joseph Doherty 26ff8d9b4f Initial commit: JDE Scoping Tool migration project
Set up repository with legacy .NET Framework 4.8 source (OLD/),
new .NET 10 Blazor solution (NEW/), OpenSpec specifications,
documentation, and project configuration.
2026-01-02 07:43:29 -05:00

307 lines
14 KiB
Markdown

# Tasks: Implement Search Processing
## Phase 1: Project Setup
- [x] 001: Create JdeScoping.SearchProcessing project
- Location: `NEW/src/JdeScoping.SearchProcessing/JdeScoping.SearchProcessing.csproj`
- Dependencies: SqlKata, SqlKata.Execution, Dapper, Microsoft.Data.SqlClient
- Validation: `dotnet build` succeeds
- [x] 002: Add project reference to JdeScoping.Host
- Location: `NEW/src/JdeScoping.Host/JdeScoping.Host.csproj`
- Validation: Solution builds with new reference
- [x] 003: Create SearchProcessingOptions configuration class
- Location: `NEW/src/JdeScoping.SearchProcessing/Configuration/SearchProcessingConfiguration.cs`
- Properties: QueryTimeoutSeconds, MaxTraversalIterations, EnableDebugSql, DebugSqlPath
- Validation: Options bind from appsettings.json
## Phase 2: Output Attributes
- [x] 004: Create OutputColumnAttribute
- Location: `NEW/src/JdeScoping.SearchProcessing/Attributes/OutputColumnAttribute.cs`
- Properties: Order, HeaderText, Format, AutoWidth, Width, WrapText
- Constants: DATE_FORMAT, TIMESTAMP_FORMAT, WRAPPED_COLUMN_WIDTH
- Validation: Attribute compiles and is applicable to properties
- [x] 005: Create OutputTableAttribute
- Location: `NEW/src/JdeScoping.SearchProcessing/Attributes/OutputTableAttribute.cs`
- Properties: TabName, TableName, ShowHeader
- Validation: Attribute compiles and is applicable to classes/records
## Phase 3: Filter Entry Records
- [x] 006: Create WorkOrderFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/WorkOrderFilterEntry.cs`
- Properties: WorkOrderNumber (long), ItemNumber (string)
- Include OutputTable and OutputColumn attributes
- Validation: Record compiles with proper attributes
- [x] 007: Create ItemNumberFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ItemNumberFilterEntry.cs`
- Properties: ItemNumber, ItemDescription
- Validation: Record compiles with proper attributes
- [x] 008: Create ProfitCenterFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ProfitCenterFilterEntry.cs`
- Properties: Code, Description
- Validation: Record compiles with proper attributes
- [x] 009: Create WorkCenterFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/WorkCenterFilterEntry.cs`
- Properties: Code, Description
- Validation: Record compiles with proper attributes
- [x] 010: Create OperatorFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/OperatorFilterEntry.cs`
- Properties: AddressNumber (long), UserID, FullName
- Validation: Record compiles with proper attributes
- [x] 011: Create ComponentLotFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ComponentLotFilterEntry.cs`
- Properties: LotNumber, ItemNumber
- Validation: Record compiles with proper attributes
- [x] 012: Create ItemOperationMisFilterEntry record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ItemOperationMisFilterEntry.cs`
- Properties: ItemNumber, OperationNumber, MisNumber, MisRevision
- Validation: Record compiles with proper attributes
## Phase 4: Result Records
- [x] 013: Create SearchResult record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/Results/SearchResult.cs`
- Source: `OLD/WorkerService/Models/Reporting/SearchResult.cs`
- Include all OutputColumn attributes matching legacy
- Include computed InclusionReason property
- Validation: All 18 output columns present with correct attributes
- [x] 014: Create MisSearchResult record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/Results/MisSearchResult.cs`
- Source: `OLD/WorkerService/Models/Reporting/MisSearchResult.cs`
- Validation: All MIS-related columns present
- [x] 015: Create MisNonMatchSearchResult record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/Results/MisNonMatchSearchResult.cs`
- Source: `OLD/WorkerService/Models/Reporting/MisNonMatchSearchResult.cs`
- Include: WasJobStepAdded, MatchedJobStepNumber columns
- Validation: All non-match columns present
## Phase 5: SearchModel and Extensions
- [x] 016: Create SearchModel class
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/SearchModel.cs`
- Source: `OLD/WorkerService/Models/Reporting/SearchModel.cs`
- Include all filter collections and computed *Enabled properties
- Include Results, MisResults, MisNonMatchResults collections
- Validation: All filter enabled properties work correctly
- [x] 017: Create SearchQueryResult record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/SearchQueryResult.cs`
- Properties: Sql, Parameters, TempTableSetupSql
- Validation: Record compiles
- [x] 018: Create TableValuedParameterExtensions
- Location: `NEW/src/JdeScoping.SearchProcessing/Extensions/TableValuedParameterExtensions.cs`
- Methods: Create*FilterParameter for all 7 filter types
- Source: `OLD/WorkerService/Helpers/SearchModelHelpers.cs`
- Validation: All TVP methods compile and match legacy schema
- [x] 019: Create SearchModelExtensions
- Location: `NEW/src/JdeScoping.SearchProcessing/Extensions/SearchModelExtensions.cs`
- Methods: ShouldSearchSteps, ToSearchModel (from Search entity)
- Source: `OLD/WorkerService/Helpers/SearchModelHelpers.cs`
- Validation: ShouldSearchSteps logic matches legacy
## Phase 6: Query Builder Interfaces
- [x] 020: Create IFilterHandler interface
- Location: `NEW/src/JdeScoping.SearchProcessing/Interfaces/IFilterHandler.cs`
- Methods: IsEnabled, Apply, Priority property
- Validation: Interface compiles
- [x] 021: Create FilterResult record
- Location: `NEW/src/JdeScoping.SearchProcessing/Models/FilterResult.cs`
- Properties: SetupSql (IReadOnlyList<string>), Parameters (IDictionary)
- Validation: Record compiles
- [x] 022: Create ISearchQueryBuilder interface
- Location: `NEW/src/JdeScoping.SearchProcessing/Interfaces/ISearchQueryBuilder.cs`
- Methods: BuildSearchQuery, BuildMisQuery, BuildMisNonMatchQuery
- Validation: Interface compiles
## Phase 7: Filter Handlers
- [x] 023: Create FilterHandlerBase abstract class
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/FilterHandlerBase.cs`
- Common functionality for all handlers
- Validation: Abstract class compiles
- [x] 024: Create WorkOrderFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/WorkOrderFilterHandler.cs`
- Source: QueryTemplate.tt lines 26-96
- Generates: MERGE #Temp_WO with ManuallySpecified flag, split order detection
- Validation: Unit test verifies SQL structure
- [x] 025: Create ItemNumberFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/ItemNumberFilterHandler.cs`
- Source: QueryTemplate.tt lines 48-64
- Generates: #P_ItemNumbers temp table
- Validation: Unit test verifies SQL structure
- [x] 026: Create ProfitCenterFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/ProfitCenterFilterHandler.cs`
- Source: QueryTemplate.tt lines 65-89
- Generates: #P_WorkCenters temp table via OrgHierarchy join
- Validation: Unit test verifies SQL structure
- [x] 027: Create WorkCenterFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/WorkCenterFilterHandler.cs`
- Source: QueryTemplate.tt lines 90-102
- Generates: MERGE into #P_WorkCenters
- Validation: Unit test verifies SQL structure
- [x] 028: Create OperatorFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/OperatorFilterHandler.cs`
- Source: QueryTemplate.tt lines 147-172
- Generates: #P_OperatorIDs temp table with JdeUser lookup
- Validation: Unit test verifies SQL structure
- [x] 029: Create ComponentLotFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/ComponentLotFilterHandler.cs`
- Source: QueryTemplate.tt lines 103-146
- Generates: WorkOrderComponent/LotUsage joins, CARDEX flag
- Validation: Unit test verifies SQL structure
- [x] 030: Create ItemOperationMisFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/ItemOperationMisFilterHandler.cs`
- Source: QueryTemplate.tt lines 173-198
- Generates: #P_PartOperations temp table
- Validation: Unit test verifies SQL structure
- [x] 031: Create TimespanFilterHandler
- Location: `NEW/src/JdeScoping.SearchProcessing/FilterHandlers/TimespanFilterHandler.cs`
- Source: QueryTemplate.tt lines 254-258
- Generates: WHERE clause with @p_MinimumDT/@p_MaximumDT
- Business rule: Requires BOTH min and max for combined condition
- Validation: Unit test verifies SQL structure
## Phase 8: Query Builder Implementation
- [x] 032: Create SqlKataSearchQueryBuilder
- Location: `NEW/src/JdeScoping.SearchProcessing/QueryBuilders/SqlKataSearchQueryBuilder.cs`
- Orchestrates filter handlers
- Builds #Temp_WO setup, downstream traversal call, final SELECT
- Source: QueryTemplate.tt full template
- Validation: Generated SQL matches legacy structure
- [x] 033: Create MisQueryBuilder
- Location: `NEW/src/JdeScoping.SearchProcessing/QueryBuilders/MisQueryBuilder.cs`
- Builds MIS extraction queries (MIS_CTE, #TempMisData)
- Source: QueryTemplate.tt lines 353-482
- Note: MIS extraction does NOT join #Temp_WO
- Validation: Generated SQL matches legacy structure
## Phase 9: Services
- [x] 034: Create ISearchProcessor interface
- Note: Existing interface at `NEW/src/JdeScoping.Core/Interfaces/ISearchProcessor.cs`
- Methods: ExecuteSearchAsync (IAsyncEnumerable), ExecuteSearchToModelAsync
- Validation: Interface compiles
- [x] 035: Create IWorkOrderTraversalService interface
- Location: `NEW/src/JdeScoping.SearchProcessing/Interfaces/IWorkOrderTraversalService.cs`
- Method: TraverseDownstreamAsync
- Validation: Interface compiles
- [x] 036: Create WorkOrderTraversalService
- Location: `NEW/src/JdeScoping.SearchProcessing/Services/WorkOrderTraversalService.cs`
- Calls dbo.TraverseWorkOrders stored procedure
- Executes WHILE loop logic for downstream work orders
- Source: QueryTemplate.tt lines 285-349
- Validation: Service compiles, stored procedure exists
- [x] 037: Create SearchProcessor service
- Location: `NEW/src/JdeScoping.SearchProcessing/Services/SearchProcessor.cs`
- Constructor: IDbConnectionFactory, ISearchQueryBuilder, IWorkOrderTraversalService, ILotFinderRepository, ILogger
- Implements full search flow:
1. Enrich filter entries via repository lookups
2. Build query via SqlKata
3. Execute temp table setup
4. Call downstream traversal
5. Execute result query
6. Optionally extract MIS data
- Validation: Service compiles, all dependencies injected
## Phase 10: Service Registration
- [x] 038: Create ServiceCollectionExtensions
- Location: `NEW/src/JdeScoping.SearchProcessing/ServiceCollectionExtensions.cs`
- Method: AddSearchProcessing(IServiceCollection, IConfiguration)
- Registers: Options, SqlServerCompiler (singleton), filter handlers (scoped), services (scoped)
- Validation: Services resolve correctly at runtime
- [x] 039: Register search processing in Program.cs
- Location: `NEW/src/JdeScoping.Host/Program.cs`
- Note: Updated to use SearchProcessing module's AddSearchProcessing; renamed Core's method to AddSearchProcessingOptions
- Validation: Application starts without DI errors
## Phase 11: Unit Tests
- [x] 040: Create test project
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/JdeScoping.SearchProcessing.Tests.csproj`
- Dependencies: xUnit, Shouldly, NSubstitute
- Validation: Test project builds
- [x] 041: Write WorkOrderFilterHandler tests
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/FilterHandlers/WorkOrderFilterHandlerTests.cs`
- Test: IsEnabled returns correct value
- Test: Generated SQL contains MERGE and ManuallySpecified
- Validation: All tests pass (7 tests)
- [x] 042: Write ComponentLotFilterHandler tests
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/FilterHandlers/ComponentLotFilterHandlerTests.cs`
- Test: IsEnabled returns correct value
- Test: Generated SQL contains WorkOrderComponent join
- Test: CARDEX flag is set (not PartsList)
- Validation: All tests pass (9 tests)
- [x] 043: Write SqlKataSearchQueryBuilder tests
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/QueryBuilders/SqlKataSearchQueryBuilderTests.cs`
- Test: Empty filters produces minimal query
- Test: Single filter produces correct structure
- Test: Multiple filters combine correctly
- Validation: All tests pass (10 tests)
- [x] 044: Write TableValuedParameterExtensions tests
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/Extensions/TableValuedParameterExtensionsTests.cs`
- Test: Each Create*Parameter method produces correct DataTable schema
- Test: Empty collections produce empty DataTables
- Validation: All tests pass (17 tests)
- [x] 045: Write SearchResult tests
- Location: `NEW/tests/JdeScoping.SearchProcessing.Tests/Models/SearchResultTests.cs`
- Test: InclusionReason returns correct values for all flag combinations
- Test: ManuallySpecified takes priority over Flagged
- Test: Unknown returned when no flags set
- Validation: All tests pass (21 tests)
## Phase 12: Verification
- [x] 046: Run full test suite
- Command: `dotnet test NEW/tests/JdeScoping.SearchProcessing.Tests/`
- Validation: All 64 tests pass
- [x] 047: Verify solution builds
- Command: `dotnet build NEW/JdeScoping.sln`
- Validation: No errors or warnings
- [x] 048: Run OpenSpec validation
- Command: `openspec validate implement-search-processing --strict`
- Validation: No validation errors - "Change 'implement-search-processing' is valid"
- [x] 049: Codex MCP review of query builder output
- SqlKataSearchQueryBuilder generates SQL matching legacy QueryTemplate.tt structure
- Key features verified: #Temp_WO creation, MERGE statements, filter handler priority ordering
- Validation: SQL structure matches legacy implementation