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

14 KiB

Tasks: Implement Search Processing

Phase 1: Project Setup

  • 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
  • 002: Add project reference to JdeScoping.Host

    • Location: NEW/src/JdeScoping.Host/JdeScoping.Host.csproj
    • Validation: Solution builds with new reference
  • 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

  • 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
  • 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

  • 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
  • 007: Create ItemNumberFilterEntry record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ItemNumberFilterEntry.cs
    • Properties: ItemNumber, ItemDescription
    • Validation: Record compiles with proper attributes
  • 008: Create ProfitCenterFilterEntry record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ProfitCenterFilterEntry.cs
    • Properties: Code, Description
    • Validation: Record compiles with proper attributes
  • 009: Create WorkCenterFilterEntry record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/WorkCenterFilterEntry.cs
    • Properties: Code, Description
    • Validation: Record compiles with proper attributes
  • 010: Create OperatorFilterEntry record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/OperatorFilterEntry.cs
    • Properties: AddressNumber (long), UserID, FullName
    • Validation: Record compiles with proper attributes
  • 011: Create ComponentLotFilterEntry record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ComponentLotFilterEntry.cs
    • Properties: LotNumber, ItemNumber
    • Validation: Record compiles with proper attributes
  • 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

  • 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
  • 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
  • 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

  • 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
  • 017: Create SearchQueryResult record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/SearchQueryResult.cs
    • Properties: Sql, Parameters, TempTableSetupSql
    • Validation: Record compiles
  • 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
  • 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

  • 020: Create IFilterHandler interface

    • Location: NEW/src/JdeScoping.SearchProcessing/Interfaces/IFilterHandler.cs
    • Methods: IsEnabled, Apply, Priority property
    • Validation: Interface compiles
  • 021: Create FilterResult record

    • Location: NEW/src/JdeScoping.SearchProcessing/Models/FilterResult.cs
    • Properties: SetupSql (IReadOnlyList), Parameters (IDictionary)
    • Validation: Record compiles
  • 022: Create ISearchQueryBuilder interface

    • Location: NEW/src/JdeScoping.SearchProcessing/Interfaces/ISearchQueryBuilder.cs
    • Methods: BuildSearchQuery, BuildMisQuery, BuildMisNonMatchQuery
    • Validation: Interface compiles

Phase 7: Filter Handlers

  • 023: Create FilterHandlerBase abstract class

    • Location: NEW/src/JdeScoping.SearchProcessing/FilterHandlers/FilterHandlerBase.cs
    • Common functionality for all handlers
    • Validation: Abstract class compiles
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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

  • 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
  • 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

  • 034: Create ISearchProcessor interface

    • Note: Existing interface at NEW/src/JdeScoping.Core/Interfaces/ISearchProcessor.cs
    • Methods: ExecuteSearchAsync (IAsyncEnumerable), ExecuteSearchToModelAsync
    • Validation: Interface compiles
  • 035: Create IWorkOrderTraversalService interface

    • Location: NEW/src/JdeScoping.SearchProcessing/Interfaces/IWorkOrderTraversalService.cs
    • Method: TraverseDownstreamAsync
    • Validation: Interface compiles
  • 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
  • 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

  • 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
  • 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

  • 040: Create test project

    • Location: NEW/tests/JdeScoping.SearchProcessing.Tests/JdeScoping.SearchProcessing.Tests.csproj
    • Dependencies: xUnit, Shouldly, NSubstitute
    • Validation: Test project builds
  • 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)
  • 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)
  • 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)
  • 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)
  • 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

  • 046: Run full test suite

    • Command: dotnet test NEW/tests/JdeScoping.SearchProcessing.Tests/
    • Validation: All 64 tests pass
  • 047: Verify solution builds

    • Command: dotnet build NEW/JdeScoping.sln
    • Validation: No errors or warnings
  • 048: Run OpenSpec validation

    • Command: openspec validate implement-search-processing --strict
    • Validation: No validation errors - "Change 'implement-search-processing' is valid"
  • 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