fix(seed): dedupe plans by Tier and features by Key (hotfix crash-loop)
CI/CD / CI · API (dotnet build + test) (push) Successful in 2m39s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 31s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m2s
CI/CD / CI · Admin Web (tsc) (push) Successful in 34s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Successful in 1m27s

The previous change deduped on Id, but the unique constraints are on PlatformPlanDefinitions.Tier and PlatformFeatures.Key. Prod's existing Free plan has a different Id, so seeding re-inserted a Free-tier row and crashed on IX_PlatformPlanDefinitions_Tier (23505), crash-looping the API. Now skips any tier/key that already exists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-02 02:11:42 +03:30
parent 087563bce7
commit 3b8dcf3af6
@@ -422,9 +422,12 @@ public static class PlatformDataSeeder
} }
}; };
var existingIds = (await db.PlatformPlanDefinitions.Select(p => p.Id).ToListAsync()) // Tier (not Id) carries the unique constraint, so dedupe on Tier — an
.ToHashSet(StringComparer.Ordinal); // existing Free plan may have a different Id, and inserting another
var missing = plans.Where(p => !existingIds.Contains(p.Id)).ToArray(); // Free-tier row would violate IX_PlatformPlanDefinitions_Tier.
var existingTiers = (await db.PlatformPlanDefinitions.Select(p => p.Tier).ToListAsync())
.ToHashSet();
var missing = plans.Where(p => !existingTiers.Contains(p.Tier)).ToArray();
if (missing.Length == 0) return; if (missing.Length == 0) return;
db.PlatformPlanDefinitions.AddRange(missing); db.PlatformPlanDefinitions.AddRange(missing);
@@ -459,9 +462,10 @@ public static class PlatformDataSeeder
F("discover_profile", "پروفایل کشف", "Discover profile", "growth") F("discover_profile", "پروفایل کشف", "Discover profile", "growth")
}; };
var existingIds = (await db.PlatformFeatures.Select(f => f.Id).ToListAsync()) // Key carries the unique constraint, so dedupe on Key (not Id).
var existingKeys = (await db.PlatformFeatures.Select(f => f.Key).ToListAsync())
.ToHashSet(StringComparer.Ordinal); .ToHashSet(StringComparer.Ordinal);
var missing = features.Where(f => !existingIds.Contains(f.Id)).ToArray(); var missing = features.Where(f => !existingKeys.Contains(f.Key)).ToArray();
if (missing.Length == 0) return; if (missing.Length == 0) return;
db.PlatformFeatures.AddRange(missing); db.PlatformFeatures.AddRange(missing);