# 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:** 1. Create new `JdeScoping.Infrastructure` project for Oracle/File/LDAP implementations 2. Merge all `ILotFinderRepository` partials into Core 3. Keep ViewModels in Core, have Client reference Core 4. Move DI extensions to their respective projects 5. Merge SearchProcessing into DataAccess (including tests) 6. Keep `IExcelWriter` in 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:** 1. Move `DataAccess/Interfaces/ILotFinderRepository.DataSync.cs` → `Core/Interfaces/` 2. Move `DataAccess/Interfaces/ILotFinderRepository.SearchManagement.cs` → `Core/Interfaces/` 3. Merge duplicate `.Lookups.cs` files (compare methods, keep all unique ones) 4. Delete `DataAccess/Interfaces/ILotFinderRepository*.cs` files 5. Update `LotFinderRepository` implementation to use `JdeScoping.Core.Interfaces` 6. 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):** ```xml ``` **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:** ```csharp 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.cs` - `LotExtensions.cs` - `JdeUserExtensions.cs` - `ProfitCenterExtensions.cs` - `WorkCenterExtensions.cs` - `WorkOrderExtensions.cs` --- ## Issue 4: ViewModels (Client Integration) Client references Core for shared ViewModels. **Update Client.csproj:** ```xml ``` **Delete duplicate Client models:** - `Client/Models/ItemViewModel.cs` - `Client/Models/ProfitCenterViewModel.cs` - `Client/Models/WorkCenterViewModel.cs` - `Client/Models/WorkOrderViewModel.cs` - `Client/Models/PartOperationViewModel.cs` - `Client/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.SearchProcessing` project folder - Delete `tests/SearchProcessing.Tests` project folder - Remove both from solution file - Update Host references --- ## Issue 6: Excel Export Cleanup Unify with `IExcelWriter` in Core: **Delete:** - `Core/Extensions/ExcelExportServiceExtensions.cs` - `ExcelExport/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:** ```xml ``` **Keep these packages:** ```xml ``` --- ## Verification Checklist **Build & Tests:** - [ ] `dotnet build` succeeds for entire solution - [ ] All existing tests pass - [ ] No new compiler warnings related to the refactoring **Core Layer Purity:** - [ ] `Core.csproj` has NO infrastructure packages - [ ] Core contains ONLY: Models, ViewModels, Interfaces, Options, Helpers, pure extensions - [ ] No `using` statements 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:** - [ ] `SearchProcessing` project deleted from solution - [ ] `SearchProcessing.Tests` project deleted from solution - [ ] No orphaned files in Core (old implementations) - [ ] No duplicate interface definitions