Refactor data layer to support PostgreSQL as an alternative to SQLite - #8
Merged
Conversation
Introduce ITelemetryRepository abstraction with EfTelemetryRepository base class and provider-specific implementations (SqliteTelemetryRepository, PostgresTelemetryRepository). All services now depend on the repository interface instead of TelemetryDbContext directly. Provider selection is driven by the POSTGRES_CONNECTION_STRING env var: when set, the app uses PostgreSQL with EnsureCreated(); otherwise SQLite with migrations (existing default behavior). All 16 integration test classes now run against both SQLite (in-memory) and PostgreSQL (via Testcontainers), doubling coverage from 62 to 124 database-backed test cases. Made-with: Cursor
joeldickson
commented
Mar 22, 2026
joeldickson
left a comment
Contributor
Author
There was a problem hiding this comment.
The refactoring to introduce the ITelemetryRepository abstraction looks very clean and effectively decouples the core domain logic from EF Core. Parameterizing the integration tests to run against both providers using Testcontainers is also an excellent strategy for verifying parity!
I left a couple of inline comments regarding long-term maintenance and test resource cleanup:
- Migrations vs. EnsureCreated:
EnsureCreated()prevents future schema migrations for the Postgres provider. Depending on your long-term plans, you may want to generate Postgres-specific migrations. - Test Database Leakage: The integration test setup creates a new Postgres database per test method but never drops them, which could lead to bloat inside the container as the test suite grows.
Otherwise, this is a really solid PR!
…onale - Add DropDatabaseAsync to PostgresTestServer that terminates active connections then drops the database - Call DropDatabaseAsync in CustomWebApplicationFactory.Dispose so test databases are cleaned up after each test, avoiding container bloat - Add comment explaining why EnsureCreated() is used for PostgreSQL (MVP approach) and the migration path for long-term support Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #5
ITelemetryRepositoryabstraction withEfTelemetryRepositorybase class containing all shared EF Core query logic, and two provider-specific implementations:SqliteTelemetryRepository(PRAGMA optimize + VACUUM) andPostgresTelemetryRepository(VACUUM ANALYZE)IngestService,DashboardService,FilterService,DataCleanupService) to depend onITelemetryRepositoryinstead ofTelemetryDbContextdirectly — no service class touches the DbContext anymoreProgram.cs: presence ofPOSTGRES_CONNECTION_STRINGenv var switches to PostgreSQL (withEnsureCreated()); absence keeps SQLite with existing migrations[TestFixture(DatabaseProvider.Sqlite)]/[TestFixture(DatabaseProvider.PostgreSql)]parameterization, with PostgreSQL tests powered by Testcontainers — total test cases doubled from 62 to 124New files
Core/Data/ITelemetryRepository.csCore/Data/EfTelemetryRepository.csCore/Data/SqliteTelemetryRepository.csCore/Data/PostgresTelemetryRepository.csIntegrationTests/DatabaseProvider.csIntegrationTests/PostgresTestServer.csModified files
Core/Services/IngestService.csITelemetryRepositoryCore/Services/DashboardService.csITelemetryRepositoryCore/Services/FilterService.csITelemetryRepositoryCore/Services/DataCleanupService.csITelemetryRepositoryWebApi/Program.csCore/*.csprojNpgsql.EntityFrameworkCore.PostgreSQLIntegrationTests/*.csproj[TestFixture]parameterizationTest plan
docker-compose upworks with the PostgreSQL configurationPOSTGRES_CONNECTION_STRINGset