using Distribution.Models; using Microsoft.EntityFrameworkCore; namespace Distribution.Data.Seed; public static class RoleAndPermissionSeed { private static readonly DateTime SeedDate = new(2026, 8, 18); private static readonly Guid SalesRepId = new("10000000-0000-0000-0000-000000000001"); private static readonly Guid SupervisorId = new("10000000-0000-0000-0000-000000000002"); private static readonly Guid AreaManagerId = new("10000000-0000-0000-0000-000000000003"); private static readonly Guid AreaSupervisorId = new("10000000-0000-0000-0000-000000000004"); private static readonly Guid RegionalManagerId = new("10000000-0000-0000-0000-000000000005"); private static readonly Guid RegionalAgencyId = new("10000000-0000-0000-0000-000000000006"); private static readonly (string Code, string Description) [] PermissionDefs = [ ("regions.view", "View regions"), ("regions.create", "Create regions"), ("regions.update", "Update regions"), ("regions.delete", "Delete regions"), ("routes.view", "View routes"), ("routes.create", "Create routes"), ("routes.update", "Update routes"), ("routes.delete", "Delete routes"), ("vehicles.view", "View vehicles"), ("vehicles.create", "Create vehicles"), ("vehicles.update", "Update vehicles"), ("vehicles.delete", "Delete vehicles"), ("stores.view", "View stores"), ("stores.create", "Create stores"), ("stores.update", "Update stores"), ("stores.delete", "Delete stores"), ("stores.kyc.verify", "Verify or reject store KYC documents"), ("stores.credit.update", "Update store credit limit and outstanding balance"), ("warehouses.view", "View warehouses"), ("warehouses.create", "Create warehouses"), ("warehouses.update", "Update warehouses"), ("warehouses.delete", "Delete warehouses"), ("orders.view", "View orders"), ("orders.create", "Create orders"), ("orders.update", "Update orders"), ("orders.delete", "Delete orders"), ("users.view", "View users"), ("users.create", "Create users"), ("users.update", "Update users"), ("users.deactivate", "Deactivate users"), ("users.assign_role", "Assign a role to a user"), ("users.assign_scope", "Assign region/route/store scope to a user"), ("items.view", "View items, brands and UOMs"), ("items.create", "Create items, brands and UOMs"), ("items.update", "Update items, brands and UOMs"), ("items.delete", "Delete items, brands and UOMs"), ("categories.view", "View categories"), ("categories.create", "Create categories and subcategories"), ("categories.update", "Update categories and subcategories"), ("categories.delete", "Delete categories and subcategories"), ("driver_profiles.view", "View driver profiles"), ("driver_profiles.create", "Create driver profiles"), ("driver_profiles.update", "Update driver profiles"), ("driver_profiles.deactivate", "Deactivate driver profiles"), ("compliance.manage", "Manage driver compliance configuration"), ("rides.view", "View rides"), ("rides.create", "Create rides"), ("rides.manage", "Manage ride lifecycle"), ("rides.cancel.request", "Request ride cancellation"), ("rides.cancel.approve", "Approve or reject ride cancellations"), ]; private static readonly Dictionary PermissionIds = PermissionDefs .Select((p, i) => (p.Code, Id: DeterministicPermissionId(i))) .ToDictionary(x => x.Code, x => x.Id); private static Guid DeterministicPermissionId(int index) => new($"20000000-0000-0000-0000-{index + 1:D12}"); public static void Apply(ModelBuilder modelBuilder) { modelBuilder.Entity().HasData( new Role { Id = SalesRepId, Name = "SalesRep", Level = 10, CreatedAt = SeedDate, IsActive = true }, new Role { Id = SupervisorId, Name = "Supervisor", Level = 20, CreatedAt = SeedDate, IsActive = true }, new Role { Id = AreaManagerId, Name = "AreaManager", Level = 30, CreatedAt = SeedDate, IsActive = true }, new Role { Id = AreaSupervisorId, Name = "AreaSupervisor", Level = 40, CreatedAt = SeedDate, IsActive = true }, new Role { Id = RegionalManagerId, Name = "RegionalManager", Level = 50, CreatedAt = SeedDate, IsActive = true }, new Role { Id = RegionalAgencyId, Name = "RegionalAgency", Level = 60, CreatedAt = SeedDate, IsActive = true } ); modelBuilder.Entity().HasData( PermissionDefs.Select(p => new Permission { Id = PermissionIds[p.Code], Code = p.Code, Description = p.Description, CreatedAt = SeedDate, IsActive = true }) ); var itemViewPerms = new[] { "items.view", "categories.view" }; var itemManagePerms = new[] { "items.view", "items.create", "items.update", "categories.view" }; var itemPerms = new[] { "items.view", "items.create", "items.update", "items.delete", "categories.view", "categories.create", "categories.update", "categories.delete" }; var salesRepPerms = new[] { "orders.view", "orders.create", "orders.update", "stores.view", "routes.view" }.Concat(itemViewPerms).ToArray(); var supervisorPerms = salesRepPerms.Concat(["orders.delete", "stores.create", "stores.update"]).ToArray(); var ridePerms = new[] { "driver_profiles.view", "driver_profiles.create", "driver_profiles.update", "driver_profiles.deactivate", "compliance.manage", "rides.view", "rides.create", "rides.manage", "rides.cancel.request", "rides.cancel.approve" }; var areaManagerPerms = supervisorPerms.Concat(["vehicles.view", "warehouses.view"]).Concat(itemManagePerms).Concat(ridePerms).Distinct().ToArray(); var areaSupervisorPerms = areaManagerPerms.Concat(["routes.create", "routes.update"]).Concat(itemPerms).Distinct().ToArray(); var regionalManagerPerms = new[] { "orders.view", "orders.create", "orders.update", "orders.delete", "stores.view", "stores.create", "stores.update", "stores.delete", "stores.kyc.verify", "stores.credit.update", "routes.view", "routes.create", "routes.update", "routes.delete", "vehicles.view", "vehicles.create", "vehicles.update", "vehicles.delete", "warehouses.view", "warehouses.create", "warehouses.update", "warehouses.delete", "regions.view", "users.view", "driver_profiles.view", "driver_profiles.create", "driver_profiles.update", "driver_profiles.deactivate", "compliance.manage", "rides.view", "rides.create", "rides.manage", "rides.cancel.request", "rides.cancel.approve", "items.view", "items.create", "items.update", "items.delete", "categories.view", "categories.create", "categories.update", "categories.delete" }; var regionalAgencyPerms = PermissionDefs.Select(p => p.Code).ToArray(); var rolePermissionMap = new (Guid RoleId, string[] Codes)[] { (SalesRepId, salesRepPerms), (SupervisorId, supervisorPerms), (AreaManagerId, areaManagerPerms), (AreaSupervisorId, areaSupervisorPerms), (RegionalManagerId, regionalManagerPerms), (RegionalAgencyId, regionalAgencyPerms), }; modelBuilder.Entity().HasData( rolePermissionMap.SelectMany(rp => rp.Codes.Select(code => new RolePermission { Id = DeterministicRolePermissionId(rp.RoleId, PermissionIds[code]), FK_RoleId = rp.RoleId, FK_PermissionId = PermissionIds[code], CreatedAt = SeedDate, IsActive = true })) ); } private static Guid DeterministicRolePermissionId(Guid roleId, Guid permissionId) { using var md5 = System.Security.Cryptography.MD5.Create(); var bytes = md5.ComputeHash(roleId.ToByteArray().Concat(permissionId.ToByteArray()).ToArray()); return new Guid(bytes); } }