Critical bug fix for tenant registration failure caused by incorrect EF Core migration.
## Problem
The AddUserTenantRoles migration generated duplicate columns:
- Application columns: user_id, tenant_id (used by code)
- Shadow FK columns: user_id1, tenant_id1 (incorrect EF Core generation)
Foreign key constraints referenced wrong columns (user_id1/tenant_id1), causing all
tenant registrations to fail with:
```
violates foreign key constraint "FK_user_tenant_roles_tenants_tenant_id1"
```
## Root Cause
UserTenantRoleConfiguration.cs used string column names in HasForeignKey(),
combined with Value Object properties (UserId/TenantId), causing EF Core to
create shadow properties with duplicate names (user_id1, tenant_id1).
## Solution
1. **Configuration Change**:
- Keep Value Object properties (UserId, TenantId) for application use
- Ignore navigation properties (User, Tenant) to prevent shadow property generation
- Let EF Core use the converted Value Object columns for data storage
2. **Migration Change**:
- Delete incorrect AddUserTenantRoles migration
- Generate new FixUserTenantRolesIgnoreNavigation migration
- Drop duplicate columns (user_id1, tenant_id1)
- Recreate FK constraints referencing correct columns (user_id, tenant_id)
## Changes
- Modified: UserTenantRoleConfiguration.cs
- Ignore navigation properties (User, Tenant)
- Use Value Object conversion for UserId/TenantId columns
- Deleted: 20251103135644_AddUserTenantRoles migration (broken)
- Added: 20251103150353_FixUserTenantRolesIgnoreNavigation migration (fixed)
- Updated: IdentityDbContextModelSnapshot.cs (no duplicate columns)
- Added: test-bugfix.ps1 (regression test script)
## Test Results
- Tenant registration: SUCCESS
- JWT Token generation: SUCCESS
- Refresh Token generation: SUCCESS
- Foreign key constraints: CORRECT (user_id, tenant_id)
## Database Schema (After Fix)
```sql
CREATE TABLE identity.user_tenant_roles (
id uuid PRIMARY KEY,
user_id uuid NOT NULL, -- Used by application & FK
tenant_id uuid NOT NULL, -- Used by application & FK
role varchar(50) NOT NULL,
assigned_at timestamptz NOT NULL,
assigned_by_user_id uuid,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
);
```
Fixes: BUG-002 (CRITICAL)
Severity: CRITICAL - Blocked all tenant registrations
Impact: Day 5 RBAC feature now working
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
50 lines
2.1 KiB
PowerShell
50 lines
2.1 KiB
PowerShell
# Test Bug Fix - Tenant Registration
|
|
$body = @{
|
|
tenantName = "BugFix Test Corp"
|
|
tenantSlug = "bugfix-test-$(Get-Random)"
|
|
subscriptionPlan = "Professional"
|
|
adminEmail = "admin@bugfix$(Get-Random).com"
|
|
adminPassword = "Admin@1234"
|
|
adminFullName = "Bug Fix Admin"
|
|
} | ConvertTo-Json
|
|
|
|
Write-Host "Testing Tenant Registration..."
|
|
Write-Host "Endpoint: http://localhost:5167/api/tenants/register"
|
|
|
|
try {
|
|
$response = Invoke-RestMethod -Uri "http://localhost:5167/api/tenants/register" `
|
|
-Method Post `
|
|
-ContentType "application/json" `
|
|
-Body $body `
|
|
-ErrorAction Stop
|
|
|
|
Write-Host ""
|
|
Write-Host "==================================" -ForegroundColor Green
|
|
Write-Host "SUCCESS - BUG FIXED!" -ForegroundColor Green
|
|
Write-Host "==================================" -ForegroundColor Green
|
|
Write-Host ""
|
|
Write-Host "Tenant Name: $($response.tenantName)" -ForegroundColor Cyan
|
|
Write-Host "Tenant Slug: $($response.tenantSlug)" -ForegroundColor Cyan
|
|
Write-Host "User Email: $($response.user.email)" -ForegroundColor Cyan
|
|
Write-Host "User Role: $($response.user.role)" -ForegroundColor Cyan
|
|
Write-Host "Access Token: $($response.accessToken.Substring(0, 50))..." -ForegroundColor Yellow
|
|
Write-Host "Refresh Token: $($response.refreshToken.Substring(0, 50))..." -ForegroundColor Yellow
|
|
Write-Host ""
|
|
Write-Host "The foreign key constraint bug has been successfully fixed!" -ForegroundColor Green
|
|
exit 0
|
|
} catch {
|
|
Write-Host ""
|
|
Write-Host "==================================" -ForegroundColor Red
|
|
Write-Host "FAILURE - Bug Still Exists" -ForegroundColor Red
|
|
Write-Host "==================================" -ForegroundColor Red
|
|
Write-Host ""
|
|
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
Write-Host ""
|
|
if ($_.Exception.Response) {
|
|
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
|
|
$responseBody = $reader.ReadToEnd()
|
|
Write-Host "Response: $responseBody" -ForegroundColor Yellow
|
|
}
|
|
exit 1
|
|
}
|