using EntitlementBLL.Auth; using EntitlementBLL.Interfaces; using EntitlementSL.Common; using FastEndpoints; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.ResponseStandard; using GB5Shared.FastEndPoint; using ErrorResponse = GB5Shared.Resource.Response.ErrorResponse; using static GB5Shared.GB5Constant.Constant; namespace EntitlementSL.Endpoints.Subscription; // Client-facing — Entitlement↔Payment loose coupling (§9.1). Closes the client portal's own // Billing screen "invoice history" stub: reads PAY's real TPAYORDER history directly // (SourceDocType+SourceDocId), never a local copy — same "own-ClientId-only, no spoofable ID // param" shape as GetMySubscription.cs. A read of the caller's own data, not a commercial // action, so no additional capability required (mirrors GetMySubscription/GetMyRequests). public class GetMyPaymentHistory : BaseEndpoint> { private const string ClientJwtSchemeName = "ClientJwtBearer"; private readonly ISubscriptionService _SubscriptionService; public GetMyPaymentHistory(ISubscriptionService subscriptionService) => _SubscriptionService = subscriptionService; public override void Configure() { Get("/lic/Subscription.svc/GetMyPaymentHistory"); AuthSchemes(ClientJwtSchemeName); Roles(ClientRoleCodes.ClientAdmin, ClientRoleCodes.ClientUser); } public record Params([property: FromHeader] string Login); // Not cached — payment status changes frequently; always query live (same posture as // every real-time payment-adjacent read in this engagement). protected override string? GetCacheKey(Params req, LoginDTO loginDTO) => null; protected override async Task> ExecuteAsync(Params req, LoginDTO loginDTO, CancellationToken ct) { var caller = ClientCallerContext.FromClaims(HttpContext.User.Claims); if (caller.ClientId <= 0) return await GB5Shared.ResponseStandard.Response.CreateErrorResponse( ErrorResponse.AccessDeniedMessage, CacheKeyLevel.NOT_REQUIRED, loginDTO, statusCode: 403); var result = await _SubscriptionService.GetPaymentHistoryAsync(caller.ClientId, ct); return await GB5Shared.ResponseStandard.Response.CreateSuccessResponse(result, CacheKeyLevel.NOT_REQUIRED, loginDTO); } }