using DXPBLL.Kyc; using DXPDAL.Common; using DXPSL.Parameters.Kyc; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using FastEndpoints; using GB5Shared.Authorization; namespace DXPSL.Endpoints.Kyc; // Moved off DXPBaseEndpoint (the vendor-facing JWT model every other DXP endpoint uses) onto // GB5's standard internal Login-header/[MenuRights] mechanism — this is a GB-client-side admin // action (a client's own staff approving/rejecting a vendor's KYC submission), not vendor // self-service. Confirmed via: this endpoint's own prior comment ("GB-client-side admin"), the // vendor-portal demo UI's parallel "GB-client admins" framing, and DXP's RoleCode taxonomy // (VendorGM|FinanceContact|OperationsContact|QualityContact|ReadOnly — see UserPartyRoleDTO.cs) // never having an admin tier; there is no vendor-side identity this was ever meant to run as. // // This also fixes a real identity-space bug: VerifiedById was previously stamped from // caller.DxpUserId (a vendor's global Party identity — a different ID space from MUSER, per // VendorPoBLL.cs's own documented note on this exact distinction) instead of a real internal // MUSER.UserId. // // KYC profiles still live in DXP's single shared system database (IDXPSystemContext.GetSystemLogin, // ClientId=0 sentinel) — not the caller's own tenant business DB. So the Login-header LoginDTO is // used ONLY to authorize the caller ([MenuRights], checked against their own tenant's MROLEVSMENU) // and to capture their real UserId for VerifiedById; the actual KYC read/write still goes through // the system LoginDTO, same as before. [MenuRights("dxpkycverification", RightOperation.Update)] public class VerifyKyc : BaseEndpoint> { private readonly IKycBLL _bll; private readonly IDXPSystemContext _systemContext; public VerifyKyc(IKycBLL bll, IDXPSystemContext systemContext) { _bll = bll; _systemContext = systemContext; } public override void Configure() { Post("/DXP/Kyc/Verify"); AllowAnonymous(); } public record Params( [property: FromHeader] string Login, [property: FromBody] VerifyKycParameters VerifyKycParameters ); protected override string? GetCacheKey(Params req, LoginDTO loginDTO) => null; protected override async Task> ExecuteAsync(Params req, LoginDTO loginDTO, CancellationToken ct) { var body = req.VerifyKycParameters; var systemLogin = _systemContext.GetSystemLogin(loginDTO.UserId); var message = await _bll.VerifyAsync( body.DxpPartyKycProfileId, body.Approved, body.RejectionReason, systemLogin, ct); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse( message, GB5Shared.GB5Constant.Constant.CacheKeyLevel.NOT_REQUIRED, loginDTO); } }