Skip to main content

Command Palette

Search for a command to run...

이벤트 스토밍은 비싸다.

ROI가 맞지않았던 이벤트 스토밍 실패 사례를 기록합니다

Updated
8 min read
이벤트 스토밍은 비싸다.

서론

이번 글 에서는 최근 KOS(자사 제품 명, 이하 KOS) 제품의 일본 런칭을 위해 필수 기능이였던, Stripe 결제 플랫폼과의 연동 통합 시스템을 구축하면서 시도해봤던 이벤트 스토밍 준비와 실제 결과까지의 내용을 다뤄보려고한다. 필자가 이벤트 스토밍 세션을 준비하면서 고민했던것과 실제 좋지않은 결과가 나왔던 이유를 장시간 기억하고싶어 남겨본다.

우선 이벤트 스토밍 세션 자료 준비 과정은 이랬다.

DDD 관련 서적과 이벤트 스토밍 관련 여러 아티클들을 조합하여 보다 정석적인(FM) 프로세스를 만들어본 뒤, 현재의 도메인 모델 상황과 팀원들의 도메인 지식 수준을 반영하여 아래와 같은 프레임 워크를 만들었다.


이벤트 스토밍은 무엇인가?

💡
비지니스에서 실제로 “무슨 일이 일어나는지”를 중심으로 시스템을 이해하고 설계하는 협업 워크숍이다. 스트라이프를 KOS(자사 제품, 이하 KOS)에 통합하는 과정에서 기능이나 화면부터 논의하는 대신 언제, 어떤 일이, 어떤 순서로 일어나는가? 를 중심으로 전체 흐름을 함께 그려본다.

이벤트 스토밍은 매우 비싸다

  • 이벤트 스토밍은 절대 싸지 않다

  • 여러 직군(PO, PD. Engineer, Sales 등)이 같은 시간에 모여, 깊이 있는 사고와 결정이 필요한 논의를 한다

  • 즉, 이 시간에는 사람의 시간과 집중력 모두 비싸다

    • 자칫하면 단순히 포스트잇 끄적인 회의로 끝날 수 있다
  • 따라서 우리는 이 시간에 최대한 많은걸 논의하는것이 아닌, 가장 비싼 오해를 가장 빨리 발견하는것에 집중한다

우리는 왜 이벤트 스토밍을 하는가?

  1. 수납(Purchase) 도메인 모델과 Stripe 결제 연동에 대한 이해를 얼라인한다

    1. 각자가 알고있는 도메인 모델과 연동 흐름의 차이를 드러낸다

    2. 얼라인 된 이해를 바탕으로 BC 내 보편 언어(UL)을 정의한다

  2. 각자의 머릿속에 있는 이해가 서로 다르다는 사실을 빠르게 발견한다

  3. 말로 설명하기 어려운 흐름을 하나의 시각적 모델로 맞춰본다

  4. 얼라인된 결과물을 공식 산출물로 남긴다

    1. 이벤트 스토밍 결과를 수납(Purchase) 도메인 모델 문서에 반영한다

    2. 이후 설계, 모델링, 구현에 활용한다

진행 방식

도메인 이벤트 나열 (20분)

  • 목표

    • 스트라이프 결제 연동 과정에서 발생하는 모든 도메인 이벤트 최대한 많이 수집
  • 규칙

    • 이벤트는 반드시 과거형으로 작성한다

    • 이 단계에서는 이벤트의 순서, 맞고 틀림, 구현/기술 전혀 상관없음

    • 그냥 발산한다

    • 질보다 양이 더 중요한 단계임

이벤트 흐름 정렬(Align) (20분)

  • 목표

    • 이벤트들을 시간 흐름에 따라 정렬한다

    • 정상 케이스와 비정상 케이스의 윤곽을 파악한다

  • 규칙

    • 이 순서가 맞는지 정렬에 대한 의문을 계속 제기한다

    • 만약 병렬과 분기 가능성이 있다면 분리해서 표시한다

    • 만약 논쟁 길어지면 즉석에서 결론 내지말고, 핫스팟으로 표시해준다

액터/ 트리거 식별 (10분)

  • 목표

    • 각 이벤트가 누가 / 무엇에 의해 발생했는지 명확히 하기
  • 규칙

    • 액터는 명확히 구분

      • 사용자

      • 내부 시스템

      • 관리자 (eg. 수납 담당자)

      • 외부 시스템 (eg. Stripe)

    • 트리거는 반드시 3종으로만 정의한다

      • 시간 기반

      • 외부 입력(eg. Stripe webhook)

      • 내부 시스템 정책

    • 책임의 경계를 흐리게 두지않는다

커맨드 연결 (15분)

  • 목표

    • 이벤트를 발생시키는 의도(행위)를 드러낸다
  • 규칙

    • 커맨드는 현재형과 의도형으로 정의한다

    • 하나의 이벤트가

      • 여러 커맨드에서 발생하는가?

        • eg. 결제가 취소되었다

          • 커맨드1: 사용자가 결제를 취소한다

          • 커맨드2: 관리자가 결제를 취소한다

      • 자동 처리로도 발생하는가? (사람의 커맨드 없이)

        • eg.

          • 시간 기반: 만료/타임아웃/정산일 도래

          • 외부 입력 기반: Stripe webhook 수신

          • 내부 정책 기반: 리트라이/상태 전이 규칙

    • 사용자 액션과 시스템 반응의 경계를 분명히 한다

정책 / 도메인 불변식 정리 (20분)

  • 목표

    • 이벤트 사이에 숨어 있는 정책, 조건, 분기를 드러낸다
  • 규칙

    • 언제, 어떤 조건에서를 반드시 질문하면서 밝혀낸다

    • 합의되지 않은 정책은 억지로 결정하지않는다

      • 대신 왜 어려운지, 누가 결정해야 하는지를 명확히 남긴다

컴포넌트 매핑(애그리거트 / 리드모델) (10분)

  • 목표

    • 이벤트와 커맨드가 어디의 상태를 변경하는지 드러낸다

    • 이후 설계/모델링의 초기 구조 후보를 만든다

  • 규칙

    • 이 단계에서 결정하는 애그리거트 / 리드모델은 확정이 하닌 후보 정도로 취급한다 (오늘 스트라이프 스토밍에서는 이미 정의가 되어있기때문에 이 규칙은 적용하지않는다)

    • 정책과 불변식에서 드러난 내용을 근거로만 매핑한다

    • 논쟁이 생기면 억지로 결론 내리지않고 핫스팟으로 남긴다

핫스팟 정리 (10분)

  • 목표

    • 오늘 세션에서 불확실성이 가장 큰 지점을 명확히 남겨보기
  • 규칙

    • 핫스팟 유형 구분

      • eg.

        • 정책 미결정

        • Stripe 제약 조건

        • 참여자 간 해석 차이

최종 정리 + 다음 액션 (10분)

  • 목표

    • 오늘 결과를 이후 작업으로 안전하게 넘길 수 있는 상태 만들기
  • 규칙

    • 다음을 명확히 남긴다

      • 합의된 이벤트 흐름

      • 추가 논의가 필요한 지점

      • 수납(Purchase) 도메인 모델 반영 범위

주요 원칙

확신이 없거나 모르는건 숨기지 말고 드러낸다

  • 아래 내용들 드러내라.

    • 이건 잘 모르겠다.

    • 확신이 안선다

    • Stripe가 이걸 보장해주나?

    • 이 케이스 실제로 발생할 수 있는건가?

  • 이것들은 모두 문제 제기가 아니라 이벤트 스토밍의 핵심 산출물이다

  • 이 때 확신 없는 이벤트와 정책은

    • 추측으로 채우지말고

    • 핫스팟으로 남겨두고 최종 과정에서 논의한다

이벤트 스토밍 결과는 시스템 설계가 아니다

  • 결과물은 구현 명세, API 스펙이 아니다

  • 단지 작업자들의 이해가 얼라인 된 상태를 기록한 흔적이다

    • 이 결과물을 토대로 설계, 모델링, 구현에 활용한다

동일한 의미를 가진 이벤트/커맨드 중복 정의를 허용한다

  1. 동일한 의미를 가지더라도 중복을 막지않는다

  2. 중복을 즉시 합치지 않는다

  3. 중복 자체를 정보로 활용한다

  • 이 때 왜 허용해야하는가?

    • 같은 이벤트라도, 표현이 다르거나 범위가 다르가나 의미가 다를 수 있음

    • eg.

      • 결제가 실패했다

      • 카드 승인에 실패했다

      • Stripe 결제가 실패했다

  • 그럼 언제 정리함?

    • 이벤트 나열 단계에서 정리하지않고

    • 정리는 이벤트 흐름 정렬 단계에서 한다

      • 완전한 동일한 의미의 이벤트는 한 위치에 모아둔다

      • 표현만 다른 경우, 더 도메인에 적합한 이름으로 통합

      • 의미가 다를 가능성이 있다면, 분리 유지하거나 핫스팟 표시해두고 넘어가도록한다

    • 이벤트 나열 단계의 목적은 수렴이 아니라 발산임

이벤트는 도메인 관점에서 의미 있는 사실만 다룬다

  • 이벤트는 화면 변화, API 호출, 단순 로그가 아니다

  • 도메인에서 무슨 일이 생겼는가에 집중한다

  • 만약 Stripe 결제 승인 웹훅이 수신되었다 와 같은 사건이 정의되었다면 이것은 도메인 이벤트가 아닌, 도메인 이벤트를 유발하는 트리거로 구분한다

    • 외부 입력(Trigger/Signal): Stripe 결제 승인 웹훅이 수신되었다

      • 관측된 사실일뿐임
    • 도메인 이벤트: 결제가 승인 되었다

편의상 하나로 뭉치지 않는다

  • 너무 큰 이벤트는 추후 정책/ 분기에서 터질 가능성이 높다

  • 헷갈리면 되도록 쪼개는 쪽을 택한다

    • eg. 결제 처리가 완료되었다 (X)

      • 결제가 승인되었다

      • 결제가 실패되었다

      • 결제가 취소되었다

  • 정제되지 않은 과잉 표현이 뭉개진 추상화보다 보통 낫다


위 문서를 작성하면서 고민되었던것은

우리는 이미 우리의 도메인 모델을 너무 잘 알고있다

무슨 말이냐면, 스트라이프 통합 과정에서 필요한 애그리거트와 리드모델, 이벤트 등 이미 어떻게 동작하는지, 누가 액터이고 명령을 수행하는지에 대해 팀원 모두 너무 잘 알고있다.

위 전제로 인해, 진행 방식 순서에 대한 고민이 많았다. 보통 다같이 이벤트 발산과 정렬한 뒤 여러 컴포넌트들을 통합해가며 애그리거트를 도출하는데, 이미 애그리거트와 정책은 사전 플래닝 과정에서 얼라인 되어있었기때문이다.

그래서 아래 항목이 가장 고민이 많이됐다.

우리는 왜 이벤트 스토밍을 하는가?

  1. 수납(Purchase) 도메인 모델과 Stripe 결제 연동에 대한 이해를 얼라인한다

    1. 각자가 알고있는 도메인 모델과 연동 흐름의 차이를 드러낸다

    2. 얼라인 된 이해를 바탕으로 BC 내 보편 언어(UL)을 정의한다

  2. 각자의 머릿속에 있는 이해가 서로 다르다는 사실을 빠르게 발견한다

  3. 말로 설명하기 어려운 흐름을 하나의 시각적 모델로 맞춰본다

  4. 얼라인된 결과물을 공식 산출물로 남긴다

    1. 이벤트 스토밍 결과를 수납(Purchase) 도메인 모델 문서에 반영한다

    2. 이후 설계, 모델링, 구현에 활용한다

위 내용에서 새로운 애그리거트를 도출하기보다는 각자 알고있는 지식의 수준을 얼라인 하고 보편 언어를 정의하는데 필요한 도구라는것을 강조하고싶었다. 실제 스토밍 진행 전에 이 내용을 강조도 했었고, 팀원들도 동의하는 바였다.

하지만 결과는

이것은 약 2시간 정도의 시간을 진행했을 때 나온 결과물이다. 이벤트 발산과 정렬까지 꽤나 밀도있게 진행했다고 생각은 들지만 시간 투자 대비 결과가 너무 만족스럽지못했다.

왜냐면, 아래 거래 이벤트쪽을 자세히 살펴보면

각자 많은 도메인 이벤트를 발산한거까지는 좋았지만, 막상 그룹핑 해보니 이미 우리는 도메인 모델을 너무 잘 알고있고 용어도 크게 다를게 없었다.

필자는 이 과정에서 도메인 이벤트 → 발산 → 정렬 하는 과정에서 보편 언어와 예상치 못한 사건을 발견할 수 있기를 기대했다. 하지만, 결과는 이미 모두 같은 언어를 사용하고있었고 (결제와 거래의 표현은 약간 달랐지만, 매우 사소했음) 이미 사전 플래닝에서 나온 이벤트만 정의가 되었던것이다.

물론 이 과정에서 약간의 다른 표현과 이벤트의 트리거 조건, 액터는 누구인가를 밝히는 과정에서 새롭게 알게된 지식 + 얼라인 된 것은 매우 좋았지만 시간 투자 대비 결과가 너무 아쉽다는 생각이 들었다.

매우 좋았던 부분은 사실 요청 흐름을 시퀀스 다이어그램으로 표현하고, 여기서 필요한 명령을 기준으로 정책을 뽀개보는게 더 밀도 높게 진행할것이란 생각이 스쳤고 팀원들과 이것에 대해 이야기해보니 모두 비슷한 생각이였다. (ROI가 맞지않다고 판단함)

이때, 우리는 ‘탐색이 필요한 상태’가 아니라, ‘정렬이 끝난 상태’에 가까웠다고 생각했다

그래서 과감하게 우리는 이벤트 스토밍 세션을 중단하고 아래와 같이 바로 시퀀스를 그려보고 도메인 모델 문서로 넘어갔다.

오히려 더 뾰족하게 우리가 지금 더 고민해야 하는 영역에 집중할 수 있었고 약 2시간 가까이 집중해서 그레이 영역을 모두 밝혀냈다.

그 결과, 위와 같이 보편 언어(UL)와 정책 또한 빠른 시간 내에 깔끔하게 정리가 되었다. 처음부터 이벤트 스토밍이 아니고 위 과정을 바로 들어갔다면, 플래닝의 ½ 정도의 시간을 실제 시스템 설계에 더 투자했을 것이라 생각된다.

그래서 필자의 최종 결론은

필자가 속한 KOS 팀은 DDD를 효과적으로 쓰기 위해 모두가 노력중이고, 계속 배워나가고있다. 엔지니어만 노력하는게 아닌 비 엔지니어(PO, PD, Sales) 모두가 말이다.

이벤트 스토밍은 DDD를 활용하고있는 팀에서만 사용하는 도구는 아니긴 하지만, 관련된 개념들을 접목시켜 효과적으로 도메인 사건을 도출하고 식별하며 맥락 경계(bounded context) 와 집합 (aggregate)의 지식을 맞춰볼 수 있는 행위라 생각한다.

하지만 이번 이벤트 스토밍 세션은 DDD를 더 잘하고, 효과적으로 사용하고싶은 팀, 구성원에게 아직은 어색한 도구를 익힌다는 과정에서 큰 도움은 되었지만, 실제 제품 기여 레벨로 봤을 때 모두의 비싼 시간을 허비한게 너무 컸었다.

필자는 그래서 이벤트 스토밍이라는 도구는 백지 상태에서 도메인 모델을 정의해야할 때 다시 조심히 꺼내볼거같다.

이미 그림이 그려져 있는 스케치북에서 이벤트 스토밍이라는 비싼 활동으로 색을 더해 가는 것은, 오히려 문제를 선명하게 만들기보다 밀도를 낮출 수도 있다는 것을 이번에 배웠다.

특히

  • 핵심 애그리거트와 정책이 이미 정리되어있고

  • 남은 문제가 새로운 도메인 (모델) 발견이 아니라 흐름/ 조건/ 책임의 정리이며

  • 팀의 도메인 (모델) 이해 수준이 이미 충분히 높다면

이벤트 스토밍은 탐색의 도구가 아니라 (이미 얼라인 된) 확인과 반복의 도구로만 작동할 가능성이 크다는것을 느끼고 배웠다.

이번 경험을 통해 필자는 이벤트 스토밍을 잘하는 방법 보다는 언제 쓰지 말아야하는지 에 대한 판단 기준을 얻었다고 생각한다.

마지막으로 이 경험을 함께 만들고 솔직하게 방향 전환에 동의해준 KOS팀에 감사하며 이 글을 마친다.

More from this blog

리텐션이 0에 수렴해서 데이터부터 다시 들여다봤더니

Foundry는 백엔드 엔지니어를 위한 기초 지식 학습 플랫폼입니다. 시험을 보고, 틀린 문제를 오답노트에 정리하고, 개념을 복습하는 서비스인데요. 베타 오픈 후 커뮤니티에 올려서 유저도 좀 모았고, 기능도 하나하나 잘 만들어놨다고 생각했습니다. 그런데 GA4를 열어보니 현실은 달랐거든요. 문제: 숫자가 말해주는 현실 GA4 리포트를 열어봤더니 대시보드 페

Mar 15, 20265 min read30

극한 프로그래밍?

XP(Extreame Programming, 이하 XP)는 애자일 방법론 중 하나이다. 고객의 요구가 자주 변하는 환경에서 소프트웨어 품질을 높이고, 변화에 빠르게 대응하기 위해 고안된 개발 방법을 말한다. 1990년대, 켄트 백(kent back)이 chrysler c3 프로젝트에서 처음 체계화했다고하며, 짧은 개발 주기와 강한 피드백 루프, 협업 중심 문화를 특징으로 한다. XP는 “가치를 극대화하려면 좋은 활동들을 극단으로 끌어올리자”라는...

Dec 13, 20253 min read9
극한 프로그래밍?

물음표 엔지니어

20 posts

기술적 접근에 있어 트레이드 오프에 대한 고민을 다뤄보려합니다.

(Deprecated Blog: https://jeongkyun-it.tistory.com)

이벤트 스토밍은 비싸다 – ROI 관점에서 돌아본 실패 회고