Files
ROLAC/API/ROLAC.API/Data/DbSeeder.cs
T
2026-05-28 16:19:44 -07:00

115 lines
4.3 KiB
C#

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<AppRole> 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();
}
/// <summary>
/// Seeds roles and (in Development) the default admin account.
/// Called once on application startup after migrations have been applied.
/// </summary>
public static async Task SeedAsync(IServiceProvider services)
{
var roleManager = services.GetRequiredService<RoleManager<AppRole>>();
var userManager = services.GetRequiredService<UserManager<AppUser>>();
var env = services.GetRequiredService<IWebHostEnvironment>();
await SeedRolesAsync(roleManager);
var db = services.GetRequiredService<AppDbContext>();
await SeedGivingCategoriesAsync(db);
if (env.IsDevelopment())
await SeedAdminUserAsync(userManager);
}
/// <summary>
/// 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!
/// </summary>
public static async Task SeedAdminUserAsync(UserManager<AppUser> 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");
}
}
}