Skip to content

Commit d0d0bf9

Browse files
committed
chore(db): cut over backend to PostgreSQL-only and remove SQL Server artifacts
1 parent 3571d34 commit d0d0bf9

40 files changed

Lines changed: 57 additions & 5020 deletions

File tree

.env.example

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Required in base compose
2-
SQL_PASSWORD=ChangeMe_SqlServer!
32
POSTGRES_DB=taskmanagement
43
POSTGRES_USER=postgres
54
POSTGRES_PASSWORD=postgres
6-
DATABASE_PROVIDER=SqlServer
75

86
# Development defaults used by docker-compose.override.yml
97
OPENIDDICT_ENCRYPTION_KEY=DRjd/GnduI3Efzen9V9BvbNUfc/VKgXltV7Kbk9sMkY=

README.md

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ flowchart LR
1717
SPA["TaskManagementClient (Angular SPA)"] -->|"HTTPS"| Caddy["Caddy Reverse Proxy"]
1818
Caddy -->|"HTTPS"| Auth["Auth Service<br/>OpenIddict + Identity"]
1919
Caddy -->|"HTTPS"| Api["API Service<br/>Projects + TaskItems + Activity"]
20-
Auth --> Db[("SQL Server / PostgreSQL")]
20+
Auth --> Db[("PostgreSQL")]
2121
Api --> Db
2222
```
2323

@@ -123,7 +123,7 @@ Benefits:
123123
## Tech Stack
124124

125125
- ASP.NET Core (.NET 8)
126-
- EF Core (SQL Server + PostgreSQL)
126+
- EF Core (PostgreSQL)
127127
- MediatR
128128
- FluentValidation
129129
- AutoMapper
@@ -148,12 +148,8 @@ Benefits:
148148
- SignalR real-time activity events
149149
- Unit and integration tests
150150

151-
### `SQL Server`
152-
- Shared persistence for Auth and API domains
153-
154151
### `PostgreSQL`
155-
- Alternative shared persistence for Auth and API domains
156-
- Can run side-by-side with SQL Server during migration
152+
- Shared persistence for Auth and API domains
157153

158154
### `Caddy`
159155
- Local HTTPS termination
@@ -173,27 +169,12 @@ Benefits:
173169
### Optional environment setup
174170
You can copy `.env.example` to `.env` and adjust values if needed.
175171

176-
Database selection:
177-
- `DATABASE_PROVIDER=SqlServer` (default, current baseline)
178-
- `DATABASE_PROVIDER=Postgres` (PostgreSQL runtime mode)
179-
180172
### Run
181173
```bash
182174
docker compose up --build
183175
```
184176

185-
This starts SQL Server, PostgreSQL, Auth, API, and Caddy with local HTTPS routing.
186-
Only the provider selected by `DATABASE_PROVIDER` is used by Auth/API at runtime.
187-
188-
Examples:
189-
190-
```bash
191-
# default (SQL Server)
192-
DATABASE_PROVIDER=SqlServer docker compose up --build
193-
194-
# PostgreSQL mode
195-
DATABASE_PROVIDER=Postgres docker compose up --build
196-
```
177+
This starts PostgreSQL, Auth, API, and Caddy with local HTTPS routing.
197178

198179
---
199180

docker-compose.override.yml

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
version: '3.8'
2-
31
services:
42
postgres:
53
ports:
64
- "5432:5432"
75

8-
sqlserver:
9-
environment:
10-
- SQL_PASSWORD=${SQL_PASSWORD:-Passw0rd!1234}
11-
- MSSQL_SA_PASSWORD=${SQL_PASSWORD:-Passw0rd!1234}
12-
ports:
13-
- "1433:1433"
14-
156
auth-service:
167
environment:
17-
- DatabaseProvider=${DATABASE_PROVIDER:-SqlServer}
188
- ASPNETCORE_ENVIRONMENT=Development
199
- ASPNETCORE_URLS=http://+:8080
20-
- ConnectionStrings__TaskManagementDbConnection=Server=sqlserver,1433;Database=TaskManagementDb;User Id=sa;Password=${SQL_PASSWORD:-Passw0rd!1234};TrustServerCertificate=True;
21-
- ConnectionStrings__TaskManagementDbConnectionPostgres=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
10+
- ConnectionStrings__TaskManagementDbConnection=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
2211
- OpenIddict__Issuer=https://auth.localhost
2312
- OpenIddict__Audience=task_management_api_dev
2413
- OpenIddict__EncryptionKey=${OPENIDDICT_ENCRYPTION_KEY:-DRjd/GnduI3Efzen9V9BvbNUfc/VKgXltV7Kbk9sMkY=}
@@ -49,11 +38,9 @@ services:
4938
extra_hosts:
5039
- "auth.localhost:host-gateway"
5140
environment:
52-
- DatabaseProvider=${DATABASE_PROVIDER:-SqlServer}
5341
- ASPNETCORE_ENVIRONMENT=Development
5442
- ASPNETCORE_URLS=http://+:8080
55-
- ConnectionStrings__TaskManagementDbConnection=Server=sqlserver,1433;Database=TaskManagementDb;User Id=sa;Password=${SQL_PASSWORD:-Passw0rd!1234};TrustServerCertificate=True;
56-
- ConnectionStrings__TaskManagementDbConnectionPostgres=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
43+
- ConnectionStrings__TaskManagementDbConnection=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
5744
- OpenIddict__Issuer=https://auth.localhost
5845
- OpenIddict__Audience=task_management_api_dev
5946
- OpenIddict__EncryptionKey=${OPENIDDICT_ENCRYPTION_KEY:-DRjd/GnduI3Efzen9V9BvbNUfc/VKgXltV7Kbk9sMkY=}

docker-compose.yml

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3.8'
2-
31
services:
42
postgres:
53
image: postgres:16-alpine
@@ -19,24 +17,6 @@ services:
1917
timeout: 3s
2018
restart: unless-stopped
2119

22-
sqlserver:
23-
image: mcr.microsoft.com/mssql/server:2022-latest
24-
environment:
25-
- ACCEPT_EULA=Y
26-
- MSSQL_PID=Developer
27-
- MSSQL_SA_PASSWORD=${SQL_PASSWORD}
28-
volumes:
29-
- sqlserver-data:/var/opt/mssql
30-
networks:
31-
- taskmanagement-network
32-
healthcheck:
33-
test: /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -Q "SELECT 1" || exit 1
34-
interval: 10s
35-
retries: 10
36-
start_period: 10s
37-
timeout: 3s
38-
restart: unless-stopped
39-
4020
caddy:
4121
container_name: caddy-prox
4222
image: caddy:2-alpine
@@ -61,7 +41,7 @@ services:
6141
args:
6242
- BUILD_CONFIGURATION=${BUILD_CONFIGURATION:-Release}
6343
depends_on:
64-
sqlserver:
44+
postgres:
6545
condition: service_healthy
6646
networks:
6747
- taskmanagement-network
@@ -80,7 +60,7 @@ services:
8060
args:
8161
- BUILD_CONFIGURATION=${BUILD_CONFIGURATION:-Release}
8262
depends_on:
83-
sqlserver:
63+
postgres:
8464
condition: service_healthy
8565
auth-service:
8666
condition: service_healthy
@@ -100,7 +80,6 @@ networks:
10080

10181
volumes:
10282
postgres-data:
103-
sqlserver-data:
10483
caddy_data:
10584
caddy_config:
10685
driver: local

src/TaskManagement.Api/Infrastructure/Persistence/Configuration/DatabaseConfiguration.cs

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,53 +7,27 @@ public static class DatabaseConfiguration
77
{
88
public static IServiceCollection AddDatabaseConfiguration(this IServiceCollection services, IConfiguration configuration)
99
{
10-
var databaseProvider = configuration["DatabaseProvider"] ?? "SqlServer";
11-
var sqlServerConnectionString = configuration.GetConnectionString("TaskManagementDbConnection");
12-
var postgresConnectionString = configuration.GetConnectionString("TaskManagementDbConnectionPostgres");
13-
14-
if (IsPostgres(databaseProvider))
15-
{
16-
if (string.IsNullOrWhiteSpace(postgresConnectionString))
17-
{
18-
throw new InvalidOperationException("Connection string 'TaskManagementDbConnectionPostgres' not found.");
19-
}
20-
21-
services.AddDbContext<TaskManagementDbContextPostgres>(options =>
22-
{
23-
options.UseNpgsql(postgresConnectionString,
24-
npgsqlOptions => npgsqlOptions.EnableRetryOnFailure(
25-
maxRetryCount: 5,
26-
maxRetryDelay: TimeSpan.FromSeconds(10),
27-
errorCodesToAdd: null));
28-
});
29-
30-
services.AddScoped<TaskManagementDbContext>(sp =>
31-
sp.GetRequiredService<TaskManagementDbContextPostgres>());
32-
return services;
33-
}
34-
35-
if (string.IsNullOrWhiteSpace(sqlServerConnectionString))
10+
var connectionString = configuration.GetConnectionString("TaskManagementDbConnection");
11+
if (string.IsNullOrWhiteSpace(connectionString))
3612
{
3713
throw new InvalidOperationException("Connection string 'TaskManagementDbConnection' not found.");
3814
}
3915

40-
services.AddDbContext<TaskManagementDbContext>(options =>
16+
services.AddDbContext<TaskManagementDbContextPostgres>(options =>
4117
{
42-
options.UseSqlServer(sqlServerConnectionString,
43-
sqlServerOptions => sqlServerOptions.EnableRetryOnFailure(
18+
options.UseNpgsql(connectionString,
19+
npgsqlOptions => npgsqlOptions.EnableRetryOnFailure(
4420
maxRetryCount: 5,
4521
maxRetryDelay: TimeSpan.FromSeconds(10),
46-
errorNumbersToAdd: null));
22+
errorCodesToAdd: null));
4723
});
4824

25+
services.AddScoped<TaskManagementDbContext>(sp =>
26+
sp.GetRequiredService<TaskManagementDbContextPostgres>());
27+
4928
return services;
5029
}
5130

52-
private static bool IsPostgres(string provider)
53-
=> provider.Equals("postgres", StringComparison.OrdinalIgnoreCase)
54-
|| provider.Equals("postgresql", StringComparison.OrdinalIgnoreCase)
55-
|| provider.Equals("npgsql", StringComparison.OrdinalIgnoreCase);
56-
5731
public static async Task ApplyMigrationsAsync(this WebApplication app)
5832
{
5933
using var scope = app.Services.CreateScope();

src/TaskManagement.Api/Infrastructure/Persistence/DesignTime/TaskManagementDbContextPostgresFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ public sealed class TaskManagementDbContextPostgresFactory : IDesignTimeDbContex
88
public TaskManagementDbContextPostgres CreateDbContext(string[] args)
99
{
1010
var connectionString =
11-
Environment.GetEnvironmentVariable("ConnectionStrings__TaskManagementDbConnectionPostgres")
11+
Environment.GetEnvironmentVariable("ConnectionStrings__TaskManagementDbConnection")
12+
?? Environment.GetEnvironmentVariable("ConnectionStrings__TaskManagementDbConnectionPostgres")
1213
?? "Host=localhost;Port=5432;Database=TaskManagementDb;Username=postgres;Password=postgres";
1314

1415
var optionsBuilder = new DbContextOptionsBuilder<TaskManagementDbContextPostgres>();

0 commit comments

Comments
 (0)