Handler.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. using Application.Abstractions.Chat;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Messaging;
  4. using Application.Helpers;
  5. using Microsoft.EntityFrameworkCore;
  6. using SharedKernel.Results;
  7. namespace Application.Features.Api.Chat.GetHistory;
  8. /// <summary>
  9. /// 룸 최근 메시지 히스토리 (D2 M1) — 익명 허용 (게스트 읽기 — d0 §5-④).
  10. /// main 은 항상 조회 가능, 종목방은 ChatRoomConfig row 존재 + IsActive 시에만 (단계 오픈).
  11. /// </summary>
  12. internal sealed class Handler(IAppDbContext db, IChatMessageStore messageStore) : IQueryHandler<Query, Result<Response>>
  13. {
  14. public const int DefaultCount = 50;
  15. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  16. {
  17. var roomKey = request.RoomKey?.Trim() ?? string.Empty;
  18. if (!ChatRoomKeys.IsValid(roomKey))
  19. {
  20. return Result.Failure<Response>(Error.NotFound("Chat.RoomNotFound", "존재하지 않는 채팅방입니다."));
  21. }
  22. var row = await db.ChatRoomConfig.AsNoTracking().Where(c => c.RoomKey == roomKey).Select(c => new { c.IsActive, c.SlowModeSeconds, c.Notice }).FirstOrDefaultAsync(ct);
  23. var config = row is null
  24. ? new ChatRoomConfigLoader.RoomConfig(false, false, 0, null)
  25. : new ChatRoomConfigLoader.RoomConfig(true, row.IsActive, row.SlowModeSeconds, row.Notice);
  26. if (!ChatRoomConfigLoader.IsRoomOpen(roomKey, config))
  27. {
  28. return Result.Failure<Response>(Error.NotFound("Chat.RoomNotOpen", "아직 열리지 않은 채팅방입니다."));
  29. }
  30. var count = Math.Clamp(request.Count <= 0 ? DefaultCount : request.Count, 1, ChatSettings.MaxMessages);
  31. var messages = await messageStore.GetRecentMessagesAsync(roomKey, count);
  32. return new Response
  33. {
  34. RoomKey = roomKey,
  35. Notice = config.Notice,
  36. SlowModeSeconds = config.SlowModeSeconds,
  37. Messages = messages
  38. };
  39. }
  40. }