Handler.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Forum.Posts.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. using SharedKernel.Results;
  6. namespace Application.Features.Api.Forum.StockBoard.GetPrediction;
  7. /// <summary>글의 예측 메타 + 채점 상태 (d2 §④ M2, 익명). 예측이 없으면 NotFound.</summary>
  8. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  9. {
  10. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  11. {
  12. var prediction = await db.PostPrediction.AsNoTracking()
  13. .Where(c => c.PostID == request.PostID)
  14. .Select(c => new
  15. {
  16. c.PostID,
  17. c.MemberID,
  18. c.StockCode,
  19. c.Direction,
  20. c.BasePrice,
  21. c.TargetPrice,
  22. c.HorizonDays,
  23. c.DueDate,
  24. c.Status,
  25. c.SettledPrice,
  26. c.SettledAt,
  27. c.CreatedAt
  28. })
  29. .FirstOrDefaultAsync(ct);
  30. if (prediction is null)
  31. {
  32. return Result.Failure<Response>(Error.NotFound("Prediction.NotFound", "예측 정보를 찾을 수 없습니다."));
  33. }
  34. var stockName = await db.Stock.AsNoTracking().Where(c => c.Code == prediction.StockCode).Select(c => c.Name).FirstOrDefaultAsync(ct);
  35. return new Response(
  36. prediction.PostID,
  37. prediction.MemberID,
  38. prediction.StockCode,
  39. stockName,
  40. (byte)prediction.Direction,
  41. DirectionLabel(prediction.Direction),
  42. prediction.BasePrice,
  43. prediction.TargetPrice,
  44. prediction.HorizonDays,
  45. prediction.DueDate,
  46. (byte)prediction.Status,
  47. StatusLabel(prediction.Status),
  48. prediction.SettledPrice,
  49. prediction.SettledAt,
  50. prediction.CreatedAt);
  51. }
  52. private static string DirectionLabel(PredictionDirection direction) => direction switch
  53. {
  54. PredictionDirection.Up => "상승",
  55. PredictionDirection.Down => "하락",
  56. _ => "알수없음"
  57. };
  58. private static string StatusLabel(PredictionStatus status) => status switch
  59. {
  60. PredictionStatus.Pending => "채점대기",
  61. PredictionStatus.Hit => "적중",
  62. PredictionStatus.Miss => "실패",
  63. PredictionStatus.Void => "무효",
  64. _ => "알수없음"
  65. };
  66. }