| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- using Application.Abstractions.Data;
- using Application.Abstractions.Kyc;
- using Application.Abstractions.Messaging;
- using Domain.Entities.Developers.ValueObject;
- using Microsoft.EntityFrameworkCore;
- using SharedKernel.Results;
- namespace Application.Features.Api.Developers.Profile.CompleteKyc;
- internal sealed class Handler(IAppDbContext db, INiceAuthClient nice) : ICommandHandler<Command, Result>
- {
- public async Task<Result> Handle(Command request, CancellationToken ct)
- {
- var session = await db.NiceAuthSession
- .AsTracking()
- .Include(c => c.Developer)
- .FirstOrDefaultAsync(c => c.SessionToken == request.SessionToken, ct);
- if (session is null)
- {
- return Result.Failure(Error.NotFound(
- "Nice.SessionNotFound",
- "본인인증 세션을 찾을 수 없습니다."));
- }
- if (!session.CanProcessCallback())
- {
- // 이미 Completed/Failed/Expired 처리된 세션 — 결과는 그대로 두고 안내
- return session.Status == NiceAuthSessionStatus.Completed
- ? Result.Success()
- : Result.Failure(Error.Problem(
- "Nice.SessionFinalized",
- "본인인증 세션이 이미 종료되었습니다."));
- }
- if (session.IsExpired(DateTime.UtcNow))
- {
- session.MarkExpired();
- await db.SaveChangesAsync(ct);
- return Result.Failure(Error.Problem(
- "Nice.AuthFailedOrExpired",
- "본인인증 유효시간이 만료되었습니다. 다시 시도해 주세요."));
- }
- if (session.Developer is null)
- {
- session.MarkFailed("Developer 정보 누락");
- await db.SaveChangesAsync(ct);
- return Result.Failure(Error.NotFound(
- "Developer.NotFound",
- "개발자 정보를 찾을 수 없습니다."));
- }
- session.MarkWebTransactionReceived(request.WebTransactionID);
- var userResult = await nice.GetResultAsync(
- session.RequestNo,
- session.TransactionID,
- request.WebTransactionID,
- session.Ticket,
- session.Iterators,
- ct);
- if (userResult.IsFailure)
- {
- session.MarkFailed(userResult.Error.Code);
- await db.SaveChangesAsync(ct);
- return Result.Failure(userResult.Error);
- }
- var user = userResult.Value;
- // CI 가 다른 Developer 와 이미 묶여 있으면 중복가입 차단
- var ciTaken = await db.Developer
- .AsNoTracking()
- .AnyAsync(c => c.ID != session.DeveloperID && c.KycCi == user.Ci, ct);
- if (ciTaken)
- {
- session.MarkFailed("CI 중복");
- await db.SaveChangesAsync(ct);
- return Result.Failure(Error.Conflict(
- "Developer.KycCiTaken",
- "해당 명의로 이미 가입된 개발자 계정이 있습니다."));
- }
- session.Developer.MarkKycVerified(user.Ci, user.Di);
- session.MarkCompleted();
- await db.SaveChangesAsync(ct);
- return Result.Success();
- }
- }
|