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.
This commit is contained in:
+272
@@ -0,0 +1,272 @@
|
||||
# Search Processing Specification Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
This document captures ADDED and MODIFIED requirements for the search processing subsystem specific to the .NET 10 migration. It supplements the base specification at `openspec/specs/search-processing/spec.md`.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: SqlKata Query Builder Integration
|
||||
|
||||
The system SHALL use SqlKata fluent query builder instead of T4 text templates for dynamic SQL generation.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- `SearchModel` containing filter criteria and enriched filter entries
|
||||
- `SqlServerCompiler` for T-SQL generation
|
||||
|
||||
#### Outputs
|
||||
|
||||
- `SearchQueryResult` record containing:
|
||||
- `Sql`: Parameterized T-SQL query string
|
||||
- `Parameters`: Dictionary of named parameter values
|
||||
- `TempTableSetupSql`: List of temp table creation/population statements
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- SqlKata `SqlServerCompiler` SHALL be registered as a singleton (thread-safe)
|
||||
- All queries SHALL use named parameters (not positional)
|
||||
- Parameter names SHALL match legacy convention (`@p_*` prefix)
|
||||
- Generated SQL SHALL produce equivalent results to legacy QueryTemplate.tt
|
||||
|
||||
#### Scenario: Build query with SqlKata
|
||||
|
||||
- **WHEN** `ISearchQueryBuilder.BuildSearchQuery(model)` is called
|
||||
- **THEN** SqlKata generates parameterized SQL with named bindings
|
||||
- **AND** the `SearchQueryResult.Sql` is executable via Dapper
|
||||
- **AND** `SearchQueryResult.Parameters` contains all TVP parameters
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Filter Handler Pattern
|
||||
|
||||
The system SHALL use a composable filter handler pattern for modular query building.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- `SearchModel` with active filter criteria
|
||||
- `SqlServerCompiler` for SQL compilation
|
||||
|
||||
#### Outputs
|
||||
|
||||
- `FilterResult` record containing:
|
||||
- `SetupSql`: List of temp table setup statements
|
||||
- `Parameters`: Dictionary of parameters for this filter
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- Each filter type SHALL have a dedicated `IFilterHandler` implementation
|
||||
- Filter handlers SHALL be registered in dependency injection container
|
||||
- Handlers SHALL execute in priority order (lower priority = earlier execution)
|
||||
- Handler priorities SHALL ensure dependent temp tables exist before use:
|
||||
- WorkOrder: 10
|
||||
- ItemNumber: 20
|
||||
- ComponentLot: 30
|
||||
- ProfitCenter: 40
|
||||
- WorkCenter: 50
|
||||
- Operator: 60
|
||||
- ItemOperationMis: 70
|
||||
- Timespan: 80
|
||||
|
||||
#### Scenario: Execute filter handlers in order
|
||||
|
||||
- **WHEN** search criteria includes work orders, items, and operators
|
||||
- **THEN** WorkOrderFilterHandler executes first (priority 10)
|
||||
- **AND** ItemNumberFilterHandler executes second (priority 20)
|
||||
- **AND** OperatorFilterHandler executes later (priority 60)
|
||||
|
||||
---
|
||||
|
||||
### Requirement: IAsyncEnumerable Result Streaming
|
||||
|
||||
The system SHALL support streaming large result sets using `IAsyncEnumerable<T>`.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- `SearchModel` with executed query
|
||||
- `CancellationToken` for cooperative cancellation
|
||||
|
||||
#### Outputs
|
||||
|
||||
- `IAsyncEnumerable<SearchResult>` streaming results one at a time
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- Streaming SHALL use Dapper's `QueryUnbufferedAsync` method
|
||||
- Cancellation SHALL be supported via `[EnumeratorCancellation]` attribute
|
||||
- Memory allocation SHALL remain constant regardless of result set size
|
||||
- Consumer MAY materialize results using `ToListAsync()` when needed
|
||||
|
||||
#### Scenario: Stream large result set
|
||||
|
||||
- **WHEN** search returns 10,000 work orders
|
||||
- **THEN** results stream via `IAsyncEnumerable<SearchResult>`
|
||||
- **AND** memory usage remains constant during enumeration
|
||||
- **AND** `await foreach` consumes results incrementally
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Async-First Design
|
||||
|
||||
The system SHALL use async methods throughout the search processing pipeline.
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- All repository methods SHALL accept `CancellationToken` parameter
|
||||
- All database operations SHALL use async Dapper methods (`QueryAsync`, `ExecuteAsync`)
|
||||
- Long-running operations SHALL respect cancellation tokens
|
||||
- `ISearchProcessor.ExecuteSearchAsync` SHALL be the primary entry point
|
||||
|
||||
#### Scenario: Cancel long-running search
|
||||
|
||||
- **WHEN** a search is in progress and cancellation is requested
|
||||
- **THEN** the operation throws `OperationCanceledException`
|
||||
- **AND** database connections are properly disposed
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Configuration via IOptions Pattern
|
||||
|
||||
The system SHALL use `IOptions<SearchProcessingOptions>` for configuration.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- `appsettings.json` section: `SearchProcessing`
|
||||
|
||||
#### Outputs
|
||||
|
||||
- Strongly-typed `SearchProcessingOptions` injected via DI
|
||||
|
||||
#### Configuration Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `QueryTimeoutSeconds` | int | 600 | SQL query timeout |
|
||||
| `MaxTraversalIterations` | int | 20 | Downstream traversal limit |
|
||||
| `EnableDebugSql` | bool | false | Write SQL to debug files |
|
||||
| `DebugSqlPath` | string? | null | Path for debug SQL files |
|
||||
|
||||
#### Scenario: Configure query timeout
|
||||
|
||||
- **WHEN** `SearchProcessingOptions.QueryTimeoutSeconds` is set to 900
|
||||
- **THEN** Dapper queries use `commandTimeout: 900`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Service Registration Extension
|
||||
|
||||
The system SHALL provide an `AddSearchProcessing` extension method for DI registration.
|
||||
|
||||
#### Service Lifetimes
|
||||
|
||||
| Service | Lifetime | Rationale |
|
||||
|---------|----------|-----------|
|
||||
| `SqlServerCompiler` | Singleton | Thread-safe, stateless |
|
||||
| `IFilterHandler` implementations | Scoped | Per-request state |
|
||||
| `ISearchQueryBuilder` | Scoped | Uses scoped handlers |
|
||||
| `ISearchProcessor` | Scoped | Uses scoped repositories |
|
||||
| `IWorkOrderTraversalService` | Scoped | Uses connection factory |
|
||||
|
||||
#### Scenario: Register search processing services
|
||||
|
||||
- **WHEN** `services.AddSearchProcessing(configuration)` is called
|
||||
- **THEN** all search processing services are registered
|
||||
- **AND** `ISearchProcessor` can be resolved from service provider
|
||||
|
||||
---
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Work Order Traversal
|
||||
|
||||
The system SHALL execute downstream work order traversal via stored procedure `dbo.TraverseWorkOrders` instead of inline WHILE loop in generated SQL.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- Active database connection with `#Temp_WO` temporary table populated
|
||||
- Maximum iteration count (default 20)
|
||||
|
||||
#### Outputs
|
||||
|
||||
- Updated `#Temp_WO` table with downstream work orders flagged
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- `IWorkOrderTraversalService.TraverseDownstreamAsync` SHALL call stored procedure
|
||||
- Stored procedure SHALL contain iterative WHILE loop logic
|
||||
- Single stored procedure call SHALL replace 20 inline iterations
|
||||
- Transaction scope SHALL be maintained within stored procedure
|
||||
|
||||
#### Scenario: Execute downstream traversal via stored procedure
|
||||
|
||||
- **WHEN** initial work orders are flagged in `#Temp_WO`
|
||||
- **THEN** `dbo.TraverseWorkOrders` stored procedure is called
|
||||
- **AND** downstream work orders are added with PartsList and CARDEX flags
|
||||
- **AND** split orders are detected and flagged
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Filter Entry Types
|
||||
|
||||
The system SHALL use C# record types for filter entry DTOs to provide immutability and value semantics.
|
||||
|
||||
#### Inputs
|
||||
|
||||
- Raw filter values from `SearchCriteria`
|
||||
- Reference data lookups from `ILotFinderRepository`
|
||||
|
||||
#### Outputs
|
||||
|
||||
- Immutable record instances with output attributes for Excel export
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- All filter entry types SHALL be declared as C# records
|
||||
- Records SHALL use primary constructor syntax
|
||||
- Output attributes SHALL be applied using `[property:]` target
|
||||
- Records SHALL provide value-based equality for testing
|
||||
|
||||
#### Scenario: Create immutable filter entry record
|
||||
|
||||
- **WHEN** a WorkOrderFilterEntry is created with WorkOrderNumber 12345 and ItemNumber "ITEM-001"
|
||||
- **THEN** the record is immutable (properties are init-only)
|
||||
- **AND** two records with same values are considered equal
|
||||
|
||||
---
|
||||
|
||||
### Requirement: SQL Client Package
|
||||
|
||||
The system SHALL use `Microsoft.Data.SqlClient` instead of deprecated `System.Data.SqlClient` for SQL Server connectivity.
|
||||
|
||||
#### Business Rules
|
||||
|
||||
- All SQL Server connections SHALL use `Microsoft.Data.SqlClient.SqlConnection`
|
||||
- All SQL commands SHALL use `Microsoft.Data.SqlClient.SqlCommand`
|
||||
- NuGet package `Microsoft.Data.SqlClient` version 5.2+ SHALL be referenced
|
||||
- Code SHALL NOT reference `System.Data.SqlClient` namespace
|
||||
|
||||
#### Scenario: Create SQL connection with modern client
|
||||
|
||||
- **WHEN** `IDbConnectionFactory.CreateLotFinderConnectionAsync` is called
|
||||
- **THEN** a `Microsoft.Data.SqlClient.SqlConnection` instance is returned
|
||||
- **AND** connection supports all modern SQL Server features
|
||||
|
||||
---
|
||||
|
||||
## Migration Notes
|
||||
|
||||
| Legacy Pattern | New Pattern | Status |
|
||||
|----------------|-------------|--------|
|
||||
| T4 Text Template | SqlKata fluent builder | ADDED |
|
||||
| Inline WHILE loop | Stored procedure | MODIFIED |
|
||||
| Filter entry classes | Record types | MODIFIED |
|
||||
| Synchronous Dapper | Async Dapper | MODIFIED |
|
||||
| System.Data.SqlClient | Microsoft.Data.SqlClient | MODIFIED |
|
||||
| Static class methods | DI-registered services | MODIFIED |
|
||||
| Newtonsoft.Json | System.Text.Json | Retained in domain models |
|
||||
|
||||
---
|
||||
|
||||
## Open Questions
|
||||
|
||||
None - all design decisions resolved per base specification.
|
||||
Reference in New Issue
Block a user