mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-10-07 22:03:14 -04:00
fix(storage): repair provider account creator type
This commit is contained in:
2 files changed
+135
No files matched your search
@@ -704,6 +704,85 @@ public sealed class PostgresStorageIntegrationTests
|
||||
Assert.Equal(2, (await restarted.RecommendationCandidates.SingleAsync(item => item.Id == candidate)).Revision);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Postgres")]
|
||||
[Trait("Lane", "ReleaseCritical")]
|
||||
public async Task ProviderAccountCreatorRepair_ConvertsLegacyTextColumnAndPreservesCreator()
|
||||
{
|
||||
const string previous = "20260804080000_BackfillV3CompatibilityState";
|
||||
const string current = "20260820173000_RepairProviderAccountCreatorIdentity";
|
||||
await using var database = await PostgresTestDatabase.CreateAsync(useTemplate: false);
|
||||
await using var context = new AllstarrDbContext(database.Options);
|
||||
var migrator = context.GetService<IMigrator>();
|
||||
await migrator.MigrateAsync(previous);
|
||||
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var tenantId = Guid.CreateVersion7();
|
||||
var userId = Guid.CreateVersion7();
|
||||
var accountId = Guid.CreateVersion7();
|
||||
context.Tenants.Add(new TenantRecord
|
||||
{
|
||||
Id = tenantId,
|
||||
Slug = "provider-creator-repair",
|
||||
Name = "Provider creator repair",
|
||||
CreatedAt = now
|
||||
});
|
||||
context.Users.Add(new PlatformUserRecord
|
||||
{
|
||||
Id = userId,
|
||||
TenantId = tenantId,
|
||||
DisplayName = "Creator",
|
||||
Status = PlatformUserStatus.Active,
|
||||
CreatedAt = now,
|
||||
UpdatedAt = now
|
||||
});
|
||||
context.ProviderAccounts.Add(new ProviderAccountRecord
|
||||
{
|
||||
Id = accountId,
|
||||
TenantId = tenantId,
|
||||
OwnerUserId = userId,
|
||||
CreatedByUserId = userId,
|
||||
ProviderId = "audiomuse-ai",
|
||||
DisplayName = "AudioMuse",
|
||||
Scope = ProviderAccountScope.User,
|
||||
Enabled = false,
|
||||
CreatedAt = now,
|
||||
UpdatedAt = now
|
||||
});
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
await context.Database.ExecuteSqlRawAsync("""
|
||||
ALTER TABLE provider_accounts DROP CONSTRAINT IF EXISTS "FK_provider_account_creator";
|
||||
DROP INDEX IF EXISTS "IX_provider_accounts_CreatedByUserId";
|
||||
ALTER TABLE provider_accounts
|
||||
ALTER COLUMN "CreatedByUserId" TYPE text
|
||||
USING "CreatedByUserId"::text;
|
||||
""");
|
||||
Assert.Equal("text", await ColumnType(context, "provider_accounts", "CreatedByUserId"));
|
||||
|
||||
await migrator.MigrateAsync(current);
|
||||
context.ChangeTracker.Clear();
|
||||
|
||||
Assert.Equal("uuid", await ColumnType(context, "provider_accounts", "CreatedByUserId"));
|
||||
Assert.Equal(userId, (await context.ProviderAccounts.AsNoTracking()
|
||||
.SingleAsync(item => item.Id == accountId)).CreatedByUserId);
|
||||
await using (var command = context.Database.GetDbConnection().CreateCommand())
|
||||
{
|
||||
command.CommandText = "SELECT count(*) FROM pg_constraint " +
|
||||
"WHERE conrelid = 'provider_accounts'::regclass " +
|
||||
"AND conname = 'FK_provider_account_creator'";
|
||||
Assert.Equal(1L, Convert.ToInt64(await command.ExecuteScalarAsync()));
|
||||
command.CommandText = "SELECT count(*) FROM pg_indexes " +
|
||||
"WHERE schemaname = 'public' AND tablename = 'provider_accounts' " +
|
||||
"AND indexname = 'IX_provider_accounts_CreatedByUserId'";
|
||||
Assert.Equal(1L, Convert.ToInt64(await command.ExecuteScalarAsync()));
|
||||
}
|
||||
|
||||
await migrator.MigrateAsync(previous);
|
||||
await migrator.MigrateAsync(current);
|
||||
Assert.Equal("uuid", await ColumnType(context, "provider_accounts", "CreatedByUserId"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", "Postgres")]
|
||||
[Trait("Lane", "ReleaseCritical")]
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace allstarr.Core.Storage.Migrations;
|
||||
|
||||
[DbContext(typeof(AllstarrDbContext))]
|
||||
[Migration("20260820173000_RepairProviderAccountCreatorIdentity")]
|
||||
public sealed class RepairProviderAccountCreatorIdentity : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("""
|
||||
DO $repair$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'provider_accounts'
|
||||
AND column_name = 'CreatedByUserId'
|
||||
AND data_type = 'text') THEN
|
||||
ALTER TABLE provider_accounts
|
||||
ALTER COLUMN "CreatedByUserId" TYPE uuid
|
||||
USING "CreatedByUserId"::uuid;
|
||||
END IF;
|
||||
END
|
||||
$repair$;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS "IX_provider_accounts_CreatedByUserId"
|
||||
ON provider_accounts ("CreatedByUserId");
|
||||
|
||||
DO $repair$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conrelid = 'provider_accounts'::regclass
|
||||
AND conname = 'FK_provider_account_creator') THEN
|
||||
ALTER TABLE provider_accounts
|
||||
ADD CONSTRAINT "FK_provider_account_creator"
|
||||
FOREIGN KEY ("CreatedByUserId") REFERENCES users ("Id")
|
||||
ON DELETE SET NULL;
|
||||
END IF;
|
||||
END
|
||||
$repair$;
|
||||
""");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// The repaired UUID shape is the model expected by every supported build. Keeping it
|
||||
// also makes rollback and reapplication safe for databases that never had the drift.
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user