fix(iam): return real role data — description, isSystemRole, createdAt, userCount

- IamServiceContext: add EF column mappings for ApplicationRole private
  fields (description, is_system_role, created_at) matching new DB columns
- GetRolesQueryHandler: JOIN with UserRoles to compute real user count
  per role instead of returning 0
- RoleDto/RoleResponse: add UserCount field
- DB: added columns description, is_system_role, created_at to roles table
  with correct data for all 8 roles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ho Ngoc Hai
2026-03-25 18:53:05 +07:00
parent f3217ab270
commit 2ce17f0940
4 changed files with 40 additions and 12 deletions

View File

@@ -31,4 +31,5 @@ public record RoleDto(
string Name,
string? Description,
bool IsSystemRole,
DateTime CreatedAt);
DateTime CreatedAt,
int UserCount = 0);

View File

@@ -2,23 +2,27 @@ using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using IamService.Domain.AggregatesModel.RoleAggregate;
using IamService.Infrastructure;
namespace IamService.API.Application.Queries.Roles;
/// <summary>
/// EN: Handler for GetRolesQuery.
/// VI: Handler cho GetRolesQuery.
/// EN: Handler for GetRolesQuery — includes user count per role via DB join.
/// VI: Handler cho GetRolesQuery — bao gồm số user mỗi role qua DB join.
/// </summary>
public class GetRolesQueryHandler : IRequestHandler<GetRolesQuery, GetRolesQueryResult>
{
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly IamServiceContext _dbContext;
private readonly ILogger<GetRolesQueryHandler> _logger;
public GetRolesQueryHandler(
RoleManager<ApplicationRole> roleManager,
IamServiceContext dbContext,
ILogger<GetRolesQueryHandler> logger)
{
_roleManager = roleManager;
_dbContext = dbContext;
_logger = logger;
}
@@ -27,19 +31,25 @@ public class GetRolesQueryHandler : IRequestHandler<GetRolesQuery, GetRolesQuery
_logger.LogInformation("Getting roles - Page: {Page}, Size: {Size}", request.PageNumber, request.PageSize);
var query = _roleManager.Roles;
var totalCount = await query.CountAsync(cancellationToken);
// EN: Join with UserRoles to get user count per role
// VI: Join với UserRoles để lấy số user mỗi role
var roles = await query
.OrderBy(r => r.Name)
.Skip((request.PageNumber - 1) * request.PageSize)
.Take(request.PageSize)
.Select(r => new RoleDto(
r.Id,
r.Name!,
r.Description,
r.IsSystemRole,
r.CreatedAt))
.GroupJoin(
_dbContext.UserRoles,
role => role.Id,
userRole => userRole.RoleId,
(role, userRoles) => new RoleDto(
role.Id,
role.Name!,
role.Description,
role.IsSystemRole,
role.CreatedAt,
userRoles.Count()))
.ToListAsync(cancellationToken);
return new GetRolesQueryResult(

View File

@@ -67,7 +67,8 @@ public class RolesController : ControllerBase
Name = r.Name,
Description = r.Description,
IsSystemRole = r.IsSystemRole,
CreatedAt = r.CreatedAt
CreatedAt = r.CreatedAt,
UserCount = r.UserCount
}),
Pagination = new PaginationInfo
{
@@ -435,6 +436,12 @@ public class RoleResponse
/// VI: Thời gian tạo.
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// EN: Number of users assigned this role.
/// VI: Số lượng người dùng được gán role này.
/// </summary>
public int UserCount { get; set; }
}
#endregion

View File

@@ -196,7 +196,17 @@ public class IamServiceContext : IdentityDbContext<ApplicationUser, ApplicationR
b.Ignore(u => u.LastLoginAt);
b.Ignore(u => u.DomainEvents);
});
modelBuilder.Entity<ApplicationRole>().ToTable("roles");
modelBuilder.Entity<ApplicationRole>(b =>
{
b.ToTable("roles");
b.Property<string>("_description").HasColumnName("description");
b.Property<bool>("_isSystemRole").HasColumnName("is_system_role");
b.Property<DateTime>("_createdAt").HasColumnName("created_at");
b.Ignore(r => r.Description);
b.Ignore(r => r.IsSystemRole);
b.Ignore(r => r.CreatedAt);
b.Ignore(r => r.DomainEvents);
});
modelBuilder.Entity<IdentityUserRole<Guid>>().ToTable("user_roles");
modelBuilder.Entity<IdentityUserClaim<Guid>>().ToTable("user_claims");
modelBuilder.Entity<IdentityUserLogin<Guid>>().ToTable("user_logins");