604bfe919c
Apply comprehensive fixes from code reviews including: - Extract shared utilities (SqlFormatHelper, CellValueConverter, DbDestinationBase) - Add interface abstractions (IAuthenticationService, IDatabaseMigrator, IMisQueryBuilder) - Implement SecureStore for encrypted secrets storage - Fix error handling with proper HTTP status codes and logging - Optimize double enumeration in DevEtlRegistry - Add DataSync.Dev README for developer onboarding - Extract filter panel base classes to reduce duplication - Update code review docs to mark all issues as fixed
202 lines
6.0 KiB
Markdown
202 lines
6.0 KiB
Markdown
# Code Review: JdeScoping.Core
|
|
|
|
**Project Path:** `NEW/src/JdeScoping.Core`
|
|
**Layer:** Domain
|
|
**Purpose:** Core models, DTOs, interfaces
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
The JdeScoping.Core project is the domain layer containing core models, DTOs, interfaces, and shared contracts. The codebase demonstrates **good architectural practices** with clear separation of concerns, proper use of nullable reference types, and consistent documentation.
|
|
|
|
**Overall Grade: B+**
|
|
|
|
| Category | Rating | Notes |
|
|
|----------|--------|-------|
|
|
| SOLID Principles | Good | Minor ISP violation |
|
|
| Clean Architecture | Excellent | No inappropriate dependencies |
|
|
| Code Organization | Excellent | Well-organized structure |
|
|
| Error Handling | Good | `TryGetCriteria` method with logging support |
|
|
| Testability | Excellent | Interface-based design |
|
|
| Code Duplication | Fair | Repeated JDE date conversion pattern |
|
|
| Async Patterns | Good | Consistent naming, CancellationToken support |
|
|
| Null Safety | Good | Nullable enabled with proper annotations |
|
|
| Documentation | Excellent | Comprehensive XML documentation |
|
|
|
|
---
|
|
|
|
## 1. SOLID Principles
|
|
|
|
### Single Responsibility Principle (SRP)
|
|
|
|
**Positive:** Most classes adhere well to SRP - each model represents a single domain concept.
|
|
|
|
### Interface Segregation Principle (ISP)
|
|
|
|
~~**Issue: IExcelExportService uses `object` parameter**~~ ✅ FIXED
|
|
|
|
~~```csharp
|
|
public interface IExcelExportService
|
|
{
|
|
Task<byte[]> GenerateAsync(object search, CancellationToken cancellationToken = default);
|
|
}
|
|
```~~
|
|
|
|
~~**Recommendation:** Change to use strongly-typed `SearchModel` parameter.~~
|
|
|
|
**Resolution:** Changed `IExcelExportService.GenerateAsync` to accept `Core.Models.SearchResults.SearchModel` instead of `object`. The `ExcelExportService` implementation maps to its internal `ExcelIO.Models.Reporting.SearchModel` for Excel generation.
|
|
|
|
### Dependency Inversion Principle (DIP)
|
|
|
|
**Positive:** Service interfaces properly defined in Core layer with clean abstractions.
|
|
|
|
---
|
|
|
|
## 2. Clean Architecture
|
|
|
|
### Layer Separation
|
|
|
|
**Excellent:** Core project maintains proper architectural boundaries:
|
|
- No references to infrastructure concerns
|
|
- Only depends on abstraction packages
|
|
- Defines contracts that outer layers implement
|
|
|
|
### ApiContracts Placement
|
|
|
|
The `ApiContracts` folder containing API client interfaces is appropriately placed in Core.
|
|
|
|
---
|
|
|
|
## 3. Code Organization
|
|
|
|
### Folder Structure
|
|
|
|
**Excellent:**
|
|
```
|
|
JdeScoping.Core/
|
|
├── ApiContracts/Results/
|
|
├── Helpers/
|
|
├── Interfaces/
|
|
├── Models/
|
|
│ ├── Auth/, Enums/, Infrastructure/
|
|
│ ├── Inventory/, Lookup/, Organization/
|
|
│ ├── Pipelines/, Quality/, Search/
|
|
│ ├── SearchResults/, WorkOrders/
|
|
├── Options/
|
|
└── ViewModels/
|
|
```
|
|
|
|
### Partial Classes for Repository
|
|
|
|
Using partial classes to split `ILotFinderRepository` by functional area is a good organizational choice.
|
|
|
|
### Issues
|
|
|
|
**Issue: Inconsistent Record/Class Usage**
|
|
|
|
The codebase mixes classes and records inconsistently for DTOs.
|
|
|
|
**Recommendation:** Establish consistent pattern - use records for immutable DTOs.
|
|
|
|
---
|
|
|
|
## 4. Error Handling
|
|
|
|
~~**Issue: Silent Deserialization Failure**~~ ✅ FIXED
|
|
|
|
**Resolution:** Added `TryGetCriteria(out SearchCriteria? criteria, ILogger? logger = null)` method that:
|
|
- Returns `true` if deserialization succeeded or JSON was empty
|
|
- Returns `false` if deserialization failed
|
|
- Logs at Warning level when logger is provided
|
|
- Property getter uses the method without logging for backwards compatibility
|
|
- Services that need logging can call `TryGetCriteria` directly with their logger
|
|
|
|
---
|
|
|
|
## 5. Testability
|
|
|
|
**Excellent:** Interface-based design with all services defined as interfaces, enabling easy mocking.
|
|
|
|
---
|
|
|
|
## 6. Code Duplication
|
|
|
|
### DRY Violation in Domain Models
|
|
|
|
Multiple domain models contain identical patterns for JDE date/time conversion:
|
|
|
|
```csharp
|
|
private int LastUpdateDate { get; set; }
|
|
private int LastUpdateTime { get; set; }
|
|
public DateTime? LastUpdateDt => JdeDateConverter.ToDateTime(LastUpdateDate, LastUpdateTime);
|
|
```
|
|
|
|
Pattern repeated in 13+ files.
|
|
|
|
**Recommendation:** Document why this pattern is intentionally repeated (e.g., for Dapper mapping compatibility).
|
|
|
|
### Duplicate ViewModel Classes
|
|
|
|
`LotViewModel` and `ComponentLotViewModel` have identical properties.
|
|
|
|
**Recommendation:** Consolidate or have `ComponentLotViewModel` inherit from `LotViewModel`.
|
|
|
|
---
|
|
|
|
## 7. Async Patterns
|
|
|
|
**Good:** Consistent `Async` suffix naming, all async interface methods include `CancellationToken` parameters with defaults.
|
|
|
|
---
|
|
|
|
## 8. Null Safety
|
|
|
|
**Good:** Nullable reference types enabled with proper annotations.
|
|
|
|
**Issue: Inconsistent Null Guard in Constructor**
|
|
|
|
```csharp
|
|
public SearchViewModel(Search search)
|
|
{
|
|
if (search == null) return; // Silent return on null
|
|
}
|
|
```
|
|
|
|
**Recommendation:** Throw `ArgumentNullException` or use factory method pattern.
|
|
|
|
---
|
|
|
|
## 9. Documentation
|
|
|
|
**Excellent:** Nearly all public members have XML documentation with `<summary>`, `<param>`, and `<returns>` tags.
|
|
|
|
---
|
|
|
|
## 10. Additional Observations
|
|
|
|
### Well-Designed API Result Pattern
|
|
|
|
The `ApiResult<T>` discriminated union using OneOf provides compile-time safety for error handling.
|
|
|
|
### Data Type Mismatch
|
|
|
|
`AddressNumber` is `long` in `JdeUser` but `int` in `OperatorViewModel` - potential data loss.
|
|
|
|
**Recommendation:** Change `OperatorViewModel.AddressNumber` to `long`.
|
|
|
|
---
|
|
|
|
## Recommendations Summary
|
|
|
|
### Important
|
|
1. ~~Fix `IExcelExportService` interface to use strongly-typed parameter~~ ✅ FIXED
|
|
2. Consolidate duplicate ViewModels
|
|
3. Fix `AddressNumber` type mismatch
|
|
4. ~~Add logging to `Search.Criteria` deserialization~~ ✅ FIXED - Added `TryGetCriteria` method with logging support
|
|
|
|
### Suggestions
|
|
1. Document JDE date pattern rationale
|
|
2. Establish guideline for records vs classes for DTOs
|
|
3. Fix null guard in `SearchViewModel` constructor
|