using AuthHex.Models; using AuthHex.Utility.passwordHasher; using Microsoft.EntityFrameworkCore; namespace AuthHex.Infra.Seed { /// /// Idempotent bootstrap seed so the system is usable on a fresh database: /// two UserTypes, one ADMIN Role (fixed well-known GUID, mirrored by ERP-core's /// DataSeeder so the two role stores line up), and one admin User to log in with. /// Admin credentials are config-overridable (Bootstrap:AdminEmail / :AdminPassword). /// public static class AuthHexSeeder { // Fixed GUIDs shared with ERP-core (ERPCore DataSeeder seeds the same ADMIN RoleId). public static readonly Guid AdminRoleId = Guid.Parse("11111111-1111-1111-1111-111111111111"); public static readonly Guid ErpAdminUserTypeId = Guid.Parse("21111111-1111-1111-1111-111111111111"); public static readonly Guid ErpStaffUserTypeId = Guid.Parse("22222222-2222-2222-2222-222222222222"); public static readonly Guid AdminUserId = Guid.Parse("a1111111-1111-1111-1111-111111111111"); // core-api hardcodes these exact GUIDs when it registers a new Customer/Client/Staff // user via this service's registerUser endpoint (see Fitness_core_BE ClientService.cs // / StaffService.cs) -- they must exist here as real Role/UserType rows or that // registration call fails its FK check. UserRoleHelper.GetUserType in core-api doesn't // actually read these Code strings for authorization (it goes by which central table -- // Admin/Customer/Client/Staff -- has a row for the user), so only the GUIDs themselves // are load-bearing; the Code/Name text is just for readability. public static readonly Guid CustomerUserTypeId = Guid.Parse("00000000-0000-0000-0000-000000000001"); public static readonly Guid ClientUserTypeId = Guid.Parse("00000000-0000-0000-0000-000000000002"); public static readonly Guid StaffUserTypeId = Guid.Parse("00000000-0000-0000-0000-000000000003"); public static readonly Guid CustomerRoleId = Guid.Parse("08de6a11-9e9f-4401-8a10-685cc57b41ed"); public static readonly Guid ClientRoleId = Guid.Parse("08de6a11-9e9f-4401-8a10-6859860b41ed"); public static readonly Guid StaffRoleId = Guid.Parse("08de6a11-9e9f-4401-8a10-6854567b41ed"); public static async Task SeedAsync(AppDBContext db, IConfiguration config, CancellationToken ct = default) { // --- UserTypes --- if (!await db.UserType.AnyAsync(t => t.UserTypeId == ErpAdminUserTypeId, ct)) db.UserType.Add(new UserType { UserTypeId = ErpAdminUserTypeId, Code = "ERP_ADMIN", Description = "ERP administrator", CreatedAt = DateTime.UtcNow }); if (!await db.UserType.AnyAsync(t => t.UserTypeId == ErpStaffUserTypeId, ct)) db.UserType.Add(new UserType { UserTypeId = ErpStaffUserTypeId, Code = "ERP_STAFF", Description = "ERP staff", CreatedAt = DateTime.UtcNow }); if (!await db.UserType.AnyAsync(t => t.UserTypeId == CustomerUserTypeId, ct)) db.UserType.Add(new UserType { UserTypeId = CustomerUserTypeId, Code = "Customer", Description = "Gym member", CreatedAt = DateTime.UtcNow }); if (!await db.UserType.AnyAsync(t => t.UserTypeId == ClientUserTypeId, ct)) db.UserType.Add(new UserType { UserTypeId = ClientUserTypeId, Code = "Client", Description = "Club owner", CreatedAt = DateTime.UtcNow }); if (!await db.UserType.AnyAsync(t => t.UserTypeId == StaffUserTypeId, ct)) db.UserType.Add(new UserType { UserTypeId = StaffUserTypeId, Code = "Staff", Description = "Club staff", CreatedAt = DateTime.UtcNow }); // --- ADMIN role (same RoleId ERP-core seeds) --- if (!await db.Roles.AnyAsync(r => r.RoleId == AdminRoleId, ct)) db.Roles.Add(new Role { RoleId = AdminRoleId, Code = "ADMIN", Name = "Administrator", IsSystemRole = true, CreatedAt = DateTime.UtcNow }); if (!await db.Roles.AnyAsync(r => r.RoleId == CustomerRoleId, ct)) db.Roles.Add(new Role { RoleId = CustomerRoleId, Code = "CUSTOMER", Name = "Customer", IsSystemRole = true, CreatedAt = DateTime.UtcNow }); if (!await db.Roles.AnyAsync(r => r.RoleId == ClientRoleId, ct)) db.Roles.Add(new Role { RoleId = ClientRoleId, Code = "CLIENT", Name = "Client", IsSystemRole = true, CreatedAt = DateTime.UtcNow }); if (!await db.Roles.AnyAsync(r => r.RoleId == StaffRoleId, ct)) db.Roles.Add(new Role { RoleId = StaffRoleId, Code = "STAFF", Name = "Staff", IsSystemRole = true, CreatedAt = DateTime.UtcNow }); await db.SaveChangesAsync(ct); // --- Admin user (after role/type exist for the FK) --- var adminEmail = config["Bootstrap:AdminEmail"] ?? "admin@erp.local"; var adminPassword = config["Bootstrap:AdminPassword"] ?? "Admin@123"; if (!await db.Users.AnyAsync(u => u.Id == AdminUserId, ct)) { db.Users.Add(new User { Id = AdminUserId, FullName = "ERP Administrator", UserName = "admin", Email = adminEmail, EmailVerified = true, PasswordHash = PasswordHasher.Hash(adminPassword), RoleId = AdminRoleId, UserTypeId = ErpAdminUserTypeId, IsActive = true, IsLocked = false, CreatedAt = DateTime.UtcNow }); await db.SaveChangesAsync(ct); } } } }