Handler.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using System.Text.RegularExpressions;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Messaging;
  4. using SharedKernel.Results;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Admin.Channel.List.Create;
  7. public sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result<int>>
  8. {
  9. public async Task<Result<int>> Handle(Command request, CancellationToken ct)
  10. {
  11. var exists = await db.Channel.AnyAsync(c => c.SID == request.SID, ct);
  12. if (exists)
  13. {
  14. return Result.Failure<int>(Error.Conflict("Channel.DuplicateSID", "이미 등록된 채널 SID입니다."));
  15. }
  16. // 후원 코드 사전 검증: 형식 + 중복 (도메인 안전망 외 사용자 친화적 에러)
  17. string? normalizedDonationCode = null;
  18. if (!string.IsNullOrWhiteSpace(request.DonationCode))
  19. {
  20. var trimmed = request.DonationCode.Trim();
  21. if (!Regex.IsMatch(trimmed, "^[A-Za-z0-9]{4,7}$"))
  22. {
  23. return Result.Failure<int>(Error.Problem("DonationCode.InvalidFormat", "후원 코드는 4~7자 영문/숫자만 가능합니다."));
  24. }
  25. normalizedDonationCode = trimmed.ToUpperInvariant();
  26. var codeTaken = await db.Channel.AnyAsync(c => c.DonationCode == normalizedDonationCode, ct);
  27. if (codeTaken)
  28. {
  29. return Result.Failure<int>(Error.Conflict("DonationCode.Duplicate", "이미 사용 중인 후원 코드입니다."));
  30. }
  31. }
  32. var channel = Domain.Entities.Members.Channel.Create(
  33. request.MemberID,
  34. request.SID,
  35. request.Name,
  36. request.YouTubeUrl
  37. );
  38. channel.Update(
  39. request.Name,
  40. request.Handle,
  41. request.YouTubeUrl,
  42. request.PlatformFeeRate,
  43. request.StoreCommissionRate,
  44. request.IsVerified,
  45. request.IsActive
  46. );
  47. channel.SetDonationCodeByAdmin(normalizedDonationCode);
  48. await db.Channel.AddAsync(channel, ct);
  49. try
  50. {
  51. await db.SaveChangesAsync(ct);
  52. }
  53. catch (DbUpdateException)
  54. {
  55. return Result.Failure<int>(Error.Conflict("DonationCode.Duplicate", "이미 사용 중인 후원 코드입니다."));
  56. }
  57. return Result.Success(channel.ID);
  58. }
  59. }