Handler.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using SharedKernel.Results;
  4. using Domain.Entities.Donations;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.Crew.JoinByCode;
  7. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<Response>>
  8. {
  9. public async Task<Result<Response>> Handle(Command request, CancellationToken ct)
  10. {
  11. var crew = await db.Crew
  12. .FirstOrDefaultAsync(c => c.InviteCode == request.InviteCode && c.IsActive, ct);
  13. if (crew is null)
  14. {
  15. return Result.Failure<Response>(Error.NotFound("Crew.InvalidInviteCode", "유효하지 않은 초대 코드입니다."));
  16. }
  17. // 이미 등록된 크루원인지 확인
  18. var exists = await db.CrewMember
  19. .AnyAsync(m => m.CrewID == crew.ID && m.MemberID == request.MemberID, ct);
  20. if (exists)
  21. {
  22. return Result.Failure<Response>(Error.Conflict("Crew.MemberAlreadyExists", "이미 등록된 크루원입니다."));
  23. }
  24. var channel = await db.Channel.AsNoTracking()
  25. .FirstOrDefaultAsync(c => c.MemberID == request.MemberID, ct);
  26. var nextOrder = await db.CrewMember
  27. .Where(m => m.CrewID == crew.ID)
  28. .MaxAsync(m => (int?)m.SortOrder, ct) ?? 0;
  29. var member = CrewMember.Create(
  30. crew.ID,
  31. request.MemberID,
  32. request.Nickname,
  33. channel?.ID,
  34. sortOrder: nextOrder + 1
  35. );
  36. db.CrewMember.Add(member);
  37. await db.SaveChangesAsync(ct);
  38. return Result.Success(new Response(member.ID, crew.Name));
  39. }
  40. }