--- id: wiki-2026-0508-event-storming title: Event Storming category: 10_Wiki/Topics status: verified canonical_id: self aliases: [EventStorming, DDD discovery workshop] duplicate_of: none source_trust_level: A confidence_score: 0.92 verification_status: applied tags: [ddd, modeling, workshop, architecture, discovery] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: methodology framework: ddd --- # Event Storming ## 매 한 줄 > **"매 sticky-note 의 도메인 의 explosion"**. Alberto Brandolini 의 2013 invent, 매 domain experts + devs 의 한 방 (혹은 Miro/FigJam) 에 모여 매 orange sticky note (domain event) 의 timeline 의 plot. 매 2026 의 매 distributed workshop tool (Miro AI, FigJam AI) 의 매 LLM-assisted aggregation 의 standard. ## 매 핵심 ### 매 sticky note color convention - 🟧 **Orange** — Domain Event (past tense — "OrderPlaced", "PaymentReceived"). - 🟦 **Blue** — Command (intent — "PlaceOrder", "RefundPayment"). - 🟨 **Yellow** — Actor / Persona. - 🟪 **Purple** — Policy / Reactive logic ("when X then Y"). - 🟩 **Green** — Read Model / View. - 🟥 **Red / Pink** — Hotspot / Issue (매 unclear / disagreement). - ⬜ **White** — Aggregate (매 consistency boundary). - 🟫 **Brown** — External system. ### 매 3 levels 1. **Big Picture** — 매 entire business — 매 chaos exploration, 매 hours. 2. **Process Level** — 매 한 process flow — 매 commands / policies / read models. 3. **Design Level** — 매 aggregate / bounded context — 매 implementation 의 input. ### 매 step-by-step (Big Picture) 1. **Chaotic exploration** — 매 모두 orange events 의 plaster. 2. **Timeline** — 매 left → right 의 sort. 3. **Pivotal events** — 매 phase boundary 의 mark. 4. **Hotspot identification** — 매 red sticky 의 disagreement. 5. **Bounded context** — 매 swimlane 의 split. ### 매 응용 1. Greenfield DDD design — 매 aggregate / bounded context discovery. 2. Legacy understanding — 매 domain knowledge 의 surface. 3. Microservice decomposition — 매 service boundary 의 inform. ## 💻 패턴 ### Pattern 1: Miro-export → JSON event log ```typescript interface DomainEvent { id: string; name: string; // PascalCase past tense timestamp: number; // 매 column index aggregate?: string; triggeredBy?: string; // command id hotspots: string[]; } const events: DomainEvent[] = [ { id: "e1", name: "OrderPlaced", timestamp: 1, aggregate: "Order", triggeredBy: "c1", hotspots: [] }, { id: "e2", name: "PaymentReceived", timestamp: 2, aggregate: "Payment", triggeredBy: "c2", hotspots: ["partial-payment-policy"] }, ]; ``` ### Pattern 2: Event → TypeScript event type ```typescript // 매 sticky 의 code 의 transition export type OrderEvent = | { type: "OrderPlaced"; orderId: string; items: Item[]; placedAt: Date } | { type: "OrderPaid"; orderId: string; paymentId: string } | { type: "OrderShipped"; orderId: string; trackingNo: string } | { type: "OrderCancelled"; orderId: string; reason: string }; ``` ### Pattern 3: Policy as code ```typescript // Purple sticky: "When OrderPaid then schedule shipment" function onOrderPaid(e: Extract) { shipmentService.schedule({ orderId: e.orderId }); } eventBus.on("OrderPaid", onOrderPaid); ``` ### Pattern 4: Aggregate boundary check ```typescript // 매 white sticky 의 invariant class OrderAggregate { private events: OrderEvent[] = []; place(items: Item[]) { if (items.length === 0) throw new Error("empty order"); this.events.push({ type: "OrderPlaced", orderId: this.id, items, placedAt: new Date() }); } // 매 모든 mutation 의 매 event 의 emit. } ``` ### Pattern 5: Bounded context map (Mermaid) ```mermaid flowchart LR subgraph Sales Order Cart end subgraph Billing Payment Invoice end subgraph Logistics Shipment end Order -- "OrderPlaced" --> Payment Payment -- "OrderPaid" --> Shipment ``` ### Pattern 6: AI-assisted event extraction (2026) ```typescript // 매 transcript / Miro export → event suggestions const prompt = `From this user interview, extract domain events (PascalCase past tense), commands, and hotspots. Output JSON matching: { events:[], commands:[], hotspots:[] }. Interview: ${transcript}`; const result = await claude.messages.create({ model: "claude-opus-4-7", max_tokens: 4000, messages: [{ role: "user", content: prompt }], }); ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Greenfield complex domain | Big Picture → Process → Design | | Legacy reverse engineering | Big Picture only | | Microservice split | Process Level + bounded context | | Small CRUD app | Skip — overkill | | Distributed team | Miro / FigJam + AI summarizer | **기본값**: 매 complex domain 시 Big Picture (4 hours), 매 implementation 직전 Design Level. ## 🔗 Graph - 응용: [[Bounded Context]] · [[CQRS]] - Adjacent: [[Event Sourcing]] · [[User-Story-Mapping]] · [[C4 Model (Architecture Documentation)]] ## 🤖 LLM 활용 **언제**: 매 domain discovery, 매 microservice boundary 의 find, 매 onboarding 의 understanding. **언제 X**: 매 trivial CRUD, 매 well-known domain (e.g., todo app). ## ❌ 안티패턴 - **Tech-first sticky**: 매 "INSERT INTO orders" — 매 domain event 의 X. - **Present tense**: 매 "PlaceOrder" 의 event 의 X — 매 command. - **No business expert**: 매 dev-only — 매 EventStorming purpose 의 lost. - **Skip hotspot**: 매 red sticky 의 ignore — 매 가장 valuable disagreement. - **Premature aggregate**: 매 Big Picture 에서 white sticky 의 too early. ## 🧪 검증 / 중복 - Verified (Brandolini "Introducing EventStorming" book 2021, DDD Europe talks). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — sticky color + 3 levels + AI-assisted |