Set up repository with legacy .NET Framework 4.8 source (OLD/), new .NET 10 Blazor solution (NEW/), OpenSpec specifications, documentation, and project configuration.
12 KiB
Architecture Cleanup Design
Date: 2026-01-01 Status: Approved Source: PLANS/architecture-review.md
Summary
This design addresses all 6 issues identified in the architecture review to achieve full Clean Architecture compliance.
Key decisions:
- Create new
JdeScoping.Infrastructureproject for Oracle/File/LDAP implementations - Merge all
ILotFinderRepositorypartials into Core - Keep ViewModels in Core, have Client reference Core
- Move DI extensions to their respective projects
- Merge SearchProcessing into DataAccess (including tests)
- Keep
IExcelWriterin Core, ExcelExport implements it
Target Project Structure
NEW/src/
├── JdeScoping.Core # Domain layer (PURE - no infrastructure deps)
│ ├── Models/ # Domain entities
│ ├── ViewModels/ # DTOs (shared with Client)
│ ├── Interfaces/ # All repository interfaces
│ ├── Options/ # Configuration POCOs
│ └── Helpers/ # Pure helper functions
│
├── JdeScoping.Infrastructure # NEW: All external system implementations
│ ├── Sources/
│ │ ├── Jde/ # JdeOracleDataSource, JdeFileDataSource
│ │ └── Cms/ # CmsOracleDataSource, CmsFileDataSource
│ ├── Auth/ # LdapAuthService
│ └── Extensions/ # AddInfrastructure() DI registration
│
├── JdeScoping.DataAccess # SQL Server cache + search processing
│ ├── Repositories/ # LotFinderRepository (implements Core interface)
│ ├── Services/ # SearchProcessor (merged from SearchProcessing)
│ └── Extensions/ # AddDataAccess() DI registration
│
├── JdeScoping.DataSync # Background sync service
├── JdeScoping.ExcelExport # Excel generation (implements Core.IExcelWriter)
├── JdeScoping.Api # Web API controllers
├── JdeScoping.Host # Composition root
├── JdeScoping.Client # Blazor WASM (references Core for ViewModels)
└── JdeScoping.Database # DbUp migrations
Dependency Graph
┌─────────────────┐
│ HOST │
│ (Composition │
│ Root) │
└────────┬────────┘
│ references all
┌─────────────┬───────────┼───────────┬─────────────┐
▼ ▼ ▼ ▼ ▼
┌─────────────┐ ┌───────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐
│ API │ │ DataAccess│ │DataSync │ │ExcelExp │ │Infrastructure│
└──────┬──────┘ └─────┬─────┘ └────┬────┘ └────┬────┘ └──────┬──────┘
│ │ │ │ │
│ │ ├───────────┘ │
│ │ │ (uses DataAccess) │
└──────────────┴────────────┴─────────────────────────┘
│
▼
┌─────────────────┐
│ CORE │
│ (Pure Domain) │
└─────────────────┘
▲
│
┌─────────────────┐
│ CLIENT │
│ (Blazor WASM) │
└─────────────────┘
Project References:
| Project | References |
|---|---|
| Host | Api, Core, DataAccess, DataSync, ExcelExport, Infrastructure, Database |
| Api | Core |
| DataAccess | Core |
| DataSync | Core, DataAccess |
| ExcelExport | Core |
| Infrastructure | Core |
| Client | Core |
| Database | (none) |
Issue 1: Interface Consolidation
Merge all ILotFinderRepository partials into Core:
Target structure:
Core/Interfaces/
├── ILotFinderRepository.cs # Base partial
├── ILotFinderRepository.SearchOperations.cs # Queue, execute, get results
├── ILotFinderRepository.SearchManagement.cs # CRUD for searches
├── ILotFinderRepository.Lookups.cs # Autocomplete queries
└── ILotFinderRepository.DataSync.cs # Sync status, bulk operations
Steps:
- Move
DataAccess/Interfaces/ILotFinderRepository.DataSync.cs→Core/Interfaces/ - Move
DataAccess/Interfaces/ILotFinderRepository.SearchManagement.cs→Core/Interfaces/ - Merge duplicate
.Lookups.csfiles (compare methods, keep all unique ones) - Delete
DataAccess/Interfaces/ILotFinderRepository*.csfiles - Update
LotFinderRepositoryimplementation to useJdeScoping.Core.Interfaces - Update DI registration to register
JdeScoping.Core.Interfaces.ILotFinderRepository
Issue 2: Infrastructure Project
Create new JdeScoping.Infrastructure project:
Structure:
JdeScoping.Infrastructure/
├── JdeScoping.Infrastructure.csproj
├── Sources/
│ ├── Jde/
│ │ ├── JdeOracleDataSource.cs
│ │ └── JdeFileDataSource.cs
│ └── Cms/
│ ├── CmsOracleDataSource.cs
│ └── CmsFileDataSource.cs
├── Auth/
│ └── LdapAuthService.cs
└── Extensions/
└── InfrastructureServiceExtensions.cs
Package references (Infrastructure.csproj):
<PackageReference Include="Dapper" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" />
<PackageReference Include="System.DirectoryServices.Protocols" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
Files to move from Core:
Core/Repositories/Jde/JdeOracleDataSource.cs→Infrastructure/Sources/Jde/Core/Repositories/Jde/JdeFileDataSource.cs→Infrastructure/Sources/Jde/Core/Repositories/Cms/CmsOracleDataSource.cs→Infrastructure/Sources/Cms/Core/Repositories/Cms/CmsFileDataSource.cs→Infrastructure/Sources/Cms/Core/Auth/LdapAuthService.cs→Infrastructure/Auth/
Issue 3: DI Registration Distribution
Move extensions from Core to respective projects:
| Current Location | Target Location |
|---|---|
Core/Extensions/DataSourceServiceExtensions.cs |
Infrastructure/Extensions/ |
Core/Extensions/AuthServiceExtensions.cs |
Infrastructure/Extensions/ |
Core/Extensions/DataSyncServiceExtensions.cs |
DataSync/Extensions/ |
Core/Extensions/ExcelExportServiceExtensions.cs |
ExcelExport/Extensions/ |
Core/Extensions/SearchProcessingServiceExtensions.cs |
Delete (merged) |
Host Program.cs:
builder.Services.AddDataAccess(builder.Configuration);
builder.Services.AddDataSync(builder.Configuration);
builder.Services.AddExcelExport(builder.Configuration);
builder.Services.AddInfrastructure(builder.Configuration);
Core/Extensions after cleanup (keep only pure extensions):
ItemExtensions.csLotExtensions.csJdeUserExtensions.csProfitCenterExtensions.csWorkCenterExtensions.csWorkOrderExtensions.cs
Issue 4: ViewModels (Client Integration)
Client references Core for shared ViewModels.
Update Client.csproj:
<ItemGroup>
<ProjectReference Include="..\JdeScoping.Core\JdeScoping.Core.csproj" />
</ItemGroup>
Delete duplicate Client models:
Client/Models/ItemViewModel.csClient/Models/ProfitCenterViewModel.csClient/Models/WorkCenterViewModel.csClient/Models/WorkOrderViewModel.csClient/Models/PartOperationViewModel.csClient/Models/SearchViewModel.cs
Keep Client-only models:
Client/Models/LoginModel.cs- Other Client-specific models (check for Core equivalents first)
Issue 5: Merge SearchProcessing into DataAccess
Files to move:
SearchProcessing/Services/SearchProcessor.cs → DataAccess/Services/
SearchProcessing/Templates/QueryTemplate.cs → DataAccess/Templates/
SearchProcessing/Templates/*.cs → DataAccess/Templates/
Test files to merge:
tests/SearchProcessing.Tests/* → tests/DataAccess.Tests/Services/
Cleanup:
- Delete
JdeScoping.SearchProcessingproject folder - Delete
tests/SearchProcessing.Testsproject folder - Remove both from solution file
- Update Host references
Issue 6: Excel Export Cleanup
Unify with IExcelWriter in Core:
Delete:
Core/Extensions/ExcelExportServiceExtensions.csExcelExport/Interfaces/IExcelExportService.cs
Keep/Update:
Core/Interfaces/IExcelWriter.cs(single interface)ExcelExport/Services/ExcelWriter.cs(implements Core.IExcelWriter)ExcelExport/Extensions/ExcelExportServiceExtensions.cs(AddExcelExport)
Core.csproj After Cleanup
Remove these packages:
<!-- DELETE THESE -->
<PackageReference Include="ClosedXML" Version="0.105.0" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.3" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.26.0" />
<PackageReference Include="System.DirectoryServices.Protocols" Version="10.0.1" />
Keep these packages:
<PackageReference Include="Cronos" Version="0.11.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.1" />
Verification Checklist
Build & Tests:
dotnet buildsucceeds for entire solution- All existing tests pass
- No new compiler warnings related to the refactoring
Core Layer Purity:
Core.csprojhas NO infrastructure packages- Core contains ONLY: Models, ViewModels, Interfaces, Options, Helpers, pure extensions
- No
usingstatements referencing infrastructure namespaces in Core
Dependency Direction:
- No circular references
- Only Host references Infrastructure
- Client successfully references Core (WASM compatible)
DI Resolution:
- All interfaces resolve correctly at runtime
- API endpoints work end-to-end
- DataSync background service starts correctly
- SignalR hub connects and pushes updates
Cleanup Complete:
SearchProcessingproject deleted from solutionSearchProcessing.Testsproject deleted from solution- No orphaned files in Core (old implementations)
- No duplicate interface definitions