using line_gestao_api.Models; using line_gestao_api.Services; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace line_gestao_api.Data; public class SeedOptions { public bool Enabled { get; set; } = true; public string DefaultTenantName { get; set; } = "Default"; public string AdminName { get; set; } = "Administrador"; public string AdminEmail { get; set; } = "admin@linegestao.local"; public string AdminPassword { get; set; } = "DevAdmin123!"; public bool ReapplyAdminCredentialsOnStartup { get; set; } = false; } public static class SeedData { public static readonly Guid DefaultTenantId = Guid.Parse("11111111-1111-1111-1111-111111111111"); public static async Task EnsureSeedDataAsync(IServiceProvider services) { using var scope = services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var userManager = scope.ServiceProvider.GetRequiredService>(); var roleManager = scope.ServiceProvider.GetRequiredService>>(); var tenantProvider = scope.ServiceProvider.GetRequiredService(); var options = scope.ServiceProvider.GetRequiredService>().Value; await db.Database.MigrateAsync(); if (!options.Enabled) { return; } var roles = new[] { "admin", "gestor", "operador", "leitura" }; foreach (var role in roles) { if (!await roleManager.RoleExistsAsync(role)) { await roleManager.CreateAsync(new IdentityRole(role)); } } var tenant = await db.Tenants.FirstOrDefaultAsync(t => t.Id == DefaultTenantId); if (tenant == null) { tenant = new Tenant { Id = DefaultTenantId, Name = options.DefaultTenantName, CreatedAt = DateTime.UtcNow }; db.Tenants.Add(tenant); await db.SaveChangesAsync(); } await NormalizeLegacyTenantDataAsync(db, tenant.Id); tenantProvider.SetTenantId(tenant.Id); var normalizedEmail = userManager.NormalizeEmail(options.AdminEmail); var existingAdmin = await userManager.Users .FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail && u.TenantId == tenant.Id); if (existingAdmin == null) { var adminUser = new ApplicationUser { UserName = options.AdminEmail, Email = options.AdminEmail, Name = options.AdminName, TenantId = tenant.Id, EmailConfirmed = true, IsActive = true, LockoutEnabled = true }; var createResult = await userManager.CreateAsync(adminUser, options.AdminPassword); if (createResult.Succeeded) { await userManager.AddToRoleAsync(adminUser, "admin"); } } else if (options.ReapplyAdminCredentialsOnStartup) { existingAdmin.Name = options.AdminName; existingAdmin.Email = options.AdminEmail; existingAdmin.UserName = options.AdminEmail; existingAdmin.EmailConfirmed = true; existingAdmin.IsActive = true; existingAdmin.LockoutEnabled = true; await userManager.SetLockoutEndDateAsync(existingAdmin, null); await userManager.ResetAccessFailedCountAsync(existingAdmin); await userManager.UpdateAsync(existingAdmin); var resetToken = await userManager.GeneratePasswordResetTokenAsync(existingAdmin); var resetPasswordResult = await userManager.ResetPasswordAsync(existingAdmin, resetToken, options.AdminPassword); if (!resetPasswordResult.Succeeded) { var removePasswordResult = await userManager.RemovePasswordAsync(existingAdmin); if (removePasswordResult.Succeeded) { await userManager.AddPasswordAsync(existingAdmin, options.AdminPassword); } } if (!await userManager.IsInRoleAsync(existingAdmin, "admin")) { await userManager.AddToRoleAsync(existingAdmin, "admin"); } } tenantProvider.SetTenantId(null); } private static async Task NormalizeLegacyTenantDataAsync(AppDbContext db, Guid defaultTenantId) { if (defaultTenantId == Guid.Empty) return; await db.Users .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.MobileLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.MuregLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.BillingClients .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.UserDatas .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.VigenciaLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.TrocaNumeroLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ChipVirgemLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ControleRecebidoLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.Notifications .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoMacrophonyPlans .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoMacrophonyTotals .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoVivoLineResumos .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoVivoLineTotals .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoClienteEspeciais .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoPlanoContratoResumos .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoPlanoContratoTotals .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoLineTotais .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoReservaLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ResumoReservaTotals .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ParcelamentoLines .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ParcelamentoMonthValues .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.AuditLogs .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ImportAuditRuns .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); await db.ImportAuditIssues .IgnoreQueryFilters() .Where(x => x.TenantId == Guid.Empty) .ExecuteUpdateAsync(setters => setters.SetProperty(x => x.TenantId, defaultTenantId)); } }