diff --git a/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs b/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs index 97ddee1..b9d9d16 100644 --- a/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs +++ b/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs @@ -2038,6 +2038,12 @@ public static class DbInitializer // (GetMyMenuTree lọc CanRead). Chạy SAU grant seed để revoke thắng. // Mở lại sau golive: gỡ prefix khỏi revoke + thêm lại vào InReviewScope. await RevokeTemporarilyHiddenModulesAsync(db, roleManager, logger); + + // [S65 2026-06-16] CHẠY SAU revoke để THẮNG: mở lại quyền XEM "Hồ sơ Nhân sự" + // (+ root nhóm "Nhân sự") cho MỌI role — anh chốt public module Nhân sự cho + // user thường tra cứu hồ sơ. Dashboard NS (Hrm_Dashboard) + 6 catalog + // Hrm_Config* VẪN ẨN (revoke che). Read-only (chỉ CanRead). + await SeedAllRolesHrmProfileReadPermissionsAsync(db, roleManager, logger); } // [S57] Cấp CanRead (CHỈ xem) cho MỌI role trên menu HRM + Office + Master để mọi @@ -2183,6 +2189,66 @@ public static class DbInitializer } } + // [S65 2026-06-16] Mở quyền XEM (Read-only) "Hồ sơ Nhân sự" cho MỌI role: anh chốt + // public module Nhân sự (trọng tâm Hồ sơ NS) để user thường tra cứu hồ sơ nhân sự. + // CHẠY SAU RevokeTemporarilyHiddenModulesAsync (SeedAsync) để THẮNG revoke: revoke + // set mọi Hrm* = false cho non-Admin; method này nâng RIÊNG 2 key Hrm + Hrm_HoSo. + // - GIỮ ẨN: Dashboard NS (Hrm_Dashboard) + 6 catalog Hrm_Config* — vẫn bị revoke che. + // - Read-only: chỉ CanRead. Create/Update/Delete hồ sơ vẫn khóa qua policy + // Hrm_HoSo.{Create/Update/Delete} (EmployeesController) — non-Admin không có. + // - UPGRADE-ONLY (mirror Pe S57bis :2107): row đã tồn tại (revoke vừa set CanRead + // =false trên prod) → NÂNG CanRead=true. Row chưa có (DB mới) → tạo CanRead=true, + // cờ khác false. KHÔNG hạ + KHÔNG đụng Create/Update/Delete (không phá quyền admin). + // Flip ẩn lại khi cần: xóa call ở SeedAsync — revoke sẽ tự che lại lần seed kế. + private static async Task SeedAllRolesHrmProfileReadPermissionsAsync( + ApplicationDbContext db, RoleManager roleManager, ILogger logger) + { + // Root nhóm "Nhân sự" (để menu group hiện chắc chắn) + leaf "Hồ sơ Nhân sự". + // KHÔNG Hrm_Dashboard, KHÔNG Hrm_Config* (giữ ẩn theo scope anh chốt). + var hrmKeys = new[] { MenuKeys.Hrm, MenuKeys.HrmHoSo }; + var roles = await roleManager.Roles.ToListAsync(); + + var existingRows = (await db.Permissions + .Where(p => hrmKeys.Contains(p.MenuKey)) + .ToListAsync()) + .ToDictionary(p => (p.RoleId, p.MenuKey)); + + var added = 0; + var upgraded = 0; + foreach (var role in roles) + { + foreach (var key in hrmKeys) + { + if (existingRows.TryGetValue((role.Id, key), out var row)) + { + // Upgrade-only: nâng CanRead nếu đang false (revoke vừa set false). + if (!row.CanRead) { row.CanRead = true; upgraded++; } + continue; + } + + db.Permissions.Add(new Permission + { + RoleId = role.Id, + MenuKey = key, + CanRead = true, + CanCreate = false, + CanUpdate = false, + CanDelete = false, + }); + added++; + } + } + + if (added > 0 || upgraded > 0) + { + await db.SaveChangesAsync(); + logger.LogInformation( + "Seeded all-roles HRM profile read perms: {Added} added + {Upgraded} upgraded " + + "(Hrm + Hrm_HoSo CanRead — public Hồ sơ NS, S65)", + added, upgraded); + } + } + // [Plan CA S29 2026-05-22] Permission defaults cho role CatalogManager. // Strategy: full CRUD trên 9 menu key danh mục dùng chung: // - Master (root group) + Suppliers + Projects + Departments