사용자 스토리 (마이클 콘)

대상 도서: User Stories Applied (Mike Cohn)
목표: 요구사항을 "한 번에 완성된 명세"로 다루지 않고, 작은 가치 단위 + 대화 + 검증으로 운영하기.


1) 사용자 스토리의 본질

사용자 스토리는 PRD/설계서의 축약본이 아니다.

  • 스토리 = 대화를 시작하기 위한 약속
  • 상세는 대화로 확정하고, 완료는 검증 기준으로 판단
  • 핵심 프레임: 3C (Card / Conversation / Confirmation)

3C를 실무에 적용하는 법

  • Card: 1~2문장으로 의도만 담는다.
  • Conversation: 기획/개발/QA가 예외/경계/범위제외를 맞춘다.
  • Confirmation: AC(수용 기준)와 테스트로 Done을 판단한다.

실제 시나리오

문제: "주문 검색 고도화"가 너무 큰 요구로 들어옴.

  • Card:
    • As a 상담사, I want 주문을 고객 전화번호로 검색, so that 고객 문의를 빠르게 처리할 수 있다.
  • Conversation에서 나온 쟁점:
    • 부분일치 허용 여부
    • 기간 기본값
    • 개인정보 마스킹 기준
  • Confirmation:
    • 3자리 미만 입력 시 검색 불가
    • 최근 90일 데이터 기본 조회
    • 응답 목록의 전화번호는 가운데 4자리 마스킹

2) 스토리 템플릿

기본 형태:

As a [사용자 유형], I want [원하는 것], so that [얻는 가치].

좋은 문장과 나쁜 문장

좋은 예:

  • As a 구매자, I want 주문 내역을 기간별로 조회, so that 월별 지출을 확인할 수 있다.

나쁜 예:

  • 주문 API에서 인덱스를 추가한다. (사용자/가치 없음)
  • Redis 캐시를 붙인다. (해결수단만 있고 문제정의 없음)

실무 팁

  • so that가 비어 있으면 거의 항상 품질이 낮다.
  • 기술 태스크는 스토리의 하위 Task로 내린다.
  • 스토리에는 "왜"를, 태스크에는 "어떻게"를 적는다.

3) 좋은 스토리 기준 (INVEST)

  • Independent: 독립성
  • Negotiable: 협상 가능성
  • Valuable: 가치
  • Estimable: 추정 가능성
  • Small: 작은 크기
  • Testable: 검증 가능성

INVEST 점검 예시 (결제 실패 재시도)

스토리:

As a 구매자, I want 결제 실패 후 즉시 재시도, so that 주문을 놓치지 않는다.

점검:

  • Independent: 주문조회 개선 스토리와 분리됨 (O)
  • Negotiable: 재시도 횟수/쿨타임 조정 가능 (O)
  • Valuable: 주문 전환율과 직결 (O)
  • Estimable: 대략 3~5pt 추정 가능 (O)
  • Small: 재시도 버튼 + API 1개 범위로 제한 (O)
  • Testable: 실패 코드/성공 전환 시나리오 테스트 가능 (O)

4) 수용 기준(AC) 상세 작성법

스토리는 짧게, AC는 구체적으로.

AC 작성 원칙

  1. 관찰 가능해야 함
  2. 모호한 단어 금지("빠르게", "적절히")
  3. 정상/예외/경계값 포함
  4. 가능한 Given/When/Then 형식

실제 시나리오: 주문 목록 기간 조회

스토리:

As a 구매자, I want 주문을 기간별로 조회, so that 지출 추이를 파악할 수 있다.

AC:

  • Given 로그인 사용자일 때
  • When 기간을 2026-03-01~2026-03-31로 설정하면
  • Then 해당 기간 주문만 최신순으로 반환된다.
  • And 응답 시간 p95는 1.0초 이하이다.
  • And 주문이 0건이면 빈 배열과 "주문 없음" 메시지를 반환한다.

경계값 AC:

  • 시작일 > 종료일이면 400 에러
  • 최대 조회 기간은 365일

5) 스토리 분할 전략 (큰 요구를 작게)

큰 스토리를 한 번에 구현하면 예측도 품질도 무너진다.

대표 분할 방식

  1. 워크플로우 단계 분리: 조회 → 생성 → 수정 → 취소
  2. 규칙 분리: 기본 규칙 → 예외 규칙
  3. 데이터 분리: 핵심 필드 → 부가 필드
  4. 접점 분리: API → UI → 운영도구
  5. 난이도 분리: happy path → edge cases

실제 시나리오: "환불 자동화"

원본 에픽:

  • "환불 자동화 구축"

분할 후 스토리: 1) 상담사가 환불 요청을 생성한다. 2) 결제상태가 PAID일 때만 승인 가능하다. 3) 승인 시 PG 환불 API 호출 이력이 저장된다. 4) 실패 시 재시도 큐에 적재된다. 5) 관리자 화면에서 환불 상태를 조회한다.

이렇게 쪼개면 각 스토리가 사용자 가치와 테스트 경계를 가진다.


6) Theme / Epic / Story 운영

  • Theme: 전략적 방향
  • Epic: 큰 기능 그룹
  • Story: 스프린트 단위 구현 항목

실제 시나리오

  • Theme: 고객센터 처리속도 개선
  • Epic: 상담사 주문조회 고도화
  • Stories:
    • 전화번호 검색
    • 기간 필터
    • 상태 필터
    • 결과 CSV 다운로드

운영 팁:

  • 계획 단계에선 Epic 중심, 실행 단계에선 Story 중심으로 전환
  • 스프린트 중 "생각보다 큼"이 확인되면 즉시 재분할

7) 추정(Estimation)과 불확실성 관리

핵심은 "정답 시간"이 아니라 "상대 크기"다.

실무 방식

  • 스토리 포인트 기반 상대 추정
  • 기준 스토리(앵커) 1~2개 유지
  • 불확실성 큰 건 스파이크(탐색) 먼저 수행

실제 시나리오

문제: 신규 정산 배치가 데이터량에 따라 성능 위험 큼.

대응:

  1. 스토리 직접 개발 전 스파이크 1pt 배정
  2. 샘플 데이터 100만 건으로 실행시간 측정
  3. 결과 기반으로 본 스토리 재추정(5pt → 8pt)

효과:

  • 중간에 "예상 밖 지연"으로 스프린트 깨지는 확률 감소

8) 우선순위: 가치 + 위험 + 학습

우선순위는 "중요해 보임"이 아니라, 아래 4축으로 본다.

  • 비즈니스 가치
  • 리스크 감소
  • 학습 가치(빠른 피드백)
  • 구현 비용

실제 시나리오

후보 3개:

  • A: 신규 대시보드 UI 개선 (가치 중, 위험 낮음)
  • B: 결제 중복요청 멱등 처리 (가치 높음, 위험 높음)
  • C: 관리자 필터 추가 (가치 중, 비용 낮음)

우선순위: 1) B (장애/금전 리스크 감소) 2) C (빠른 가치 제공) 3) A


9) 안 좋은 스토리 신호와 수정법

신호

  • 사용자/가치가 없음
  • AC가 없음
  • 한 스프린트 내 종료 불가
  • 의존성이 과도함
  • 팀원 해석이 다름

수정 예시

나쁜 스토리:

  • "정산 모듈 리팩토링"

개선:

  • As a 운영자, I want 정산 실패 건을 즉시 재처리, so that 수동 정산 시간을 줄인다.
  • AC:
    • 실패 건 목록 조회 가능
    • 단건 재처리 가능
    • 재처리 결과 이력 저장

10) 실무 템플릿 (복붙용)

스토리 카드

[Story]
As a [role]
I want [goal]
so that [value]

[Acceptance Criteria]
1) Given ... When ... Then ...
2) Given ... When ... Then ...
3) 예외/경계 조건

[Notes]
- 범위 제외(Out of Scope):
- 의존성:
- 리스크:
- 측정지표(KPI):

스프린트 진입 체크리스트

  • INVEST 충족
  • AC 3개 이상
  • 범위 제외 명시
  • 테스트 가능
  • QA/개발/기획 공통 이해

PR 본문 연결 템플릿

[Story]
링크: ...

[AC Mapping]
- AC1: 어떤 코드/테스트로 충족했는지
- AC2: ...
- AC3: ...

[Validation]
- 통합테스트:
- 수동검증:
- 모니터링 포인트:

11) 백엔드 팀 적용 시나리오 (Kotlin/Spring)

시나리오 A: 주문 상태 필터 API

스토리:

As a 상담사, I want 주문을 상태별로 필터, so that 고객 문의를 빠르게 처리한다.

AC:

  • 상태 파라미터가 없으면 전체 조회
  • 상태 파라미터가 있으면 해당 상태만 반환
  • 잘못된 상태값이면 400 에러

Task 예시:

  • Controller 파라미터 검증
  • Service 필터 로직
  • Repository query 추가
  • 테스트(정상/예외)

시나리오 B: 멱등 키 기반 중복 결제 방지

스토리:

As a 구매자, I want 결제가 한 번만 처리, so that 중복 결제를 피한다.

AC:

  • 동일 idempotency key 재요청 시 기존 결과 반환
  • key 만료시간 정책 적용
  • 충돌/경합 상황에서 이중 처리 없음

검증:

  • 동시성 테스트
  • DB unique 제약/락 확인
  • 운영 로그에서 중복 결제 0건 확인

시나리오 C: 배치 실패 재처리

스토리:

As a 운영자, I want 실패 배치를 재실행, so that 정산 지연을 줄인다.

AC:

  • 실패 목록 조회 가능
  • 재실행 버튼/API 제공
  • 성공/실패 이력 보관

추가 포인트:

  • 재처리 idempotent 설계
  • 재시도 횟수/백오프 정책 명시

12) 도입 로드맵 (2주)

1주차

  1. 스토리 템플릿 팀 공통화
  2. AC 없는 이슈 스프린트 진입 금지
  3. PR에 AC 매핑 필수 적용

2주차

  1. 에픽 분할 리뷰 미팅 15분 고정
  2. 스프린트 회고에서 "스토리 품질" 항목 추가
  3. INVEST 미충족 사례 수집 후 개선

측정 지표:

  • 스프린트 carry-over 감소율
  • 리뷰 재작업 횟수 감소
  • AC 누락 이슈 비율

요약

마이클 콘의 사용자 스토리 핵심은 "형식"이 아니라 "운영"이다.

  • 스토리는 짧게(Card)
  • 대화는 충분히(Conversation)
  • 검증은 구체적으로(Confirmation)
  • 구현 단위는 작고 독립적으로

이걸 지키면, 스프린트 예측 가능성과 코드 리뷰 품질이 같이 오른다.