Files
clean-architecture-backend-…/docs/messaging/cutover.md
T

35 lines
2.0 KiB
Markdown

# 기존 runtime → 신규 messaging platform cutover (MSG-015)
## 왜 기계적 매핑이 안 되는가
두 outbox 모델의 enum 이름이 겹치는데 의미가 반대다.
| 모델 | retryable | terminal |
|---|---|---|
| 기존 `OutboxEventStatus` | `FAILED` (`next_attempt_at` 보유) | `DEAD` |
| 신규 `OutboxStatus` | `AMBIGUOUS` | `FAILED`, `EXHAUSTED` |
이름으로 매핑하면 **확정 거절이 무한 재시도**가 되고 **불확정이 park**된다. 그래서 application은
자기 어휘(`OutboxPublishOutcome`)만 쓰고, 변환은 bridge adapter가 한다.
## 지금 반영된 것
- `OutboxPublishOutcome``CONFIRMED` / `AMBIGUOUS` / `REJECTED_BEFORE_SEND` /
`REJECTED_AFTER_BROKER`. application이 소유하는 canonical 결과 타입이며, "리턴 or throw"만 가능한
기존 어댑터를 위해 `OutboxMessagePublishPort.publishForOutcome`의 default가 `CONFIRMED`를 돌려준다.
- `APPLICATION_DOES_NOT_DEPEND_ON_THE_MESSAGING_PLATFORM` ArchUnit 규칙 — application-core가
`dev.caskeleton.messaging..`를 import하면 빌드가 깨진다.
- 반대 방향(신규 `PublishResult` → application outcome) 매핑 규칙을 테스트로 고정.
## 남은 것
- `messaging-platform-bridge` outbound leaf: validated application event → platform envelope,
`PublishResult``OutboxPublishOutcome`. registry에 leaf를 추가하는 변경이라 별도 커밋.
- golden contract 테스트: event/message ID, type, schema revision, partition/order/correlation/
causation/tenant/trace, payload digest, wire version이 bytes 단위로 보존되는지.
- 단일 publication authority: 기존 `OutboxPublicationAuthority` fence를 재사용해 writer/relay가
동시에 ACTIVE가 되지 않도록. **dual write/publish는 금지** — 한 business fact가 두 durable store와
두 relay로 나가는 상태가 cutover에서 가장 위험하다.
- 첫 cutover 범위는 **transport만** 교체(저장소는 기존 유지). storage migration은 shadow read →
authority switch → old backlog drain 순서로 별도 release.