| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Messaging;
- using Domain.Entities.Developers.ValueObject;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- namespace Application.Features.Api.V1.Purchases.List;
- internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
- {
- public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
- {
- var page = Math.Max(1, request.Page);
- var size = Math.Clamp(request.Size, 1, 100);
- var query = db.ApiPurchase.AsNoTracking().AsQueryable();
- // 호출 주체 범위 제한 — OAuth2: 해당 앱 / PAT: 본인 소유 앱 전체
- if (request.ApplicationID.HasValue)
- {
- query = query.Where(c => c.ApplicationID == request.ApplicationID.Value);
- }
- else if (request.OwnerMemberID.HasValue)
- {
- query = query.Where(c => c.Application!.OwnerMemberID == request.OwnerMemberID.Value);
- }
- else
- {
- return Result.Failure<Response>(Error.Unauthorized("Purchase.CallerUnknown", "호출 주체를 식별할 수 없습니다."));
- }
- // 상태 필터 (pending / confirmed / canceled)
- if (!string.IsNullOrWhiteSpace(request.Status))
- {
- if (!Enum.TryParse<ApiPurchaseStatus>(request.Status.Trim(), ignoreCase: true, out var status))
- {
- return Result.Failure<Response>(Error.Problem("Purchase.StatusInvalid", "status 는 pending / confirmed / canceled 중 하나여야 합니다."));
- }
- query = query.Where(c => c.Status == status);
- }
- if (request.From.HasValue)
- {
- query = query.Where(c => c.CreatedAt >= request.From.Value);
- }
- if (request.To.HasValue)
- {
- query = query.Where(c => c.CreatedAt <= request.To.Value);
- }
- var total = await query.CountAsync(ct);
- var items = await query
- .OrderByDescending(c => c.ID)
- .Skip((page - 1) * size)
- .Take(size)
- .Select(c => new Response.Row(
- c.ID,
- c.OrderID,
- (int)c.Marketplace,
- c.Channel!.DonationCode,
- c.Game!.Code ?? string.Empty,
- c.OrderPrice,
- c.CommissionRate,
- c.CommissionAmount,
- c.Status.ToString(),
- c.ConfirmDueAt,
- c.ConfirmedAt,
- c.CanceledAt,
- c.CreatedAt
- ))
- .ToListAsync(ct);
- return Result.Success(new Response(total, page, size, items));
- }
- }
|