Skip to content

Commit 487d0ce

Browse files
committed
Merge branch 'feat/postgres-migration'
2 parents 6eb95db + d0d0bf9 commit 487d0ce

47 files changed

Lines changed: 981 additions & 3676 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Required in base compose
2-
SQL_PASSWORD=ChangeMe_SqlServer!
2+
POSTGRES_DB=taskmanagement
3+
POSTGRES_USER=postgres
4+
POSTGRES_PASSWORD=postgres
35

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

README.md

Lines changed: 4 additions & 4 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")]
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)
126+
- EF Core (PostgreSQL)
127127
- MediatR
128128
- FluentValidation
129129
- AutoMapper
@@ -148,7 +148,7 @@ Benefits:
148148
- SignalR real-time activity events
149149
- Unit and integration tests
150150

151-
### `SQL Server`
151+
### `PostgreSQL`
152152
- Shared persistence for Auth and API domains
153153

154154
### `Caddy`
@@ -174,7 +174,7 @@ You can copy `.env.example` to `.env` and adjust values if needed.
174174
docker compose up --build
175175
```
176176

177-
This starts SQL Server, Auth, API, and Caddy with local HTTPS routing.
177+
This starts PostgreSQL, Auth, API, and Caddy with local HTTPS routing.
178178

179179
---
180180

docker-compose.override.yml

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
1-
version: '3.8'
2-
31
services:
4-
sqlserver:
5-
environment:
6-
- SQL_PASSWORD=${SQL_PASSWORD:-Passw0rd!1234}
7-
- MSSQL_SA_PASSWORD=${SQL_PASSWORD:-Passw0rd!1234}
2+
postgres:
83
ports:
9-
- "1433:1433"
4+
- "5432:5432"
105

116
auth-service:
127
environment:
138
- ASPNETCORE_ENVIRONMENT=Development
149
- ASPNETCORE_URLS=http://+:8080
15-
- ConnectionStrings__TaskManagementDbConnection=Server=sqlserver,1433;Database=TaskManagementDb;User Id=sa;Password=${SQL_PASSWORD:-Passw0rd!1234};TrustServerCertificate=True;
10+
- ConnectionStrings__TaskManagementDbConnection=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
1611
- OpenIddict__Issuer=https://auth.localhost
1712
- OpenIddict__Audience=task_management_api_dev
1813
- OpenIddict__EncryptionKey=${OPENIDDICT_ENCRYPTION_KEY:-DRjd/GnduI3Efzen9V9BvbNUfc/VKgXltV7Kbk9sMkY=}
@@ -45,7 +40,7 @@ services:
4540
environment:
4641
- ASPNETCORE_ENVIRONMENT=Development
4742
- ASPNETCORE_URLS=http://+:8080
48-
- ConnectionStrings__TaskManagementDbConnection=Server=sqlserver,1433;Database=TaskManagementDb;User Id=sa;Password=${SQL_PASSWORD:-Passw0rd!1234};TrustServerCertificate=True;
43+
- ConnectionStrings__TaskManagementDbConnection=Host=postgres;Port=5432;Database=${POSTGRES_DB:-taskmanagement};Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres};
4944
- OpenIddict__Issuer=https://auth.localhost
5045
- OpenIddict__Audience=task_management_api_dev
5146
- OpenIddict__EncryptionKey=${OPENIDDICT_ENCRYPTION_KEY:-DRjd/GnduI3Efzen9V9BvbNUfc/VKgXltV7Kbk9sMkY=}

docker-compose.yml

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
version: '3.8'
2-
31
services:
4-
sqlserver:
5-
image: mcr.microsoft.com/mssql/server:2022-latest
2+
postgres:
3+
image: postgres:16-alpine
64
environment:
7-
- ACCEPT_EULA=Y
8-
- MSSQL_PID=Developer
9-
- MSSQL_SA_PASSWORD=${SQL_PASSWORD}
5+
- POSTGRES_DB=${POSTGRES_DB:-taskmanagement}
6+
- POSTGRES_USER=${POSTGRES_USER:-postgres}
7+
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres}
108
volumes:
11-
- sqlserver-data:/var/opt/mssql
9+
- postgres-data:/var/lib/postgresql/data
1210
networks:
1311
- taskmanagement-network
1412
healthcheck:
15-
test: /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -Q "SELECT 1" || exit 1
13+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-taskmanagement}"]
1614
interval: 10s
1715
retries: 10
1816
start_period: 10s
@@ -43,7 +41,7 @@ services:
4341
args:
4442
- BUILD_CONFIGURATION=${BUILD_CONFIGURATION:-Release}
4543
depends_on:
46-
sqlserver:
44+
postgres:
4745
condition: service_healthy
4846
networks:
4947
- taskmanagement-network
@@ -62,7 +60,7 @@ services:
6260
args:
6361
- BUILD_CONFIGURATION=${BUILD_CONFIGURATION:-Release}
6462
depends_on:
65-
sqlserver:
63+
postgres:
6664
condition: service_healthy
6765
auth-service:
6866
condition: service_healthy
@@ -81,7 +79,7 @@ networks:
8179
driver: bridge
8280

8381
volumes:
84-
sqlserver-data:
82+
postgres-data:
8583
caddy_data:
8684
caddy_config:
8785
driver: local

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Configuration;
23

34
namespace TaskManagement.Api.Infrastructure.Persistence.Configuration
45
{
56
public static class DatabaseConfiguration
67
{
78
public static IServiceCollection AddDatabaseConfiguration(this IServiceCollection services, IConfiguration configuration)
89
{
9-
services.AddDbContext<TaskManagementDbContext>(options =>
10+
var connectionString = configuration.GetConnectionString("TaskManagementDbConnection");
11+
if (string.IsNullOrWhiteSpace(connectionString))
1012
{
11-
options.UseSqlServer(configuration.GetConnectionString("TaskManagementDbConnection"),
12-
sqlServerOptions => sqlServerOptions.EnableRetryOnFailure(
13+
throw new InvalidOperationException("Connection string 'TaskManagementDbConnection' not found.");
14+
}
15+
16+
services.AddDbContext<TaskManagementDbContextPostgres>(options =>
17+
{
18+
options.UseNpgsql(connectionString,
19+
npgsqlOptions => npgsqlOptions.EnableRetryOnFailure(
1320
maxRetryCount: 5,
1421
maxRetryDelay: TimeSpan.FromSeconds(10),
15-
errorNumbersToAdd: null));
22+
errorCodesToAdd: null));
1623
});
1724

25+
services.AddScoped<TaskManagementDbContext>(sp =>
26+
sp.GetRequiredService<TaskManagementDbContextPostgres>());
27+
1828
return services;
1929
}
2030

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Design;
3+
4+
namespace TaskManagement.Api.Infrastructure.Persistence.DesignTime
5+
{
6+
public sealed class TaskManagementDbContextPostgresFactory : IDesignTimeDbContextFactory<TaskManagementDbContextPostgres>
7+
{
8+
public TaskManagementDbContextPostgres CreateDbContext(string[] args)
9+
{
10+
var connectionString =
11+
Environment.GetEnvironmentVariable("ConnectionStrings__TaskManagementDbConnection")
12+
?? Environment.GetEnvironmentVariable("ConnectionStrings__TaskManagementDbConnectionPostgres")
13+
?? "Host=localhost;Port=5432;Database=TaskManagementDb;Username=postgres;Password=postgres";
14+
15+
var optionsBuilder = new DbContextOptionsBuilder<TaskManagementDbContextPostgres>();
16+
optionsBuilder.UseNpgsql(connectionString);
17+
18+
return new TaskManagementDbContextPostgres(optionsBuilder.Options);
19+
}
20+
}
21+
}

src/TaskManagement.Api/Infrastructure/Persistence/Migrations/20250430192920_InitialApiSchema.Designer.cs

Lines changed: 0 additions & 161 deletions
This file was deleted.

0 commit comments

Comments
 (0)