fix: seed all plans/features in prod (upsert); fix admin toggle RTL knob
CI/CD / CI · API (dotnet build + test) (push) Successful in 50s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 39s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Failing after 5m44s
CI/CD / CI · API (dotnet build + test) (push) Successful in 50s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 39s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m5s
CI/CD / CI · Admin Web (tsc) (push) Successful in 35s
CI/CD / CI · Website (tsc) (push) Successful in 45s
CI/CD / CI · Koja (tsc) (push) Successful in 49s
CI/CD / Deploy · all services (push) Failing after 5m44s
Plan + feature seeding was dev-gated and all-or-nothing, so production only had the Free plan (admin Plans page showed one). Now runs in every environment and upserts missing rows (adds Pro/Business/Enterprise on top of the existing Free). Also force LTR on the admin toggle switch so the knob doesn't render off-track under the RTL page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,12 @@ public static class PlatformDataSeeder
|
|||||||
// from their city, so the public map lights up. Idempotent (fills nulls).
|
// from their city, so the public map lights up. Idempotent (fills nulls).
|
||||||
await BackfillCafeLocationsAsync(db, logger);
|
await BackfillCafeLocationsAsync(db, logger);
|
||||||
|
|
||||||
|
// Subscription plans + feature flags are platform config the admin panel
|
||||||
|
// reads in every environment. Idempotent: adds any rows that are missing
|
||||||
|
// (so prod, which only had the Free plan, gets Pro/Business/Enterprise).
|
||||||
|
await SeedPlansAsync(db, logger);
|
||||||
|
await SeedFeaturesAsync(db, logger);
|
||||||
|
|
||||||
if (!env.IsDevelopment())
|
if (!env.IsDevelopment())
|
||||||
{
|
{
|
||||||
// Production: also ensure integration settings (Kavenegar enabled/template,
|
// Production: also ensure integration settings (Kavenegar enabled/template,
|
||||||
@@ -43,8 +49,6 @@ public static class PlatformDataSeeder
|
|||||||
|
|
||||||
await EnsureCatalogUpgradesAsync(db, logger);
|
await EnsureCatalogUpgradesAsync(db, logger);
|
||||||
await SeedSystemAdminAsync(db, logger);
|
await SeedSystemAdminAsync(db, logger);
|
||||||
await SeedPlansAsync(db, logger);
|
|
||||||
await SeedFeaturesAsync(db, logger);
|
|
||||||
await SeedSettingsAsync(db, logger);
|
await SeedSettingsAsync(db, logger);
|
||||||
await EnsureIntegrationSettingsAsync(db, logger);
|
await EnsureIntegrationSettingsAsync(db, logger);
|
||||||
}
|
}
|
||||||
@@ -357,9 +361,6 @@ public static class PlatformDataSeeder
|
|||||||
|
|
||||||
private static async Task SeedPlansAsync(AppDbContext db, ILogger logger)
|
private static async Task SeedPlansAsync(AppDbContext db, ILogger logger)
|
||||||
{
|
{
|
||||||
if (await db.PlatformPlanDefinitions.AnyAsync())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var plans = new[]
|
var plans = new[]
|
||||||
{
|
{
|
||||||
new PlatformPlanDefinition
|
new PlatformPlanDefinition
|
||||||
@@ -421,16 +422,18 @@ public static class PlatformDataSeeder
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
db.PlatformPlanDefinitions.AddRange(plans);
|
var existingIds = (await db.PlatformPlanDefinitions.Select(p => p.Id).ToListAsync())
|
||||||
|
.ToHashSet(StringComparer.Ordinal);
|
||||||
|
var missing = plans.Where(p => !existingIds.Contains(p.Id)).ToArray();
|
||||||
|
if (missing.Length == 0) return;
|
||||||
|
|
||||||
|
db.PlatformPlanDefinitions.AddRange(missing);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
logger.LogInformation("Platform seed: {Count} subscription plans", plans.Length);
|
logger.LogInformation("Platform seed: +{Count} subscription plans", missing.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task SeedFeaturesAsync(AppDbContext db, ILogger logger)
|
private static async Task SeedFeaturesAsync(AppDbContext db, ILogger logger)
|
||||||
{
|
{
|
||||||
if (await db.PlatformFeatures.AnyAsync())
|
|
||||||
return;
|
|
||||||
|
|
||||||
var features = new[]
|
var features = new[]
|
||||||
{
|
{
|
||||||
F("pos", "صندوق", "POS", "core"),
|
F("pos", "صندوق", "POS", "core"),
|
||||||
@@ -456,9 +459,14 @@ public static class PlatformDataSeeder
|
|||||||
F("discover_profile", "پروفایل کشف", "Discover profile", "growth")
|
F("discover_profile", "پروفایل کشف", "Discover profile", "growth")
|
||||||
};
|
};
|
||||||
|
|
||||||
db.PlatformFeatures.AddRange(features);
|
var existingIds = (await db.PlatformFeatures.Select(f => f.Id).ToListAsync())
|
||||||
|
.ToHashSet(StringComparer.Ordinal);
|
||||||
|
var missing = features.Where(f => !existingIds.Contains(f.Id)).ToArray();
|
||||||
|
if (missing.Length == 0) return;
|
||||||
|
|
||||||
|
db.PlatformFeatures.AddRange(missing);
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
logger.LogInformation("Platform seed: {Count} feature flags", features.Length);
|
logger.LogInformation("Platform seed: +{Count} feature flags", missing.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PlatformFeature F(string key, string fa, string en, string group) => new()
|
private static PlatformFeature F(string key, string fa, string en, string group) => new()
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ function Toggle({ checked, onChange, disabled }: { checked: boolean; onChange: (
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
role="switch"
|
role="switch"
|
||||||
|
dir="ltr"
|
||||||
aria-checked={checked}
|
aria-checked={checked}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={() => onChange(!checked)}
|
onClick={() => onChange(!checked)}
|
||||||
|
|||||||
Reference in New Issue
Block a user