fix(backend): simplify Finbuckle namespace imports and register DB interceptors

- Use consolidated Finbuckle.MultiTenant namespace instead of separate imports
- Switch TenantProvider to use untyped IMultiTenantContextAccessor (Finbuckle 9.x pattern)
- Register TenantDbConnectionInterceptor and SaveChangesTenantInterceptor as singletons
- Add interceptors to DbContext configuration for RLS tenant context support
- Update evidence files for Task 7 and Task 8 verification
This commit is contained in:
WorkClub Automation
2026-03-03 18:52:35 +01:00
parent c9cb629ddb
commit 3a82933fd5
11 changed files with 562 additions and 1134 deletions

View File

@@ -0,0 +1,105 @@
Task 7: PostgreSQL Schema + EF Core Migrations + RLS Policies
Build Verification Evidence
Generated: 2026-03-03 17:10 CET
=== BUILD STATUS ===
✅ ALL PROJECTS BUILD SUCCESSFULLY (0 errors)
Build command: dotnet build WorkClub.slnx
Working directory: /Users/mastermito/Dev/opencode/backend
Projects built successfully:
1. WorkClub.Domain -> bin/Debug/net10.0/WorkClub.Domain.dll
2. WorkClub.Application -> bin/Debug/net10.0/WorkClub.Application.dll
3. WorkClub.Infrastructure -> bin/Debug/net10.0/WorkClub.Infrastructure.dll
4. WorkClub.Api -> bin/Debug/net10.0/WorkClub.Api.dll
5. WorkClub.Tests.Unit -> bin/Debug/net10.0/WorkClub.Tests.Unit.dll
6. WorkClub.Tests.Integration -> bin/Debug/net10.0/WorkClub.Tests.Integration.dll
Warnings: 6 (BouncyCastle.Cryptography 2.2.1 security vulnerabilities - transitive dependency from Testcontainers)
Errors: 0
=== IMPLEMENTATION COMPLETED ===
✅ AppDbContext created with DbSets for all 5 entities
✅ Entity configurations via IEntityTypeConfiguration<T> pattern
✅ PostgreSQL xmin concurrency tokens on WorkItem and Shift
✅ TenantDbConnectionInterceptor with SET LOCAL for RLS
✅ SaveChangesTenantInterceptor for auto-assigning TenantId
✅ EF Core migration generated: 20260303132952_InitialCreate
✅ RLS policies SQL script created: add-rls-policies.sql
✅ Interceptors registered in Program.cs DI container
✅ Finbuckle.MultiTenant v10 API compatibility verified
=== CHANGES MADE ===
Modified Files:
- backend/WorkClub.Api/Program.cs
* Added singleton registrations for both interceptors
* Updated DbContext registration to use service provider and .AddInterceptors()
- backend/WorkClub.Infrastructure/Services/TenantProvider.cs
* Updated to Finbuckle v10 API (IMultiTenantContextAccessor without generic)
- backend/WorkClub.Domain/Entities/WorkItem.cs
* Changed RowVersion type from byte[]? to uint for xmin
- backend/WorkClub.Domain/Entities/Shift.cs
* Changed RowVersion type from byte[]? to uint for xmin
Created Files:
- backend/WorkClub.Infrastructure/Data/AppDbContext.cs
- backend/WorkClub.Infrastructure/Data/Configurations/*.cs (5 configuration classes)
- backend/WorkClub.Infrastructure/Data/Interceptors/*.cs (2 interceptor classes)
- backend/WorkClub.Infrastructure/Migrations/20260303132952_InitialCreate.*
- backend/WorkClub.Infrastructure/Migrations/add-rls-policies.sql
- backend/WorkClub.Tests.Integration/Data/MigrationTests.cs
- backend/WorkClub.Tests.Integration/Data/RlsTests.cs
=== PENDING TASKS ===
⏳ Database setup blocked by Docker/Colima issues:
- Colima VM failed to start (disk attachment error)
- Docker Desktop not installed
- PostgreSQL not available locally
Manual steps required (when Docker is available):
1. Start PostgreSQL: docker compose up -d postgres
2. Apply migration: cd backend && dotnet ef database update --project WorkClub.Infrastructure --startup-project WorkClub.Api
3. Apply RLS: psql -h localhost -U app_admin -d workclub -f backend/WorkClub.Infrastructure/Migrations/add-rls-policies.sql
4. Run tests: dotnet test backend/WorkClub.Tests.Integration --filter "FullyQualifiedName~MigrationTests|RlsTests"
=== VERIFICATION STATUS ===
✅ Code compiles without errors
✅ All dependencies resolved
✅ Interceptor pattern correctly implemented with SET LOCAL (transaction-scoped)
✅ Finbuckle v10 compatibility verified
⏳ Integration tests pending (require PostgreSQL)
⏳ Migration application pending (require PostgreSQL)
⏳ RLS policies pending (require PostgreSQL)
=== SECURITY NOTES ===
✅ CRITICAL REQUIREMENT MET: Using SET LOCAL (transaction-scoped) not SET (session-scoped)
- Prevents cross-tenant data leaks with connection pooling
- Implementation in TenantDbConnectionInterceptor line 33
✅ RLS policies use current_setting('app.current_tenant_id', true)::text
- Second parameter returns NULL instead of error when unset
- Prevents crashes when tenant context not available
✅ ShiftSignups RLS uses subquery pattern (no direct TenantId)
- Policy: "ShiftId" IN (SELECT "Id" FROM shifts WHERE "TenantId" = ...)
=== NEXT SESSION REQUIREMENTS ===
To complete Task 7, next session must:
1. Fix Docker/Colima environment or install PostgreSQL locally
2. Apply migration and RLS policies
3. Run integration tests (MigrationTests + RlsTests)
4. Verify tests pass (TDD green phase)
5. Save test evidence
6. Update learnings.md with Finbuckle v10 migration notes
DO NOT COMMIT - Task 7 and Task 8 will be committed together per directive.