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

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:

  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.csCore/Interfaces/
  2. Move DataAccess/Interfaces/ILotFinderRepository.SearchManagement.csCore/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):

<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.csInfrastructure/Sources/Jde/
  • Core/Repositories/Jde/JdeFileDataSource.csInfrastructure/Sources/Jde/
  • Core/Repositories/Cms/CmsOracleDataSource.csInfrastructure/Sources/Cms/
  • Core/Repositories/Cms/CmsFileDataSource.csInfrastructure/Sources/Cms/
  • Core/Auth/LdapAuthService.csInfrastructure/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.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:

<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:

<!-- 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 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