feat(prod): флаг SEED_DEMO_DATA — отключить демо-орг «Demo Market» и demo-admin на проде
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions

DevDataSeeder по умолчанию (dev/stage) сидирует демо-орг; на проде SEED_DEMO_DATA=false
отключает демо-орг/demo-admin/привязку, сохраняя SuperAdmin+роли+глобальные ед.изм.+SystemSettings.
Нужно для чистого (пустого) старта реального магазина.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nns 2026-10-09 19:19:10 +05:00
parent 7229a50a74
commit 77464d6c83

View file

@ -43,6 +43,13 @@ public async Task StartAsync(CancellationToken ct)
if (string.IsNullOrWhiteSpace(seedPassword) && _env.IsDevelopment())
seedPassword = "Admin12345!";
// Демо-организация «Demo Market» и demo-admin — для dev/stage. На ПРОДЕ их
// быть НЕ должно (чистый старт реального магазина): отключается флагом
// SEED_DEMO_DATA=false (или Seed:DemoData=false) в .env прода. По умолчанию
// (флаг не задан) демо сидируется — поведение dev/stage не меняется.
var seedDemoRaw = Environment.GetEnvironmentVariable("SEED_DEMO_DATA") ?? cfg["Seed:DemoData"];
var seedDemo = !string.Equals(seedDemoRaw, "false", StringComparison.OrdinalIgnoreCase);
foreach (var role in new[] { SystemRoles.SuperAdmin, SystemRoles.Admin, SystemRoles.Cashier, SystemRoles.Storekeeper })
{
if (!await roleMgr.RoleExistsAsync(role))
@ -57,7 +64,10 @@ public async Task StartAsync(CancellationToken ct)
await SeedGlobalUnitsAsync(db, ct);
var kzt = await db.Currencies.FirstOrDefaultAsync(c => c.Code == "KZT", ct);
var demoOrg = await db.Organizations.FirstOrDefaultAsync(o => o.Name == "Demo Market", ct);
Organization? demoOrg = null;
if (seedDemo)
{
demoOrg = await db.Organizations.FirstOrDefaultAsync(o => o.Name == "Demo Market", ct);
if (demoOrg is null)
{
demoOrg = new Organization
@ -80,6 +90,7 @@ public async Task StartAsync(CancellationToken ct)
}
await SeedTenantReferencesAsync(db, demoOrg.Id, ct);
}
// SuperAdmin платформы — без OrganizationId, видит все организации
const string superAdminEmail = "admin@food-market.local";
@ -126,7 +137,9 @@ public async Task StartAsync(CancellationToken ct)
}
}
// Admin демо-организации — владелец/директор Demo Market
// Admin демо-организации — владелец/директор Demo Market (только dev/stage).
if (seedDemo && demoOrg is not null)
{
const string demoAdminEmail = "admin@demo-market.local";
var demoAdmin = await userMgr.FindByEmailAsync(demoAdminEmail);
if (demoAdmin is null && !string.IsNullOrWhiteSpace(seedPassword))
@ -150,6 +163,7 @@ public async Task StartAsync(CancellationToken ct)
}
await SeedAdminEmployeeAsync(db, demoOrg.Id, superAdmin?.Id, ct);
}
// Глобальные SystemSettings — single-row. Сидируем дефолт 30 дней
// retention если ещё нет записи.