Skip to content

fix: outbox wakeup과 read model projection 순서 안정화 - #206

Merged
lunarbae628 merged 1 commit into
stagingfrom
fix/read-model-projection-ordering
Jun 6, 2026
Merged

fix: outbox wakeup과 read model projection 순서 안정화#206
lunarbae628 merged 1 commit into
stagingfrom
fix/read-model-projection-ordering

Conversation

@lunarbae628

@lunarbae628 lunarbae628 commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

🛰️ Issue Number

🪐 작업 내용

  • Domain Event Outbox wakeup을 특정 outboxId 직접 처리 명령이 아니라 relay 실행 신호로 변경했습니다.
  • Outbox OPEN 이벤트 조회 순서를 createdAt ASC, id ASC로 변경해 createdAt 동률에서도 결정적인 처리 순서를 보장했습니다.
  • DocListReadModel에 title, activity, thumbnail, deleted 필드별 projection marker를 추가했습니다.
  • marker가 없는 기존 Mongo Read Model 문서는 lastProjectedEventId를 fallback 기준선으로 사용해 기존 값이 오래된 이벤트로 덮이지 않도록 했습니다.
  • 삭제 이벤트는 terminal event로 보고, 삭제 marker가 없는 경우 다른 필드보다 오래된 삭제 이벤트라도 반영되도록 분리했습니다.
  • 삭제 이후 오래된 title, activity, thumbnail 이벤트가 문서를 되살리지 않도록 방어했습니다.
  • title/activity 이벤트의 updatedAt은 과거로 되돌아가지 않도록 max 정책을 적용했습니다.
  • Superpowers 기반 설계/구현 계획 문서를 추가했습니다.

📚 Reference

  • docs/superpowers/specs/2026-06-06-read-model-projection-ordering-design.md
  • docs/superpowers/plans/2026-06-06-read-model-projection-ordering-plan.md

🤖 AI 보조 작업 기록

  • 사용 범위:
    • Read Model projection 순서 안정화 설계 정리
    • 실패 테스트 작성
    • wakeup relay 정책 변경
    • 필드별 projection marker 구현
    • 코드 리뷰 및 리뷰 지적 반영
  • 채택한 제안과 이유:
    • wakeup은 특정 row 처리 명령이 아니라 relay 실행 신호로만 사용하도록 변경했습니다. wakeup을 correctness가 아니라 latency optimization으로 제한하기 위함입니다.
    • Domain Event Outbox 조회에 id ASC tie-breaker를 추가했습니다. createdAt 동률 시 DB 반환 순서에 의존하지 않기 위함입니다.
    • 삭제 이벤트는 terminal event로 분리했습니다. 오래된 변경 이벤트가 삭제된 문서를 되살리는 회귀를 막기 위함입니다.
    • 기존 Mongo 문서 호환을 위해 lastProjectedEventId fallback을 유지했습니다.
  • 기각한 제안과 이유:
    • Aggregate version 도입은 이번 범위에서 제외했습니다. 테이블 변경과 전체 이벤트 처리 정책 변경으로 범위가 커지기 때문입니다.
    • Kafka, CDC, consumer checkpoint 도입은 현재 consumer가 DocListProjector 하나라 과한 설계로 판단했습니다.
  • 실행한 검증:
    • bash ./gradlew test --tests io.ejangs.docsa.domain.doc.readmodel.app.DocListProjectorUnitTest --tests io.ejangs.docsa.domain.doc.readmodel.app.DocListProjectorIntegrationTest --tests io.ejangs.docsa.global.outbox.event.app.DomainEventOutboxRelayIntegrationTest
    • bash ./gradlew compileJava compileTestJava
    • git diff --check
  • 남은 리스크:
    • 이 변경은 aggregate별 완전한 순서 보장을 제공하지 않습니다. 여러 consumer 또는 다중 인스턴스 확장 시에는 aggregate version, consumer checkpoint, broker/CDC 도입 여부를 별도로 설계해야 합니다.

✅ Check List

  • 코드가 정상적으로 컴파일되나요?
  • 테스트 코드를 통과했나요?
  • merge할 브랜치의 위치를 확인했나요?
  • Label을 지정했나요?

@lunarbae628
lunarbae628 changed the base branch from dev to staging June 6, 2026 10:36
@lunarbae628

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@lunarbae628
lunarbae628 merged commit 97a1373 into staging Jun 6, 2026
2 checks passed
@lunarbae628 lunarbae628 self-assigned this Jun 8, 2026
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.

1 participant