Handler.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Application.Abstractions.Messaging;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Cache;
  4. using SharedKernel.Results;
  5. using Microsoft.EntityFrameworkCore;
  6. using BoardMetaResponse = Application.Features.Api.Forum.BoardMeta.Get.Response;
  7. namespace Application.Features.Api.Forum.Board.Get;
  8. public sealed class Handler(IAppDbContext db, ICacheService cache) : IQueryHandler<Query, Result<Response>>
  9. {
  10. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  11. {
  12. var item = await db.Board
  13. .AsNoTracking()
  14. .Include(x => x.BoardGroup)
  15. .Include(x => x.BoardPrefix.Where(p => p.IsActive).OrderBy(p => p.Order))
  16. .Include(x => x.BoardManager)
  17. .ThenInclude(m => m.Member)
  18. .FirstOrDefaultAsync(x => x.Code == request.Code, ct);
  19. if (item is null)
  20. {
  21. return Result.Failure<Response>(Error.NotFound("Board.NotFound", "게시판을 찾을 수 없습니다."));
  22. }
  23. // BoardMeta 조회 (캐시 우선)
  24. BoardMetaResponse? boardMeta = null;
  25. var cacheKey = CacheKeys.BoardMeta(item.ID);
  26. var cached = await cache.GetAsync<BoardMetaResponse>(cacheKey, ct);
  27. if (cached is not null)
  28. {
  29. boardMeta = cached;
  30. }
  31. else
  32. {
  33. var meta = await db.BoardMeta.FirstOrDefaultAsync(x => x.BoardID == item.ID, ct);
  34. if (meta is null)
  35. {
  36. meta = new Domain.Entities.Forum.Boards.BoardMeta {
  37. BoardID = item.ID
  38. };
  39. await db.BoardMeta.AddAsync(meta, ct);
  40. await db.SaveChangesAsync(ct);
  41. }
  42. boardMeta = new BoardMetaResponse(
  43. meta.ID,
  44. meta.BoardID,
  45. item.Code,
  46. item.Name,
  47. meta.List,
  48. meta.View,
  49. meta.Write,
  50. meta.Comment,
  51. meta.General,
  52. meta.Permission,
  53. meta.Notify,
  54. meta.NotifyTemplate,
  55. meta.Exp);
  56. await cache.SetAsync(cacheKey, boardMeta, ct);
  57. }
  58. return new Response(
  59. item.ID,
  60. item.BoardGroupID,
  61. item.Code,
  62. item.Name,
  63. item.IsSearch,
  64. item.IsActive,
  65. item.Posts,
  66. new BoardGroupDto(
  67. item.BoardGroup.ID,
  68. item.BoardGroup.Code,
  69. item.BoardGroup.Name
  70. ),
  71. [..item.BoardPrefix.Select(p => new BoardPrefixDto(
  72. p.ID,
  73. p.BoardID,
  74. p.Name,
  75. p.Color,
  76. p.Posts
  77. ))],
  78. [..item.BoardManager.Select(m => new BoardManagerDto(
  79. m.ID,
  80. m.BoardID,
  81. new BoardManagerUserDto(m.MemberID, m.Member.Email),
  82. m.CanEdit,
  83. m.CanDelete,
  84. m.UpdatedAt,
  85. m.CreatedAt
  86. ))],
  87. boardMeta
  88. );
  89. }
  90. }