Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
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 buildsucceeds
- Location:
-
002: Add project reference to JdeScoping.Host
- Location:
NEW/src/JdeScoping.Host/JdeScoping.Host.csproj - Validation: Solution builds with new reference
- Location:
-
003: Create SearchProcessingOptions configuration class
- Location:
NEW/src/JdeScoping.SearchProcessing/Configuration/SearchProcessingConfiguration.cs - Properties: QueryTimeoutSeconds, MaxTraversalIterations, EnableDebugSql, DebugSqlPath
- Validation: Options bind from appsettings.json
- Location:
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
- Location:
-
005: Create OutputTableAttribute
- Location:
NEW/src/JdeScoping.SearchProcessing/Attributes/OutputTableAttribute.cs - Properties: TabName, TableName, ShowHeader
- Validation: Attribute compiles and is applicable to classes/records
- Location:
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
- Location:
-
007: Create ItemNumberFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ItemNumberFilterEntry.cs - Properties: ItemNumber, ItemDescription
- Validation: Record compiles with proper attributes
- Location:
-
008: Create ProfitCenterFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ProfitCenterFilterEntry.cs - Properties: Code, Description
- Validation: Record compiles with proper attributes
- Location:
-
009: Create WorkCenterFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/WorkCenterFilterEntry.cs - Properties: Code, Description
- Validation: Record compiles with proper attributes
- Location:
-
010: Create OperatorFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/OperatorFilterEntry.cs - Properties: AddressNumber (long), UserID, FullName
- Validation: Record compiles with proper attributes
- Location:
-
011: Create ComponentLotFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ComponentLotFilterEntry.cs - Properties: LotNumber, ItemNumber
- Validation: Record compiles with proper attributes
- Location:
-
012: Create ItemOperationMisFilterEntry record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterEntries/ItemOperationMisFilterEntry.cs - Properties: ItemNumber, OperationNumber, MisNumber, MisRevision
- Validation: Record compiles with proper attributes
- Location:
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
- Location:
-
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
- Location:
-
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
- Location:
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
- Location:
-
017: Create SearchQueryResult record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/SearchQueryResult.cs - Properties: Sql, Parameters, TempTableSetupSql
- Validation: Record compiles
- Location:
-
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
- Location:
-
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
- Location:
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
- Location:
-
021: Create FilterResult record
- Location:
NEW/src/JdeScoping.SearchProcessing/Models/FilterResult.cs - Properties: SetupSql (IReadOnlyList), Parameters (IDictionary)
- Validation: Record compiles
- Location:
-
022: Create ISearchQueryBuilder interface
- Location:
NEW/src/JdeScoping.SearchProcessing/Interfaces/ISearchQueryBuilder.cs - Methods: BuildSearchQuery, BuildMisQuery, BuildMisNonMatchQuery
- Validation: Interface compiles
- Location:
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
-
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
- Location:
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
- Location:
-
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
- Location:
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
- Note: Existing interface at
-
035: Create IWorkOrderTraversalService interface
- Location:
NEW/src/JdeScoping.SearchProcessing/Interfaces/IWorkOrderTraversalService.cs - Method: TraverseDownstreamAsync
- Validation: Interface compiles
- Location:
-
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
- Location:
-
037: Create SearchProcessor service
- Location:
NEW/src/JdeScoping.SearchProcessing/Services/SearchProcessor.cs - Constructor: IDbConnectionFactory, ISearchQueryBuilder, IWorkOrderTraversalService, ILotFinderRepository, ILogger
- Implements full search flow:
- Enrich filter entries via repository lookups
- Build query via SqlKata
- Execute temp table setup
- Call downstream traversal
- Execute result query
- Optionally extract MIS data
- Validation: Service compiles, all dependencies injected
- Location:
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
- Location:
-
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
- Location:
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
- Location:
-
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)
- Location:
-
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)
- Location:
-
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)
- Location:
-
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)
- Location:
-
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)
- Location:
Phase 12: Verification
-
046: Run full test suite
- Command:
dotnet test NEW/tests/JdeScoping.SearchProcessing.Tests/ - Validation: All 64 tests pass
- Command:
-
047: Verify solution builds
- Command:
dotnet build NEW/JdeScoping.sln - Validation: No errors or warnings
- Command:
-
048: Run OpenSpec validation
- Command:
openspec validate implement-search-processing --strict - Validation: No validation errors - "Change 'implement-search-processing' is valid"
- Command:
-
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