이벤트 스토밍 문서 작성 가이드
Template
도메인 이벤트 작성
네이밍 규칙:
- 과거형 사용:
~됨,~완료됨,~생성됨 - 영문:
{Entity}{Action}ed형태 (예:OrderCreated,CallCompleted)
작성 팁:
- 성공 케이스뿐 아니라 실패/거부 케이스 이벤트도 포함
- 예:
CallCompleted,CallCompletionRejected,CallCompletionFailed - 비즈니스적으로 의미 있는 이벤트만 도출
- 기술적 이벤트(예:
DataSaved)는 제외
정책 작성
작성 원칙:
- 후속 액션이 있는 경우만 기록
- When은 도메인 이벤트(과거형), Then은 후속 이벤트/액션
조건 표현:
- When 컬럼에 괄호로 조건 표시
- 예:
OutboundCallCompleted (금액 100만원 초과)
여러 결과 표현:
- Then 컬럼에 쉼표로 나열
- 예:
EscalationCreated 발생, NotificationSent 발생
좋은 예:
| When | Then |
| --- | --- |
| OutboundCallCompleted | CallBannerUpdated 발생 |
| OutboundCallCompleted (금액 100만원 초과) | ApprovalRequested 발생 |
| PaymentCompleted | OrderConfirmed 발생, ReceiptSent 발생 |
나쁜 예:
| When | Then |
| --- | --- |
| CallPlanCreated | - | ❌ 후속 액션 없으면 기록 안 함
| CompleteCall | ... | ❌ When에 Command 사용 (Event여야 함)
액터와 명령 작성
Command 네이밍:
- 동사 원형 사용 (예:
CompleteCall,CreateMemo) - 명사형 ❌ (CallCompletion, MemoCreation)
Actor 표현:
- 역할별로 구체적으로 작성
- 예:
Operator,Manager,Admin,System
작성 예시:
| Command | Actor | Event |
| --- | --- | --- |
| CreateCallPlan | Operator | CallPlanCreated |
| ApproveCall | Manager | CallApproved |
| CompleteCall | Operator | CallCompleted |
| SendNotification | System | NotificationSent |
Context와 Aggregate 도출 방법
도출 시점: 이벤트 스토밍에서 이벤트, 정책, 커맨드를 도출한 후, Aggregate 매핑 전에 수행
Bounded Context 도출
식별 기준:
-
이벤트 클러스터링
- 관련 이벤트들이 모여있는 영역
- 예: 콜 관련 이벤트들 (CallCreated, CallCompleted, CallCancelled)
-
유비쿼터스 언어 경계
- 같은 용어가 다른 의미로 쓰이는 경계
- 예: "User"가 Support Context에서는 "고객", User Context에서는 "시스템 사용자"
-
업무 영역
- 요구사항의 기능 그룹
- 예: 콜 관리, 사용자 관리, 알림 관리
-
데이터 소유권
- 누가 데이터를 생성/관리하는가
- 예: Support Context가 콜 데이터 소유
-
팀/조직 구조
- 실제 담당 조직
- 예: 고객지원팀이 Support Context 담당
도출 예시:
이벤트 분석 →
- CallCreated, CallCompleted, CallCancelled, MemoAdded
- UserRegistered, UserActivated
- NotificationSent
클러스터링 →
- Support Context: 콜 관련 이벤트들
- User Context: 사용자 관련 이벤트들
- Notification Context: 알림 관련 이벤트들
Aggregate 도출
식별 기준:
-
트랜잭션 경계
- 함께 커밋되어야 하는 것들
- 예: 콜과 그 콜의 메모들은 함께 관리
-
불변식 공유
- 같은 불변식을 지켜야 하는 것들
- 예: "콜은 역순으로만 삭제"를 지켜야 하는 콜과 메모
-
생명주기 동일
- 함께 생성/삭제되는 것들
- 예: 콜이 삭제되면 메모도 함께 삭제
-
Command 처리 단위
- 하나의 Command가 변경하는 범위
- 예: CompleteCall은 CallPlan만 변경
도출 예시:
Command 분석 →
- CreateCall, CompleteCall, CancelCall → 콜 생명주기
- CreateMemo, UpdateMemo, DeleteMemo → 메모 생명주기
트랜잭션 경계 분석 →
- CompleteCall: 콜 상태만 변경 (메모는 별개)
- CreateMemo: 메모만 추가 (콜 상태 변경 없음)
Aggregate 도출 →
- AppUserOutboundCallPlan: 콜 관련 Command 처리
- CallMemo: 메모 관련 Command 처리 (분리)
도출 시 주의사항:
- Aggregate는 작게 유지 (Small Aggregate 원칙)
- 트랜잭션 경계가 불필요하게 크면 성능 저하
- ID로만 다른 Aggregate 참조 (직접 참조 X)
Aggregate 매핑
목적:
- 이벤트, 정책, 커맨드를 분석하여 Aggregate 후보 도출
- 트랜잭션 경계 결정
작성 구조:
## 4.1 [Aggregate명]
**트랜잭션 경계:**
[간단한 한 줄 설명]
**담당 Command:**
- [Command 목록]
**발행 Event:**
- [Event 목록]
**적용된 정책:**
- [When → Then 목록]
트랜잭션 경계 설명 작성 팁:
- 간단하게 한 줄로 요약
- "왜 이것들을 하나로 묶었는가" 설명
- 좋은 예: "콜의 생명주기 전체를 원자적으로 관리"
- 좋은 예: "주문과 결제 정보를 일관성 있게 처리"
- 나쁜 예: "콜 관련 기능" (너무 모호)
타임라인 / 프로세스 흐름
작성 시점:
- 복잡한 워크플로우가 있는 경우에만 작성
- 예: 다단계 승인 프로세스, 배치 처리 파이프라인, 상태 전이가 복잡한 경우
다이어그램 형식:
- Mermaid 다이어그램 사용
- 간단하고 명확하게 유지
작성 예시:
작성하지 않아도 되는 경우:
- 단순한 CRUD 작업
- 이벤트 순서가 명확한 경우
- 정책 섹션으로 충분히 표현 가능한 경우