Files
pos-system/services/merchant-service-net/src/MerchantService.API/Application/Queries/Pos/PosQueries.cs
Ho Ngoc Hai a8edfd1597 fix(p2): Wave 3 — fix 4 P2 backend architecture issues (TEC-261)
BACK-I-01: Add CI steps to generate openapi.yaml for all 24 .NET services
- Add .config/dotnet-tools.json with swashbuckle.aspnetcore.cli 7.2.0
- Add scripts/ci/generate-openapi.sh reusable script
- Update all 24 service CI workflows with dotnet tool restore + swagger tofile + artifact upload

BACK-I-02: Add OpenTelemetry Metrics + Prometheus /metrics to _template_dot_net
- Add OTel packages (Extensions.Hosting, Instrumentation.AspNetCore, Runtime, Prometheus)
- Register AddOpenTelemetry().WithMetrics() with ASPNetCore + Runtime instrumentation
- Map MapPrometheusScrapingEndpoint("/metrics") in middleware pipeline

BACK-W-01: Remove IHttpContextAccessor from all 18 handler files in merchant-service-net
- Create MerchantBaseController abstract base with GetCurrentUserId() helper
- Add Guid UserId to 11 Commands and 7 Queries
- Remove IHttpContextAccessor injection from all handlers, use request.UserId instead
- Update 7 controllers to inherit MerchantBaseController and extract userId from JWT claims
- Remove AddHttpContextAccessor() registration from Program.cs

BACK-W-03: Add explicit commandTimeout:5 to all Dapper queries in order-service-net
- 14 files updated: QueryAsync, ExecuteScalarAsync, QueryFirstOrDefaultAsync all get commandTimeout: 5

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-23 10:09:45 +07:00

106 lines
3.3 KiB
C#

// EN: POS queries for staff information.
// VI: Queries POS cho thông tin nhân viên.
using MediatR;
using MerchantService.Domain.AggregatesModel.MerchantStaffAggregate;
using MerchantService.Domain.Exceptions;
namespace MerchantService.API.Application.Queries.Pos;
#region Get POS Staff Query
/// <summary>
/// EN: Query to get current staff info for POS.
/// VI: Query để lấy thông tin nhân viên hiện tại cho POS.
/// </summary>
public record GetPosStaffQuery(Guid UserId) : IRequest<PosStaffDto?>;
/// <summary>
/// EN: Handler for GetPosStaffQuery.
/// VI: Handler cho GetPosStaffQuery.
/// </summary>
public class GetPosStaffQueryHandler : IRequestHandler<GetPosStaffQuery, PosStaffDto?>
{
private readonly IMerchantStaffRepository _staffRepository;
public GetPosStaffQueryHandler(
IMerchantStaffRepository staffRepository)
{
_staffRepository = staffRepository;
}
public async Task<PosStaffDto?> Handle(GetPosStaffQuery request, CancellationToken cancellationToken)
{
// EN: Use user ID passed from the controller
// VI: Dùng user ID được truyền từ controller
var staff = await _staffRepository.GetByUserIdAsync(request.UserId, cancellationToken);
if (staff == null) return null;
return new PosStaffDto
{
StaffId = staff.Id,
MerchantId = staff.MerchantId,
Email = staff.Email ?? string.Empty,
EmployeeCode = staff.EmployeeCode,
Phone = staff.Phone,
Role = staff.Role.Name,
Status = staff.Status.Name,
Permissions = (int)staff.Permissions,
HasPinCode = !string.IsNullOrEmpty(staff.PinCodeHash),
ShopAssignments = staff.ShopAssignments.Select(sm => new PosShopAssignmentDto
{
ShopId = sm.ShopId,
ShopRole = sm.Role.Name,
BranchId = sm.BranchId
}).ToList(),
RegisteredDevices = staff.DeviceTokens.Select(d => new PosDeviceDto
{
DeviceId = d.DeviceId,
DeviceName = d.DeviceName ?? string.Empty,
Platform = d.Platform,
LastUsedAt = d.LastUsedAt
}).ToList()
};
}
}
#endregion
#region POS DTOs
/// <summary>
/// EN: POS staff DTO.
/// VI: DTO nhân viên POS.
/// </summary>
public record PosStaffDto
{
public Guid StaffId { get; init; }
public Guid MerchantId { get; init; }
public string Email { get; init; } = null!;
public string? EmployeeCode { get; init; }
public string? Phone { get; init; }
public string Role { get; init; } = null!;
public string Status { get; init; } = null!;
public int Permissions { get; init; }
public bool HasPinCode { get; init; }
public List<PosShopAssignmentDto> ShopAssignments { get; init; } = [];
public List<PosDeviceDto> RegisteredDevices { get; init; } = [];
}
public record PosShopAssignmentDto
{
public Guid ShopId { get; init; }
public string ShopRole { get; init; } = null!;
public Guid? BranchId { get; init; }
}
public record PosDeviceDto
{
public string DeviceId { get; init; } = null!;
public string DeviceName { get; init; } = null!;
public string Platform { get; init; } = null!;
public DateTime? LastUsedAt { get; init; }
}
#endregion