using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Feed.GetPost; public sealed class Handler(IAppDbContext db) : IQueryHandler> { public async Task> Handle(Query request, CancellationToken ct) { var post = await db.FeedPost.AsNoTracking() .Where(p => p.ID == request.PostID && !p.IsDeleted) .Select(p => new { p.ID, p.MemberID, AuthorSID = p.Member.SID, AuthorName = p.Member.Name, AuthorThumb = p.Member.Thumb, IsCreator = p.Member.IsCreator, ChannelSID = p.Member.Channel != null ? p.Member.Channel.SID : null, p.Content, Images = p.FeedPostImage.OrderBy(i => i.ID).Select(i => new { i.Url, i.Width, i.Height }).ToList(), Medias = p.FeedPostMedia.OrderBy(m => m.ID).Select(m => m.Url).ToList(), p.Likes, p.Comments, p.Bookmarks, p.Views, Tags = p.FeedPostTag.Select(pt => new { pt.FeedTag.Name, pt.FeedTag.Slug }).ToList(), p.CreatedAt }) .FirstOrDefaultAsync(ct); if (post is null) { return Result.Failure(Error.NotFound("Feed.PostNotFound", "게시글을 찾을 수 없습니다.")); } var hasLike = false; var hasBookmark = false; if (request.ViewerMemberID is int viewerID && viewerID > 0) { hasLike = await db.FeedLike.AsNoTracking().AnyAsync(l => l.FeedPostID == post.ID && l.MemberID == viewerID, ct); hasBookmark = await db.FeedBookmark.AsNoTracking().AnyAsync(b => b.FeedPostID == post.ID && b.MemberID == viewerID, ct); } return new Response { PostID = post.ID, AuthorSID = post.AuthorSID, AuthorName = post.AuthorName, AuthorThumb = post.AuthorThumb, IsCreator = post.IsCreator, ChannelSID = post.ChannelSID, Content = post.Content, Images = [..post.Images.Select(i => new Response.ImageItem { Url = i.Url, Width = i.Width, Height = i.Height })], Medias = [..post.Medias], Likes = post.Likes, Comments = post.Comments, Bookmarks = post.Bookmarks, Views = post.Views, Tags = [..post.Tags.Select(t => new Response.TagRef { Name = t.Name, Slug = t.Slug })], CreatedAt = post.CreatedAt, HasLike = hasLike, HasBookmark = hasBookmark, IsOwner = request.ViewerMemberID is int vID && vID > 0 && post.MemberID == vID }; } }