Files
jdescopingtool/PLANS/2026-01-01-architecture-cleanup-design.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

309 lines
12 KiB
Markdown

# 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
<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:**
```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
<ItemGroup>
<ProjectReference Include="..\JdeScoping.Core\JdeScoping.Core.csproj" />
</ItemGroup>
```
**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
<!-- 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:**
```xml
<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 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