Skip to content

#167 feat: 결제 실패 시 예약 취소 outbox 패턴 구현 - #168

Merged
git-mesome merged 3 commits into
developfrom
#167-feat-payment-reservation-cancel-outbox
Feb 10, 2026
Merged

#167 feat: 결제 실패 시 예약 취소 outbox 패턴 구현#168
git-mesome merged 3 commits into
developfrom
#167-feat-payment-reservation-cancel-outbox

Conversation

@git-mesome

@git-mesome git-mesome commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

🛠️ 설명 (Description)

결제 실패 시 예약 서비스에 예약 취소 요청을 신뢰성 있게 전달하기 위해 Outbox 패턴을 구현했습니다.
이를 위해 PaymentFailedEvent를 도입하고, 결제 실패 시 해당 이벤트를 발행하여 PaymentEventHandler에서 예약 취소 Outbox를 트리거하도록 했습니다.
기존 티켓 발급 Outbox 패턴과 재사용성을 높이기 위해 Outbox 패턴의 공통 추상화를 도입하고, 기존 티켓 발급 Outbox 구현체도 이 추상화를 따르도록 리팩토링했습니다.

✅ 테스트 계획 (Test Plan)

  • 유닛 테스트:
    • PaymentTransactionService에서 결제 실패 (금액 불일치, PG 응답 실패) 시 PaymentFailedEvent가 발행되는지 확인하는 테스트.
    • PaymentEventHandlerPaymentFailedEvent를 수신하고 ReservationCancelOutboxService.cancelOrEnqueue를 올바르게 호출하는지 확인하는 테스트.
    • ReservationCancelOutboxService가 Outbox 엔트리를 PENDING으로 저장하고, 외부 호출 성공 시 SUCCESS로, 실패 시 PENDING 상태를 유지하며 lastError를 업데이트하는지 확인하는 테스트.
    • ReservationCancelRetryUseCasePENDING 상태의 Outbox 엔트리를 조회하여 재시도하고, 성공/실패 시 상태를 업데이트하는 테스트.
    • AbstractOutboxRetryUseCaseOutboxRepository 공통 인터페이스를 사용한 티켓 발급 Outbox의 리팩토링 후에도 기존 로직이 정상 동작하는지 확인하는 테스트.
  • 통합 테스트:
    • Mocking된 결제 게이트웨이를 사용하여 결제 실패 시나리오를 재현하고, 예약 취소 Outbox 엔트리가 생성되며 재시도 로직을 통해 예약 취소 클라이언트가 호출되는지 확인하는 테스트 (Testcontainers 사용).
    • ReservationCancelClient (예약 서비스 모의 클라이언트)를 통해 실제 예약 취소 API 호출 흐름을 검증하는 테스트.
  • 테스트 커버리지: 신규 및 변경된 클래스/메서드에 대한 충분한 테스트 커버리지를 확보합니다.

📝 변경 사항 요약 (Summary)

  • Payment 도메인:
    • PaymentTransactionServiceapplyConfirmResult 메서드에서 결제 실패 시 PaymentFailedEvent를 발행하도록 변경.
  • 이벤트 핸들러:
    • payment/application/payment/handler/PaymentEventHandler.javaPaymentFailedEvent를 구독하는 onPaymentFailed 메서드 추가.
    • onPaymentFailed 메서드에서 ReservationCancelOutboxService.cancelOrEnqueue를 호출하여 예약 취소 Outbox 흐름 시작.
    • 기존 onPaymentApproved 메서드에서 ticketIssueOutboxService 변수명 변경.
  • 공통 Outbox 추상화 도입:
    • payment/application/payment/outbox/ 패키지에 AbstractOutboxRetryUseCase, OutboxRepository, OutboxTarget 인터페이스를 추가하여 Outbox 패턴의 재시도 로직 및 저장소 로직을 일반화.
  • 예약 취소 Outbox 패턴 구현:
    • payment/application/payment/outbox/cancel/ 패키지에 다음 클래스 추가:
      • ReservationCancelOutboxService: 예약 취소 요청을 처리하고, 외부 시스템 호출 실패 시 Outbox에 기록하여 재시도하도록 관리.
      • ReservationCancelOutboxRepository: 예약 취소 Outbox 데이터를 영속화하기 위한 인터페이스.
      • ReservationCancelOutboxTarget: 예약 취소 Outbox의 대상 데이터를 정의하는 레코드.
      • ReservationCancelRetryUseCase: AbstractOutboxRetryUseCase를 상속받아 예약 취소 재시도 로직을 구현.
      • ReservationCancelExternalCallFailedException, ReservationCancelTemporarilyUnavailableException: 예약 취소 관련 예외 정의.
    • payment/application/payment/port/output/ReservationCancelClient.java 인터페이스 추가: 외부 예약 서비스와 연동하기 위한 포트 정의.
  • 티켓 발급 Outbox 리팩토링:
    • 기존 wisoft.nextframe.payment.application.ticketissue 패키지를 wisoft.nextframe.payment.application/payment/outbox/ticketissue로 변경.
    • 기존 티켓 발급 Outbox 관련 클래스들(TicketIssueOutboxService, TicketIssueRetryUseCase, TicketIssueOutboxRepository, TicketIssueOutboxTarget, 관련 예외 클래스)을 새로운 공통 Outbox 추상화를 사용하도록 변경 및 리팩토링.
    • TicketIssueResult 클래스 패키지 이동.
    • TicketingClient 인터페이스에서 TicketIssueResult 임포트 경로 업데이트.
  • 빌드 및 설정:
    • Gradle Wrapper 버전을 8.12에서 8.9로 다운그레이드.
    • .claude 디렉토리와 CLAUDE.md, settings.local.json 파일 추가: Claude Code AI 툴을 위한 프로젝트 가이드 및 설정 파일.

🔗 관련 이슈 (Related Issues)

☑️ 체크리스트 (Checklist)

  • 코드가 프로젝트 코딩 컨벤션을 따릅니다.
  • 테스트 코드가 작성되었고, 통과했습니다.
  • 변경 사항에 대한 문서화가 완료되었습니다.
  • 필요한 경우, 다른 팀원에게 리뷰를 요청했습니다.

👀 리뷰어를 위한 참고 사항 (Notes for Reviewers)

  • 결제 실패 시 예약 취소를 보장하기 위한 Outbox 패턴 구현을 중점적으로 검토해주시면 감사하겠습니다.
  • 새로운 AbstractOutboxRetryUseCase를 도입하여 Outbox 패턴의 재시도 로직을 일반화하고, 기존 티켓 발급 Outbox에도 적용했습니다. 이 추상화의 적절성과 재사용성에 대한 의견을 주시면 좋겠습니다.
  • PaymentTransactionService에서 도메인 이벤트를 발행하는 시점이 트랜잭션 커밋 이전이 아닌, 상태 변경 및 저장 AFTER_COMMIT 리스너에서 처리되도록 한 점에 유의해주세요.
  • Gradle Wrapper 버전 다운그레이드가 발생했습니다. 호환성 및 안정성 측면에서 특이사항이 없는지 확인 부탁드립니다.
  • .claude 디렉토리는 Claude AI 툴을 위한 가이드 및 설정 파일입니다. 코드 로직과는 무관합니다.

➕ 추가 정보 (Additional Information)

N/A

Copilot AI review requested due to automatic review settings February 6, 2026 10:12
@git-mesome git-mesome self-assigned this Feb 6, 2026
@git-mesome
git-mesome requested a review from Jinpyo-An February 6, 2026 10:13
@git-mesome git-mesome added status: review 코드 리뷰 중 type: feature 새로운 기능 요청 또는 구현 labels Feb 6, 2026
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @git-mesome, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 결제 실패 시 예약 취소 처리를 위한 강력한 Outbox 패턴을 도입하여 시스템의 견고성과 외부 시스템과의 이벤트 일관성을 크게 향상시킵니다. 또한, 기존 티켓 발급 Outbox 로직을 새로운 공통 추상화에 맞춰 리팩토링함으로써 Outbox 패턴 구현의 재사용성과 확장성을 확보했습니다. 전반적으로 비동기 처리의 안정성을 높이고 코드 구조를 개선하는 데 중점을 두었습니다.

Highlights

  • 결제 실패 시 예약 취소 Outbox 패턴 구현: 결제 실패 시 예약 취소를 비동기적으로 처리하기 위한 Outbox 패턴이 도입되었습니다. 이는 PaymentFailedEvent 발행 시 ReservationCancelOutboxService를 통해 예약 취소 요청을 Outbox에 저장하고, ReservationCancelScheduler가 이를 주기적으로 재시도하여 외부 시스템과의 일관성을 보장합니다.
  • 공통 Outbox 추상화 및 기존 티켓 발급 Outbox 리팩토링: Outbox 패턴의 재사용성을 높이기 위해 AbstractOutboxRetryUseCaseOutboxRepository 인터페이스가 도입되었습니다. 기존의 티켓 발급 Outbox 로직은 이 새로운 추상화를 따르도록 리팩토링되어, 코드 구조가 개선되고 유지보수성이 향상되었습니다.
  • 새로운 도메인 이벤트 및 외부 포트 추가: 결제 실패를 나타내는 PaymentFailedEvent 도메인 이벤트가 추가되었으며, 외부 예약 시스템에 예약 취소 요청을 보내기 위한 ReservationCancelClient 포트가 정의되었습니다. 이는 도메인 주도 설계 원칙을 강화합니다.
  • Gradle 버전 다운그레이드 및 Claude AI 설정 파일 추가: Gradle 버전이 8.12에서 8.9로 다운그레이드되었으며, Claude AI 코드 어시스턴트가 프로젝트 구조와 빌드 명령어를 이해하는 데 도움을 주는 CLAUDE.mdsettings.local.json 파일이 추가되었습니다.
  • 예약 취소 Outbox 관련 테스트 추가: 새롭게 구현된 예약 취소 Outbox 기능의 신뢰성을 보장하기 위해 ReservationCancelOutboxRepositoryImplTestReservationCancelSchedulerTest가 추가되었습니다.
Changelog
  • gradle/wrapper/gradle-wrapper.properties
    • Gradle 버전이 8.12에서 8.9로 다운그레이드되었습니다.
  • gradlew
    • 스크립트 내 printf 명령의 줄바꿈 문자가 수정되었습니다.
  • payment/.claude/CLAUDE.md
    • Claude AI 코드 어시스턴트를 위한 프로젝트 빌드 및 아키텍처 개요 문서가 추가되었습니다.
  • payment/.claude/settings.local.json
    • Claude AI 코드 어시스턴트의 권한 설정을 위한 파일이 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/PaymentTransactionService.java
    • 결제 금액 불일치 또는 결제 승인 실패 시 PaymentFailedEvent를 발행하는 로직이 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/handler/PaymentEventHandler.java
    • PaymentFailedEvent를 처리하여 ReservationCancelOutboxService를 호출하는 핸들러가 추가되었습니다.
    • TicketIssueOutboxService의 의존성 이름이 outboxService에서 ticketIssueOutboxService로 변경되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/AbstractOutboxRetryUseCase.java
    • Outbox 재시도 로직의 공통 추상 클래스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/OutboxRepository.java
    • Outbox 저장소의 공통 인터페이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/OutboxTarget.java
    • Outbox 재시도 대상의 공통 인터페이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelExternalCallFailedException.java
    • 예약 취소 외부 호출 실패 시 발생하는 예외 클래스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelOutboxRepository.java
    • 예약 취소 Outbox 저장소 인터페이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelOutboxService.java
    • 예약 취소 Outbox에 요청을 저장하고 외부 호출을 처리하는 서비스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelOutboxTarget.java
    • 예약 취소 Outbox의 대상 레코드 클래스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelRetryUseCase.java
    • 예약 취소 Outbox 재시도 로직을 구현하는 유스케이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/ReservationCancelTemporarilyUnavailableException.java
    • 예약 취소 일시적 불가 시 발생하는 예외 클래스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueExternalCallFailedException.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/exception/TicketIssueExternalCallFailedException.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueInvalidResponseException.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/exception/TicketIssueInvalidResponseException.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueOutboxRepository.java
    • 티켓 발급 Outbox 저장소 인터페이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueOutboxService.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/TicketIssueOutboxService.java에서 리팩토링되어 이동되었으며, TicketIssueOutboxRepositoryTicketIssueResult import 경로가 업데이트되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueOutboxTarget.java
    • 티켓 발급 Outbox의 대상 레코드 클래스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueResult.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/dto/TicketIssueResult.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueRetryUseCase.java
    • 티켓 발급 Outbox 재시도 로직을 구현하는 유스케이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/TicketIssueTemporarilyUnavailableException.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/exception/TicketIssueTemporarilyUnavailableException.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/port/output/ReservationCancelClient.java
    • 예약 취소 외부 호출을 위한 포트 인터페이스가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/payment/port/output/TicketingClient.java
    • TicketIssueResult의 import 경로가 새로운 outbox 패키지로 업데이트되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/TicketIssueRetryUseCase.java
    • 이전 티켓 발급 재시도 유스케이스 파일이 삭제되었습니다. (새로운 공통 추상화로 대체)
  • payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/dto/TicketIssueOutboxTarget.java
    • 이전 티켓 발급 Outbox 대상 DTO 파일이 삭제되었습니다. (새로운 공통 추상화로 대체)
  • payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/exception/TicketIssueTemporarilyUnavailableException.java
    • 이전 티켓 발급 일시적 불가 예외 파일이 삭제되었습니다. (새로운 outbox 패키지로 이동)
  • payment/src/main/java/wisoft/nextframe/payment/application/ticketissue/port/output/TicketIssueOutboxRepository.java
    • 이전 티켓 발급 Outbox 저장소 인터페이스 파일이 삭제되었습니다. (새로운 공통 추상화로 대체)
  • payment/src/main/java/wisoft/nextframe/payment/domain/payment/Payment.java
    • PaymentFailedEvent import가 추가되었으며, fail() 메서드 호출 시 PaymentFailedEvent를 도메인 이벤트 목록에 추가하도록 수정되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/domain/payment/event/PaymentFailedEvent.java
    • 결제 실패를 나타내는 도메인 이벤트 레코드가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/JpaReservationCancelOutboxRepository.java
    • 예약 취소 Outbox 엔티티를 위한 JPA 리포지토리가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/ReservationCancelAdaptor.java
    • ReservationCancelClient 포트의 구현체로, 외부 예약 시스템에 예약 취소 요청을 보내는 어댑터가 추가되었습니다. Circuit Breaker 패턴이 적용되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/ReservationCancelOutboxEntity.java
    • 예약 취소 Outbox 데이터를 저장하는 JPA 엔티티가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/ReservationCancelOutboxRepositoryImpl.java
    • ReservationCancelOutboxRepository 인터페이스의 구현체로, 예약 취소 Outbox 데이터의 영속성 로직을 담당합니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/JpaTicketIssueOutboxRepository.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/JpaTicketIssueOutboxRepository.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/TicketIssueOutboxEntity.java
    • 티켓 발급 Outbox 데이터를 저장하는 JPA 엔티티가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/TicketIssueOutboxRepositoryImpl.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/TicketIssueOutboxRepositoryImpl.java에서 리팩토링되어 이동되었으며, findIssueTargets 메서드가 findTargets로 변경되고 공통 OutboxTarget 인터페이스를 사용하도록 수정되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/TicketingAdaptor.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/TicketingAdaptor.java에서 리팩토링되어 이동되었으며, 관련 예외 및 DTO import 경로가 업데이트되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/dto/TicketIssueRequest.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/dto/TicketIssueRequest.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/dto/TicketIssueResponse.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/dto/TicketIssueResponse.java에서 리팩토링되어 이동되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/schedule/ReservationCancelScheduler.java
    • 예약 취소 Outbox 재시도 로직을 주기적으로 실행하는 스케줄러가 추가되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/payment/schedule/TicketIssueScheduler.java
    • 파일이 payment/src/main/java/wisoft/nextframe/payment/infra/schedule/TicketIssueScheduler.java에서 리팩토링되어 이동되었으며, TicketIssueRetryUseCase import 경로가 업데이트되었습니다.
  • payment/src/main/java/wisoft/nextframe/payment/infra/ticketissue/adapter/TicketIssueOutboxEntity.java
    • 이전 티켓 발급 Outbox 엔티티 파일이 삭제되었습니다. (새로운 outbox 패키지로 이동)
  • payment/src/main/java/wisoft/nextframe/payment/presentation/ticketissue/TicketIssueRetryAdminController.java
    • TicketIssueRetryUseCase import 경로가 업데이트되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/application/payment/PaymentEventHandlerTest.java
    • TicketIssueOutboxService import 경로가 업데이트되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/application/payment/PaymentServiceIntegrationTest.java
    • JpaTicketIssueOutboxRepository import 경로가 업데이트되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/ReservationCancelOutboxRepositoryImplTest.java
    • 예약 취소 Outbox 저장소 구현체에 대한 단위 테스트가 추가되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/infra/payment/outbox/ticketissue/TicketIssueOutboxRepositoryImplTest.java
    • 파일이 payment/src/test/java/wisoft/nextframe/payment/infra/ticketissue/adaptor/TicketIssueOutboxRepositoryImplTest.java에서 리팩토링되어 이동되었으며, Environment mock이 추가되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/infra/payment/schedule/ReservationCancelSchedulerTest.java
    • 예약 취소 스케줄러에 대한 단위 테스트가 추가되었습니다.
  • payment/src/test/java/wisoft/nextframe/payment/infra/payment/schedule/TicketIssueSchedulerTest.java
    • 파일이 payment/src/test/java/wisoft/nextframe/payment/infra/schedule/TicketIssueSchedulerTest.java에서 리팩토링되어 이동되었으며, TicketIssueRetryUseCase import 경로가 업데이트되었습니다.
  • payment/src/test/resources/schema-test.sql
    • reservation_cancel_outbox 테이블 생성 스키마가 추가되었습니다.
Activity
  • 결제 실패 시 예약 취소 기능을 Outbox 패턴으로 구현하는 작업이 시작되었습니다.
  • 기존 티켓 발급 Outbox 로직을 재사용 가능한 공통 Outbox 추상화로 리팩토링하는 작업이 진행되었습니다.
  • 새로운 PaymentFailedEvent 도메인 이벤트와 ReservationCancelClient 포트가 정의되었습니다.
  • 예약 취소 Outbox 관련 단위 테스트 및 스케줄러 테스트가 추가되었습니다.
  • Gradle 버전 다운그레이드 및 Claude AI 설정을 위한 파일이 추가되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

결제 실패 시 예약 취소를 위한 아웃박스 패턴을 성공적으로 구현한 좋은 PR입니다. 공통 아웃박스 로직을 AbstractOutboxRetryUseCaseOutboxRepository로 추상화하여 코드 재사용성과 유지보수성을 높인 점이 인상적입니다. 관련 테스트 코드 추가와 패키지 구조 리팩토링도 잘 이루어졌습니다.

코드 품질을 더욱 향상시키기 위해 몇 가지 제안 사항을 남깁니다.

  • 변경된 아키텍처를 반영하도록 관련 문서를 업데이트하는 것을 권장합니다.
  • PaymentTransactionService에 존재하는 일부 중복 코드를 리팩토링하면 좋을 것 같습니다.
  • 데이터베이스 스키마의 주석에 있는 사소한 불일치를 수정하면 혼동을 줄일 수 있습니다.

전반적으로 결제 서비스의 안정성을 높이는 훌륭한 기여라고 생각합니다.

Comment thread payment/.claude/CLAUDE.md
Comment thread payment/src/test/resources/schema-test.sql

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a reservation cancellation outbox pattern to ensure that when payment fails, the associated reservation is automatically canceled in a reliable, server-driven manner. The implementation includes refactoring the existing ticket issue outbox to use shared abstractions, adding a new PaymentFailedEvent, and creating the complete infrastructure for reservation cancellation via outbox pattern with retry logic.

Changes:

  • Added PaymentFailedEvent domain event and event publishing in Payment.fail() method
  • Created abstract outbox infrastructure (AbstractOutboxRetryUseCase, OutboxRepository, OutboxTarget) to reduce duplication
  • Implemented reservation cancel outbox pattern with ReservationCancelOutboxService, ReservationCancelRetryUseCase, ReservationCancelAdaptor, and supporting repository/entity classes
  • Refactored ticket issue outbox to use new abstractions (moved from application/ticketissue to application/payment/outbox/ticketissue)
  • Added comprehensive tests for the new reservation cancel functionality
  • Added database schema for reservation_cancel_outbox table

Reviewed changes

Copilot reviewed 52 out of 53 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
payment/src/main/java/wisoft/nextframe/payment/domain/payment/Payment.java Added PaymentFailedEvent publishing in fail() method
payment/src/main/java/wisoft/nextframe/payment/domain/payment/event/PaymentFailedEvent.java New domain event for payment failure
payment/src/main/java/wisoft/nextframe/payment/application/payment/PaymentTransactionService.java Added event publishing for failed payment scenarios
payment/src/main/java/wisoft/nextframe/payment/application/payment/handler/PaymentEventHandler.java Added handler for PaymentFailedEvent to trigger reservation cancellation
payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/*.java New abstract base classes for outbox pattern
payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/cancel/*.java Complete implementation of reservation cancel outbox
payment/src/main/java/wisoft/nextframe/payment/application/payment/outbox/ticketissue/*.java Refactored ticket issue outbox to use new abstractions
payment/src/main/java/wisoft/nextframe/payment/application/payment/port/output/ReservationCancelClient.java New port interface for reservation cancellation
payment/src/main/java/wisoft/nextframe/payment/infra/payment/outbox/cancel/*.java Infrastructure implementations for reservation cancel outbox
payment/src/main/java/wisoft/nextframe/payment/infra/payment/schedule/*.java Schedulers for outbox retry processing
payment/src/test/resources/schema-test.sql Added reservation_cancel_outbox table definition
payment/src/test/java/wisoft/nextframe/payment/**/*.java Test updates for package restructuring and new functionality
gradlew, gradle/wrapper/* Gradle wrapper downgrade (unrelated to feature)
payment/.claude/* Claude AI configuration files (unrelated to feature)
Comments suppressed due to low confidence (1)

payment/src/test/java/wisoft/nextframe/payment/application/payment/PaymentEventHandlerTest.java:42

  • The PaymentEventHandlerTest only tests the PaymentApprovedEvent handler, but doesn't include tests for the new PaymentFailedEvent handler (onPaymentFailed method). Add a test case to verify that when a PaymentFailedEvent is received, the ReservationCancelOutboxService.cancelOrEnqueue method is called with the correct parameters.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread payment/src/test/resources/schema-test.sql
Comment thread gradle/wrapper/gradle-wrapper.properties
Comment thread gradlew
Comment thread payment/.claude/settings.local.json
Comment thread payment/.claude/CLAUDE.md Outdated
  - 예약 취소(ReservationCancel) outbox 기능 추가
  - ticketissue outbox를 application/payment/outbox/ 하위로 이동
  - 공통 outbox 추상화 (AbstractOutboxRetryUseCase, OutboxRepository)
  - PaymentFailedEvent 도메인 이벤트 추가
  - ReservationCancelClient 포트 추가

#167 test: 예약 취소 outbox 관련 테스트 추가
  - ReservationCancelOutboxRepositoryImplTest 추가
  - ReservationCancelSchedulerTest 추가
  - 테스트 패키지 구조 main과 동일하게 정리
…t NOT NULL 위반 수정

  - PaymentTransactionService의 실패 처리 로직을 handlePaymentFailure()로 추출하고, 공통 저장/이벤트 발행 로직을 saveAndPublishEvents()로 분리
  - TicketIssue/ReservationCancel outbox의 failAndBackoff()에서 FAILED 상태 전환 시 nextRetryAt를 null로 설정하던 NOT NULL 제약 조건 위반 수정
  - CLAUDE.md를 현재 outbox 추상화 구조에 맞게 갱신
@git-mesome
git-mesome force-pushed the #167-feat-payment-reservation-cancel-outbox branch from b009fd0 to a73570f Compare February 10, 2026 05:38
@git-mesome
git-mesome merged commit 9f0ed75 into develop Feb 10, 2026
5 checks passed
@git-mesome
git-mesome deleted the #167-feat-payment-reservation-cancel-outbox branch February 10, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: review 코드 리뷰 중 type: feature 새로운 기능 요청 또는 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] payment: 결제 실패 시 예약 취소를 서버 주도로 보장하기 위한 ReservationCancel Outbox 추가

3 participants