using Microsoft.AspNetCore.Identity; using ROLAC.API.Entities; namespace ROLAC.API.Data; public static class DbSeeder { private static readonly (string En, string Zh, int Sort)[] GivingCategorySeed = [ ("Tithe", "什一奉獻", 1), ("General Offering", "一般奉獻", 2), ("Special Offering", "特別奉獻", 3), ("Building Fund", "建堂基金", 4), ("Mission", "宣教奉獻", 5), ]; private static readonly (string Name, string Description)[] Roles = [ ("super_admin", "System administrator — full access"), ("pastor", "Pastor — full member and financial overview"), ("board_member", "Board member — church governance"), ("coworker_chair", "Coworker chair — coordinates ministry leaders"), ("ministry_leader", "Ministry leader — scoped to own ministry"), ("district_leader", "District leader — manages multiple cell groups"), ("cell_leader", "Cell leader — scoped to own cell group"), ("coworker", "Coworker — general worker in assigned ministry"), ("finance", "Finance — manages giving and expense reports"), ("secretary", "Secretary — manages member data and scheduling"), ("worship_leader", "Worship leader — manages song library and setlists (Phase deferred)"), ("member", "Member — views own profile and service roster"), ("visitor", "Visitor — public pages only"), ]; public static async Task SeedRolesAsync(RoleManager roleManager) { foreach (var (name, description) in Roles) { if (!await roleManager.RoleExistsAsync(name)) { await roleManager.CreateAsync(new AppRole { Name = name, Description = description, }); } } } public static async Task SeedGivingCategoriesAsync(AppDbContext db) { foreach (var (en, zh, sort) in GivingCategorySeed) { if (!db.GivingCategories.Any(c => c.Name_en == en)) { db.GivingCategories.Add(new GivingCategory { Name_en = en, Name_zh = zh, SortOrder = sort, IsActive = true, // Audit fields are stamped by AuditSaveChangesInterceptor on save. }); } } await db.SaveChangesAsync(); } /// /// Seeds roles and (in Development) the default admin account. /// Called once on application startup after migrations have been applied. /// public static async Task SeedAsync(IServiceProvider services) { var roleManager = services.GetRequiredService>(); var userManager = services.GetRequiredService>(); var env = services.GetRequiredService(); await SeedRolesAsync(roleManager); var db = services.GetRequiredService(); await SeedGivingCategoriesAsync(db); if (env.IsDevelopment()) await SeedAdminUserAsync(userManager); } /// /// Creates a super_admin test account for local development. /// DO NOT call this in production — remove or guard with IsDevelopment(). /// Credentials: admin@rolac.org / Admin1234! /// public static async Task SeedAdminUserAsync(UserManager userManager) { const string adminEmail = "admin@rolac.org"; const string adminPassword = "Admin1234!"; if (await userManager.FindByEmailAsync(adminEmail) is null) { var admin = new AppUser { UserName = adminEmail, Email = adminEmail, EmailConfirmed = true, IsActive = true, LanguagePreference = "en", CreatedAt = DateTime.UtcNow, }; var result = await userManager.CreateAsync(admin, adminPassword); if (result.Succeeded) await userManager.AddToRoleAsync(admin, "super_admin"); } } }