using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Domain.Entities.Common.ValueObject; using Domain.Entities.Donations; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Studio.Settlement.SaveAccount; internal sealed class Handler(IAppDbContext db) : ICommandHandler> { private const int MaxAccounts = 8; public async Task> Handle(Command request, CancellationToken ct) { // 유효성 검사 if (string.IsNullOrWhiteSpace(request.BankCode)) { return Result.Failure(Error.Problem("BankCode", "은행을 선택해 주세요.")); } if (string.IsNullOrWhiteSpace(request.AccountNumber) || request.AccountNumber.Length is < 7 or > 16 || !request.AccountNumber.All(char.IsDigit)) { return Result.Failure(Error.Problem("AccountNumber", "올바른 계좌번호를 입력해 주세요. (7~16자리 숫자)")); } if (string.IsNullOrWhiteSpace(request.AccountHolder) || request.AccountHolder.Trim().Length < 2) { return Result.Failure(Error.Problem("AccountHolder", "예금주명을 입력해 주세요. (2자 이상)")); } var bank = SettlementBankCode.List.FirstOrDefault(b => b.Value == request.BankCode); if (bank is null) { return Result.Failure(Error.Problem("BankCode", "유효하지 않은 은행 코드입니다.")); } // 채널 확인 var channel = await db.Channel.AsNoTracking().FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct); if (channel is null) { return Result.Failure(Error.NotFound("Channel", "채널 정보를 찾을 수 없습니다.")); } // 수정 if (request.AccountID.HasValue) { var existing = await db.SettlementAccount.FirstOrDefaultAsync(a => a.ID == request.AccountID.Value && a.MemberID == request.MemberID, ct); if (existing is null) { return Result.Failure(Error.NotFound("Account", "계좌 정보를 찾을 수 없습니다.")); } existing.Update(request.BankCode, bank.Text, request.AccountNumber, request.AccountHolder.Trim()); await db.SaveChangesAsync(ct); return Result.Success(new Response("계좌가 수정되었습니다.")); } // 신규 등록: 개수 제한 var count = await db.SettlementAccount.CountAsync(a => a.MemberID == request.MemberID, ct); if (count >= MaxAccounts) { return Result.Failure(Error.Problem("Account", $"계좌는 최대 {MaxAccounts}개까지 등록할 수 있습니다.")); } var account = SettlementAccount.Create( channel.ID, request.MemberID, request.BankCode, bank.Text, request.AccountNumber, request.AccountHolder.Trim() ); db.SettlementAccount.Add(account); await db.SaveChangesAsync(ct); return Result.Success(new Response("계좌가 등록되었습니다.")); } }