# Implement Data Access ## Summary Implement the data access layer with repository interfaces and implementations for accessing SQL Server (LotFinderDB), JDE Oracle, and CMS Oracle databases. This provides the foundation for all data operations in the migrated application. ## Scope ### In Scope - `IDbConnectionFactory` interface and `DbConnectionFactory` implementation - `ILotFinderRepository` interface with all SQL Server cache methods - `IJdeRepository` interface with all JDE Oracle query methods - `ICmsRepository` interface with CMS MIS data methods - `LotFinderRepository`, `JdeRepository`, `CmsRepository` implementations - `DataAccessOptions` configuration class - Custom exception hierarchy (`DataAccessException`, `ConnectionException`, `QueryException`, `DataAccessTimeoutException`) - `AddDataAccess` service registration extension method - SQL queries as embedded resources or compile-time constants - Unit tests for repository methods ### Out of Scope - Database schema changes (handled by migrate-database-schema) - Data sync scheduling (Phase 5: data-sync) - Search processing logic (Phase 6: search-processing) - Azure Key Vault integration (will use .NET Secret Manager for local dev) ## Motivation The legacy data access layer uses static partial classes which are difficult to test and tightly coupled. The new design provides: - Interface-based repositories for dependency injection and testability - Connection factory abstraction for consistent connection management - Async-first design with `IAsyncEnumerable` for memory-efficient streaming - Typed exceptions for consistent error handling - Configurable timeouts via options pattern ## Acceptance Criteria 1. All three repository interfaces defined with methods matching the spec 2. `IDbConnectionFactory` provides connections for all four database connections (LotFinderDB, JDE, JDE Stage, CMS) 3. All repository implementations use Dapper for query execution 4. JDE/CMS streaming queries use `IAsyncEnumerable` with `QueryUnbufferedAsync` 5. All methods accept `CancellationToken` parameter 6. Custom exceptions thrown on errors (never return null/empty on error) 7. `AddDataAccess` extension method registers all services with appropriate lifetimes 8. SQL injection prevented via whitelist validation in `RebuildIndicesAsync` 9. Unit tests pass with mocked dependencies 10. `openspec validate implement-data-access --strict` passes ## Dependencies - `migrate-database-schema` - Database schema must exist for repository queries - NuGet packages: `Microsoft.Data.SqlClient`, `Oracle.ManagedDataAccess.Core`, `Dapper` ## Risks | Risk | Mitigation | |------|------------| | Oracle driver compatibility | Test early with Oracle.ManagedDataAccess.Core against target databases | | Query translation errors | Copy SQL exactly from legacy, validate with Codex MCP review | | Streaming memory issues | Use `QueryUnbufferedAsync` for all large result sets | | Connection pooling misconfiguration | Use default ADO.NET pooling, document connection string settings | ## Related Specs - `data-access` - All repository interface and method definitions - `domain-models` - Entity types returned by repositories - `database-schema` - SQL Server tables accessed by LotFinderRepository