using Application.Abstractions.Messaging; using Application.Abstractions.Data; using SharedKernel.Results; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Forum.BoardManager.Save; internal sealed class Handler(IAppDbContext db) : ICommandHandler { public async Task Handle(Command request, CancellationToken ct) { // 삭제 if (request.DeleteIDs is { Length: > 0 }) { var deleteTargets = await db.BoardManager .Where(c => c.BoardID == request.BoardID && request.DeleteIDs.Contains(c.ID)) .ToListAsync(ct); if (deleteTargets.Count > 0) { db.BoardManager.RemoveRange(deleteTargets); } } // 수정 if (request.Updates is { Count: > 0 }) { var updateIDs = request.Updates.Select(c => c.ID).ToList(); var updateTargets = await db.BoardManager .Where(c => c.BoardID == request.BoardID && updateIDs.Contains(c.ID)) .ToListAsync(ct); var updateByID = updateTargets.ToDictionary(c => c.ID); foreach (var row in request.Updates) { if (!updateByID.TryGetValue(row.ID, out var existing)) { return Result.Failure(Error.NotFound("BoardManager.NotFound", $"존재하지 않는 ID: {row.ID}")); } existing.CanEdit = row.CanEdit; existing.CanDelete = row.CanDelete; existing.UpdatedAt = DateTime.UtcNow; } } // 신규 추가 if (request.NewItem is not null) { // 회원 존재 확인 — FK 위반 사전 방지 var memberExists = await db.Member .AsNoTracking() .AnyAsync(c => c.ID == request.NewItem.MemberID, ct); if (!memberExists) { return Result.Failure(Error.NotFound("BoardManager.MemberNotFound", $"존재하지 않는 회원 ID 입니다: {request.NewItem.MemberID}")); } var isDuplicate = await db.BoardManager .AsNoTracking() .AnyAsync(c => c.BoardID == request.BoardID && c.MemberID == request.NewItem.MemberID, ct); if (isDuplicate) { return Result.Failure(Error.Conflict("BoardManager.Duplicate", "이미 등록된 매니저입니다.")); } db.BoardManager.Add(new Domain.Entities.Forum.Boards.BoardManager { BoardID = request.BoardID, MemberID = request.NewItem.MemberID, CanEdit = request.NewItem.CanEdit, CanDelete = request.NewItem.CanDelete }); } await db.SaveChangesAsync(ct); return Result.Success(); } }