using System.Security.Claims;
using System.Text.Json.Serialization;
using Application.Abstractions.Messaging;
using Domain.Entities.Paper.ValueObject;
using SharedKernel.Results;
using Web.Api.Common;
using Web.Api.Extensions;
namespace Web.Api.Endpoints.Paper;
public sealed class PlaceOrderRequest
{
[JsonPropertyName("stockCode")]
public string StockCode { get; set; } = "";
/// 주문 방향 — "Buy" | "Sell" (대소문자 무시).
[JsonPropertyName("side")]
public string Side { get; set; } = "";
[JsonPropertyName("quantity")]
public int Quantity { get; set; }
}
/// 모의투자 — 주문 접수.
internal sealed class PlaceOrder : IEndpoint
{
public void MapEndpoint(IEndpointRouteBuilder app)
{
app.MapPost("api/paper/orders", async (
PlaceOrderRequest body,
ClaimsPrincipal user,
ISender sender,
CancellationToken ct
) => {
if (!Enum.TryParse(body.Side, ignoreCase: true, out var side) || !Enum.IsDefined(side))
{
return CustomResults.Problem(Result.Failure(Error.Problem("Paper.InvalidSide", "주문 방향(side)이 올바르지 않습니다. (Buy | Sell)")));
}
var memberID = user.GetRequiredMemberID();
var result = await sender.Send(new Application.Features.Api.Paper.PlaceOrder.Command(memberID, body.StockCode, side, body.Quantity), ct);
if (result.IsFailure)
{
return CustomResults.Problem(result);
}
return ApiResponse.Ok(result.Value);
})
.WithTags("Paper")
.RequireAuthorization();
}
}