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
5.9 KiB
Code Review: JdeScoping.DataAccess
Project Path: NEW/src/JdeScoping.DataAccess
Layer: Infrastructure
Purpose: Repositories, Dapper queries
Executive Summary
The JdeScoping.DataAccess project is a well-structured infrastructure layer implementing the repository pattern with Dapper for data access. The code demonstrates solid architectural decisions, good separation of concerns, and proper use of modern C# features.
Overall Assessment: Good with room for improvement
| Category | Rating | Notes |
|---|---|---|
| SOLID Principles | Good | Minor SRP concerns in SearchProcessor |
| Clean Architecture | Excellent | Proper layer separation |
| Code Organization | Good | Well-organized partial classes |
| Error Handling | Good | Consistent exception hierarchy |
| Testability | Very Good | Interface-based design enables mocking |
| Code Duplication | ||
| Async Patterns | Good | Proper async/await usage |
| Null Safety | Needs Improvement | Inconsistent nullable handling |
| Documentation | Very Good | Comprehensive XML comments |
1. SOLID Principles
Single Responsibility Principle (SRP)
Positive: Clear separation between LotFinderRepository, SearchProcessor, and WorkOrderTraversalService.
Issue: SearchProcessor has multiple responsibilities
Handles search query execution, MIS data extraction, debug SQL file writing, and MisQueryBuilder instantiation.
Recommendation: Inject MisQueryBuilder through DI rather than creating internally.
Dependency Inversion Principle (DIP)
Positive: All major components depend on abstractions.
Issue: MisQueryBuilder is not registered in DI.
Recommendation: Create IMisQueryBuilder interface and register in DI.
2. Clean Architecture
Excellent: DataAccess project only references Core project with correct dependency direction.
3. Code Organization
Folder Structure
Good:
JdeScoping.DataAccess/
├── Exceptions/ # Custom exception types
├── Interfaces/ # Internal interfaces
├── Models/ # DTOs for queries
├── Options/ # Configuration classes
├── Queries/ # SQL query constants
├── QueryBuilders/ # Dynamic query construction
├── Repositories/ # Repository implementations
└── Services/ # Domain services
Partial Class Usage
Good: Repository organized using partial classes by domain.
Configuration Class Overlap
Issue: SearchProcessingOptions and SearchProcessingConfiguration both use section name "SearchProcessing".
Recommendation: Consolidate into a single options class or use distinct section names.
4. Error Handling
Exception Hierarchy
Excellent:
DataAccessException (base)
├── ConnectionException
├── QueryException
└── DataAccessTimeoutException
Consistent Error Handling Pattern
Good: Centralized LogAndThrow method used throughout repository.
Issue: Missing try-catch in some service methods (WorkOrderTraversalService).
5. Testability
Excellent: All public APIs are interface-based with constructor injection.
Issue: Inconsistent guard clauses - some classes have null guards, others do not.
Recommendation: Add consistent null guards to all constructors.
6. Code Duplication
Repetitive try-catch pattern ✅ FIXED
Pattern repeated 10+ times in repository methods.
Resolution: Extracted generic ExecuteQueryAsync<T> method to LotFinderRepository.cs. All 13 repository methods in SearchManagement.cs, Lookups.cs, and DataSync.cs now use this helper method, reducing boilerplate from ~84 lines to 14 lines.
Duplicate Code in SearchProcessor
ExecuteSearchAsync and ExecuteSearchToModelAsync share significant code.
Recommendation: Extract common logic into a private setup method.
7. Async Patterns
Positive Observations
- All database operations use async methods
- Proper
ConfigureAwait(false)in infrastructure code - IAsyncEnumerable support for streaming large result sets
Issues
Issue: Potential connection pooling concern - callers must dispose connections.
Recommendation: Document clearly or consider connection scope pattern.
8. Null Safety
Good: Nullable reference types enabled.
Issues:
- Some nullable string parameters not validated in SQL queries
- Missing null/empty validation in repository methods
Recommendation: Add validation:
if (string.IsNullOrWhiteSpace(filter))
return [];
9. Documentation
Excellent: Nearly all public members have XML documentation, SQL queries include inline comments.
10. Additional Observations
Magic Numbers
Extremely large timeout values (999999 seconds) seem arbitrary.
Recommendation: Use more reasonable defaults or document rationale.
Hardcoded Command Timeout
WorkOrderTraversalService uses hardcoded timeout instead of configuration.
Redundant throw after LogAndThrow
Recommendation: Add [DoesNotReturn] attribute to LogAndThrow method.
Recommendations Summary
Critical
- Add
[DoesNotReturn]attribute toLogAndThrow - Register
MisQueryBuilderin DI
Important
- Add null guards to
SearchProcessorconstructor - Consolidate overlapping configuration classes
- Extract repetitive try-catch pattern
- Inject timeout configuration into
WorkOrderTraversalService
Suggestions
- Add validation for search filter parameters
- Use
IReadOnlyList<T>for query result return types - Extract common setup logic from SearchProcessor methods
- Create
IMisQueryBuilderinterface for testability