Skip to content

feat: Outbox 수동 재처리와 감사로그 구현 - #102

Open
hywznn wants to merge 6 commits into
mainfrom
feat/54-outbox-manual-retry
Open

feat: Outbox 수동 재처리와 감사로그 구현#102
hywznn wants to merge 6 commits into
mainfrom
feat/54-outbox-manual-retry

Conversation

@hywznn

@hywznn hywznn commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

왜 필요한가요?

반복 실패로 REVIEW_REQUIRED에 멈춘 Outbox 이벤트를 운영자가 DB를 직접 수정하지 않고 안전하게 재처리할 수 있도록 합니다.

Refs #54

무엇이 바뀌나요?

  • POST /api/v1/admin/outbox-events/{eventId}/retry를 추가했습니다.
  • ADMIN 역할만 호출할 수 있습니다.
  • expected_version, 10~300자의 사유, Idempotency-Key를 필수로 받습니다.
  • expected_version 누락·null 요청은 400으로 거부합니다.
  • REVIEW_REQUIRED이며 lease가 없는 이벤트만 PENDING으로 되돌립니다.
  • 수동 재처리 시 attempt_count를 0으로 초기화해 Handler가 실제로 다시 실행될 기회를 부여합니다.
  • 초기화 전 횟수는 outbox_manual_retry.previous_attempt_count에 변경 불가 이력으로 보존합니다.
  • 동일 요청의 중복 제출과 동시 재처리를 차단합니다.
  • actor·company·requestId·사유와 변경 전후 상태를 감사로그와 별도 재처리 이력에 남깁니다.
  • payload·개인정보·오류 원문은 응답과 감사로그에 노출하지 않습니다.
  • Flyway V26과 PostgreSQL RLS 준비 V27을 추가했습니다.

API 결과

정상 요청은 202 Accepted를 반환합니다. 필수값 누락은 400, 잘못된 상태·오래된 version·동시 요청은 409로 안전하게 거부됩니다.

검증

  • ./gradlew clean test 성공
  • PostgreSQL 17 Migration·Tenant·RLS 테스트 성공
  • 권한·상태·version·필수값·멱등성·동시 요청·감사로그 시나리오 검증
  • 최대 횟수 이벤트의 수동 재처리 후 실제 Handler 실행 검증

병합 순서

#55의 V24·V25 병합 후 이 PR의 V26·V27을 병합해야 하며, 이후 #85의 V28을 병합합니다.

hywznn added 3 commits August 6, 2026 18:56
REVIEW_REQUIRED 이벤트를 안전하게 PENDING으로 전환하는 도메인 규칙과 재처리 이력·중복 방지 테이블, PostgreSQL tenant 정책을 추가합니다.
사유·expected version·Idempotency-Key를 검증하고 사업장 잠금과 감사로그를 거쳐 Outbox worker에 재처리를 맡기는 운영 API를 구현합니다.
권한, tenant 격리, 상태·버전 충돌, 중복·동시 요청, OpenAPI, PostgreSQL migration과 RLS 정책을 검증하고 운영 절차를 문서화합니다.
@hywznn
hywznn requested review from chaeliki and krestar August 6, 2026 10:23
최대 재시도 횟수에 도달한 이벤트도 수동 복구 후 Handler가 실행되도록 시도 횟수를 초기화합니다.
초기화 전 횟수는 수동 재처리 이력에 보존하고 실제 Processor 호출까지 통합 테스트합니다.
krestar
krestar previously approved these changes Aug 6, 2026

@krestar krestar 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.

커멘트 하나 남긴 부분이 살짝 애매하긴 한데, 나머진 전부 잘 구현된 것 같아서 승인합니다

@JsonProperty("expected_version")
@Schema(description = "운영자가 확인한 현재 Outbox event version", example = "3")
@Min(value = 0, message = "expected_version은 0 이상이어야 합니다.")
long expectedVersion,

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.

expected_version이 primitive long이라 필드 누락/null 요청이 0으로 처리될 수 있습니다. Long + @NotNull로 필수성을 보장하는 것도 좋을 것 같습니다.

@NotNull(message = "expected_version은 필수입니다.")
@min(value = 0, message = "expected_version은 0 이상이어야 합니다.")
Long expectedVersion,

expected_version 누락과 null 요청이 0으로 처리되지 않도록 명시적인 필수 검증을 추가합니다.
# Conflicts:
#	src/main/java/com/fowoco/server/audit/domain/AuditTargetType.java
#	src/test/java/com/fowoco/server/PostgreSqlMigrationTests.java
#	src/test/java/com/fowoco/server/common/security/PostgreSqlRlsIsolationTest.java
@hywznn
hywznn marked this pull request as ready for review August 6, 2026 15:29
@hywznn
hywznn requested a review from krestar August 6, 2026 15:29
@hywznn

hywznn commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

CI 에러 무엇이 문제냐 .. infra작업하고 계신건가

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants