Files
jdescopingtool/CodeReviews/DataAccess/review.md
T
Joseph Doherty 604bfe919c refactor: address code review findings across all projects
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
2026-01-19 11:05:36 -05:00

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 Needs Improvement Good Repetitive patterns in repository FIXED
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

  1. Add [DoesNotReturn] attribute to LogAndThrow
  2. Register MisQueryBuilder in DI

Important

  1. Add null guards to SearchProcessor constructor
  2. Consolidate overlapping configuration classes
  3. Extract repetitive try-catch pattern
  4. Inject timeout configuration into WorkOrderTraversalService

Suggestions

  1. Add validation for search filter parameters
  2. Use IReadOnlyList<T> for query result return types
  3. Extract common setup logic from SearchProcessor methods
  4. Create IMisQueryBuilder interface for testability