feat(infra): V009 migration + Usuario.WithPermisosJson + SqlTestFixture V009 schema [UDT-009]

This commit is contained in:
2026-04-15 21:27:29 -03:00
parent da1eb83ac1
commit 54955231bf
4 changed files with 370 additions and 3 deletions

View File

@@ -29,6 +29,9 @@ public sealed class SqlTestFixture : IAsyncLifetime
// V008: ensure MustChangePassword column and IX_Usuario_Activo_Rol exist in test DB
await EnsureV008SchemaAsync();
// V009: update PermisosJson DEFAULT constraint and migrate legacy rows
await EnsureV009SchemaAsync();
_respawner = await Respawner.CreateAsync(_connection, new RespawnerOptions
{
DbAdapter = DbAdapter.SqlServer,
@@ -215,6 +218,7 @@ public sealed class SqlTestFixture : IAsyncLifetime
private async Task SeedAdminAsync()
{
// V009: PermisosJson uses new canonical shape {"grant":[],"deny":[]} — NOT legacy '["*"]'
const string sql = """
SET QUOTED_IDENTIFIER ON;
IF NOT EXISTS (SELECT 1 FROM dbo.Usuario WHERE Username = 'admin')
@@ -222,9 +226,53 @@ public sealed class SqlTestFixture : IAsyncLifetime
VALUES (
'admin',
'$2a$12$rmq6tlSAQ8WXhR2CwLCSeuwCJKz/.8Eab95UQCUNfwe4dokeOqMcW',
'Administrador', 'Sistema', 'admin', '["*"]', 1, 0
'Administrador', 'Sistema', 'admin', '{"grant":[],"deny":[]}', 1, 0
);
""";
await _connection.ExecuteAsync(sql);
}
/// <summary>
/// Applies V009 schema changes idempotently to the test database.
/// Mirrors V009__activate_permisos_overrides.sql.
/// Drops and re-adds DF_Usuario_Permisos with the new shape, then migrates legacy rows.
/// </summary>
private async Task EnsureV009SchemaAsync()
{
const string dropConstraint = """
IF EXISTS (
SELECT 1 FROM sys.default_constraints
WHERE name = 'DF_Usuario_Permisos'
AND parent_object_id = OBJECT_ID('dbo.Usuario')
)
BEGIN
ALTER TABLE dbo.Usuario DROP CONSTRAINT DF_Usuario_Permisos;
END
""";
const string addConstraint = """
IF NOT EXISTS (
SELECT 1 FROM sys.default_constraints
WHERE name = 'DF_Usuario_Permisos'
AND parent_object_id = OBJECT_ID('dbo.Usuario')
)
BEGIN
ALTER TABLE dbo.Usuario
ADD CONSTRAINT DF_Usuario_Permisos
DEFAULT('{"grant":[],"deny":[]}') FOR PermisosJson;
END
""";
const string migrateRows = """
UPDATE dbo.Usuario
SET PermisosJson = '{"grant":[],"deny":[]}'
WHERE PermisosJson IN ('[]', '["*"]', '')
OR PermisosJson IS NULL
OR LTRIM(RTRIM(PermisosJson)) = ''
""";
await _connection.ExecuteAsync(dropConstraint);
await _connection.ExecuteAsync(addConstraint);
await _connection.ExecuteAsync(migrateRows);
}
}