Communitygithub.com

Design by Story

사용자가 사용자 스토리별로 정리된 클릭 가능한 제품 프로토타입이나 디자인 목업(웹 앱, 폰 앱, 태블릿 앱 또는 여러 개를 한 번에)을 원할 때 사용합니다. 기기 전환기(웹사이트/Android/iPhone/iPad)와 스토리 전환기가 있는 단일 HTML 파일을 생성하여, 검토자가 스토리를 선택하고 해당 스토리에 필요한 화면과 데이터를 모든 기기에서 정확히 살펴볼 수 있도록 합니다. 또한 이러한 프로토타입에서 스토리를 추가, 변경 또는 분할할 때도 사용합니다.

Design by Story란 무엇인가요?

Design by Story는 사용자 스토리 중심의 단일 파일 HTML 프로토타입을 생성하는 AI 어시스턴트 스킬입니다. 웹 앱, 안드로이드, 아이폰, 아이패드 등 여러 기기에서 동일한 프로토타입을 미리보기 할 수 있으며, 각 스토리별로 필요한 화면과 데이터를 분리하여 제공합니다. 이 스킬은 주로 Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트에서 사용되며, 사용자 스토리를 기반으로 한 프로토타이핑 워크플로우를 자동화합니다. 스토리의 우선순위(MoSCoW), 상태, 수락 기준(Given/When/Then 형식), 연습 과정(walkthrough) 및 메모를 포함한 상세 정보를 프로토타입 내에서 직접 확인할 수 있습니다. 또한 스토리 분할, 변경, 추가 등의 변경 작업을 지원하며, 모든 상호작용은 URL 해시를 통해 공유 가능합니다. 마크업, CSS, JS가 모두 하나의 HTML 파일에 인라인으로 포함되어 별도의 빌드 과정이나 백엔드 없이 바로 실행할 수 있습니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/rinkledink/design-by-story-skill/tree/HEAD/design-by-story

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Design by Story은(는) 무엇을 하나요?

여러 기기에서 볼 수 있는 단일 파일 HTML 프로토타입을 제품의 사용자 스토리별로 기기별 구분과 동일한 방식으로 분류하여 만듭니다.

상단 바에는 두 개의 전환기가 있습니다.

  • 기기: 예: 웹사이트 · Android · iPhone. 동일한 제품이지만 프레임이 다릅니다.
  • 스토리: "모든 스토리"와 각 사용자 스토리별 항목. 스토리를 선택하면 공유 데이터가 해당 스토리의 초기값으로 재설정되고, 모든 기기가 스토리의 시작 화면으로 이동하며, 스토리, 우선순위, 상태, 수락 기준, 연습 과정 및 메모가 포함된 패널이 열립니다.

두 선택 항목 모두 URL 해시(#story=S2&device=iphone)에 저장되므로, 특정 스토리의 특정 기기 링크를 리뷰나 티켓에 복사하여 붙여넣을 수 있습니다.

워크플로우

  1. 입력 수집 (한 번의 메시지로 누락된 정보만 질문):

    • 제품이 무엇이며 누가 사용하는지.
    • 표시할 기기. 기본값: 웹사이트 + Android + iPhone. 현장/키오스크 사용 시 태블릿 포함.
    • 사용자 스토리 (목록, 백로그 내보내기, 기능 문서 등 어떤 형태든 가능).
    • AC 형식: Given/When/Then 또는 일반 규칙? 기본값은 Given/When/Then.
    • 우선순위(MoSCoW)와 상태(있는 경우). 없으면 기본값은 should / draft.
    • 주요 데이터 모델 (주요 레코드 + 핵심 필드) 또는 스토리에서 유추.

    모든 스토리를 스토리 형식으로 정규화합니다. 사용자에게 스토리가 없으면 제품 설명에서 3~6개를 초안 작성한 후 빌드 전에 확인합니다.

  2. 스토리 확인 품질 체크리스트에 따라 검증합니다. 문제점을 짧은 목록으로 제시합니다. 사용자의 표현을 조용히 재작성하지 마십시오.

  3. 스토리별 화면 계획. 각 스토리에 대해 해당 스토리가 각 기기에서 사용하는 화면과 필요한 초기 데이터를 나열합니다. 스토리는 제품이 실제로 그렇게 작동하는 경우에만 특정 기기를 건너뜁니다(예: 웹사이트에서만 관리자 기능). devices 목록에 이를 명시하고, 해당 기기가 선택된 동안 전환기에서 다른 기기를 비활성화합니다.

  4. assets/shell.html 복사 사용자가 선택한 경로(기본값 docs/reference/prototype.html)로 복사하고 내용을 채웁니다. references/prototype-spec.md를 참조하여 시각적 규칙(프레임, 토큰, 유형, 카드, 알약, 토스트, 서랍, 아이콘, 복사 어조)을 확인합니다.

  5. 스토리가 아닌 화면 구축. 화면은 공유되고, 스토리는 진입점과 초기 데이터 역할을 합니다. 스토리별로 화면을 절대 중복하지 마십시오. 스토리에 변형이 필요한 경우 초기 데이터를 통해 구동합니다.

  6. 브라우저에서 확인. 브라우저 도구가 있으면 사용합니다. 그렇지 않으면 headless Chrome 사용: --dump-dom "file:///…/prototype.html#story=S2&device=iphone"으로 렌더링 결과 확인, --screenshot으로 시각 확인, --enable-logging=stderr로 콘솔 오류 확인. 확인 사항:

    • 목록에 있는 모든 기기의 모든 스토리가 올바른 화면에서 열리는지;
    • 모든 AC를 시연할 수 있고, 연습 과정을 클릭하여 진행할 수 있는지;
    • 스토리 도중 기기를 전환해도 상태가 유지되는지;
    • 다른 스토리의 컨트롤이 현재 스토리 아래에 나타나지 않고, "모든 스토리"에서 모든 스토리의 컨트롤이 함께 작동하는지;
    • 콘솔에 오류가 없는지.
  7. 동기화 유지. 나중에 스토리가 추가되거나 변경되면 동일한 편집에서 #story-text 항목, BEHAVIOUR 항목 및 해당 스토리가 나열된 모든 기기를 업데이트합니다.

스토리 형식

스토리는 셸에서 두 곳에 존재하며, 모두 ID로 키가 지정됩니다.

  • 텍스트는 #story-text JSON 블록에 있으며, 스토리 패널에서 읽기 전용으로 표시됩니다.
  • 동작은 BEHAVIOUR에 있으며, 코드만 포함됩니다.
<script type="application/json" id="story-text">
{
  "S1": {
    "title": "검색 저장",
    "story": "방문자로서 검색을 저장할 수 있어, 다시 검색하지 않고도 새로운 일치 항목을 알 수 있습니다.",
    "priority": "must",
    "status": "draft",
    "ac": [
      { "id": "S1-AC1", "text": "Given \"오크 테이블\"을 검색했을 때, When 저장 검색을 탭하면, Then 저장됨 아래에 나타난다" },
      { "id": "S1-AC2", "text": "Given 해당 검색이 이미 저장되었을 때, When 다시 저장하면, Then 저장됨에 여전히 한 번만 표시된다" }
    ],
    "acNext": 2,
    "walkthrough": ["\"오크 테이블\" 검색", "저장 검색 탭", "저장됨 열기"],
    "outOfScope": ["이메일 알림"],
    "assumptions": ["저장하려면 방문자가 로그인해야 함"],
    "questions": ["저장된 검색에 제한이 있나요?"]
  }
}
</script>
const BEHAVIOUR = {
  S1: {
    devices: ['web', 'android', 'iphone'],         // 이 스토리가 적용되는 프레임
    start: { web: 'search', android: 'search', iphone: 'search' }, // 기기별 시작 화면
    features: ['save-search'],                      // 이 스토리가 활성화하는 기능
    seed: () => ({ user: SIGNED_IN, saved: [] }),  // 이 스토리의 초기 데이터
  },
};
필드규칙
storyAs a <persona>, I can <action>, so that <benefit>. 혜택은 사용자가 얻는 것이지, 행동의 재진술이 아니어야 합니다.
prioritymust · should · could · won't (MoSCoW).
statusdraft · in review · agreed.
ac객체 { id, text }. ID는 <story>-AC<n> 형식이며, 절대 번호를 다시 매기거나 재사용하지 않습니다. 아래 참조.
acNext이 스토리에 대해 발급된 가장 높은 AC 번호입니다. 새 AC는 acNext + 1을 사용하며, acNext도 업데이트됩니다. AC를 추가할 때마다 업데이트합니다.
walkthrough검토자가 클릭하여 진행하는 데모 스크립트입니다. 수락 기준이 아닙니다. 짧게 유지하세요.
outOfScope, assumptions, questions일반 목록입니다. 채우기 항목을 만들지 말고 비워 두세요. 사용자가 확실하지 않은 내용은 질문으로 기록하세요.

seed()는 호출할 때마다 새 객체를 반환하므로, 스토리를 다시 선택하면 항상 깨끗하게 다시 시작됩니다. "모든 스토리"는 DEFAULT_SEED와 각 기기의 홈 화면을 사용합니다.

수락 기준

  • AC당 하나의 테스트 가능한 동작, 사용자가 선택한 형식으로. Given/When/Then은 한 줄: Given <컨텍스트>, when <액션>, then <관찰 가능한 결과>.
  • 정확한 문구: AC가 메시지에 관한 것일 때는 메시지를 인용하세요(then I see "현재 열려 있는 항목이 없습니다."). "친근한 메시지"처럼 애매하게 쓰지 마십시오.
  • 결과, 스타일링이 아님: "완료로 표시됨"은 괜찮지만 "초록색 알약이 나타남"은 안 됩니다. 시각적 세부 사항은 그것이 요구 사항일 때만 AC가 됩니다.
  • 한 기기에서 테스트 가능. 다른 기기에 대한 AC를 작성하지 마십시오(예: "모든 기기에 표시됨", "웹 전용", "휴대폰에서 변경 불가"). 스토리가 다루는 기기는 devices에 속하며, 기기 간 동기화는 백엔드의 책임입니다.
  • ID는 영구적입니다. S1-AC3는 편집, 이동 또는 하위 스토리로 분할될 때도 ID를 유지하므로 테스트 및 티켓으로 추적할 수 있습니다. 새 AC는 acNext + 1을 사용합니다. 삭제된 ID는 다시 발급되지 않으며, 번호를 다시 매기지 않습니다.

품질 체크리스트

빌드하기 전과 변경될 때마다 각 스토리를 확인하세요.

  • 페르소나는 실제 사용자 역할이며, 혜택은 사용자가 실제로 말할 법한 내용인가?
  • 독립적으로 가치를 제공하며(독립적), 1분 이내에 데모할 수 있을 정도로 작은가? 그렇지 않다면 분할하세요.
  • 모든 AC에 ID, 단일 동작 및 관찰 가능한 결과가 있는가?
  • 빈 상태, 오류 상태, 제한 사례가 다루어졌거나 questions 아래에 나열되었는가?
  • 다른 스토리에 대한 의존성이 표시되었는가? (공유 기능 키와 assumptions에 언급, 예: "S2에 기반하여 구축").

스토리 기능은 해당 스토리가 선택될 때까지 비활성화됨

스토리가 도입하는 모든 상호작용은 해당 스토리의 features에 나열된 기능 키를 받습니다. can('save-search')는 해당 스토리를 나열하는 스토리가 선택된 경우에만 true입니다.

  • 렌더링: 스토리의 컨트롤을 can(...)으로 감싸서 그렇지 않으면 존재하지 않도록 합니다(버튼 없음, 폼 없음, 메뉴 항목 없음). 비활성화된 상태로 표시하지 마십시오. 검토자는 선택한 스토리가 추가하는 내용만 볼 수 있어야 합니다.
  • 핸들러: 각 스토리 핸들러를 if (!can('save-search')) return;으로 시작하여, 오래된 DOM이나 콘솔에서도 스토리 외부에서는 아무것도 실행되지 않도록 합니다.
  • **"모든 스토리"**는 모든 스토리의 기능을 동시에 활성화합니다: DEFAULT_SEED에서 현재 상태의 전체 제품. 스토리가 충돌하지 않는지 확인하십시오(예: 두 컨트롤이 같은 위치에 있는 경우).
  • 다른 스토리의 상호작용에 의존하는 스토리는 두 키를 모두 나열합니다(예: "상태별 필터링"은 ['filter', 'complete']를 나열하여 작업 완료 시 필터링된 목록을 벗어나는 것을 보여줄 수 있음).
  • 스토리가 표시만 하는 데이터(예: 담당자의 이니셜)는 게이트되지 않습니다. 변경할 수 있는 기능만 게이트됩니다.

스토리 변경

프로토타입은 스토리를 표시만 할 뿐, 편집하거나 저장하지 않습니다. 모든 스토리 변경은 채팅을 통해 Claude를 통해 이루어집니다.

  • 새 스토리: 스토리, AC 및 질문을 초안 작성하고, 사용자와 품질 체크리스트를 실행한 후, #story-text 항목과 BEHAVIOUR 항목을 작성하고 화면을 한 번에 구축합니다. 스토리는 텍스트로만 존재하지 않습니다. 그렇게 되면 셸이 전환기에서 제외하고 콘솔에 오류를 기록합니다.
  • 변경된 스토리(문구, AC, 우선순위, 상태, 메모): #story-text를 편집합니다. 변경이 스토리의 동작을 변경하는 경우(새 AC, 다른 연습 과정), 동일한 편집에서 화면과 BEHAVIOUR도 업데이트합니다.
  • 리뷰 피드백: 사용자가 검토자의 의견을 전달하면, 각각을 위의 변경 유형 중 하나로 변환하거나, 아직 해결되지 않은 경우 questions 아래에 항목으로 추가합니다.
  • 항상 어떤 스토리와 AC ID를 빌드하거나 변경했는지 말하세요.

사용자가 Jira 등 트래커에 스토리를 보관하는 경우, 트래커가 마스터 사본입니다. 여기서는 스토리를 프로토타입에서만 편집하지 말고 트래커의 문구를 반영하세요.

스토리 분할

사용자가 스토리를 분할하도록 요청하거나, 스토리에 약 5개 이상의 AC, 둘 이상의 주요 기능 키 또는 별도로 출시할 수 있는 AC가 있는 경우 분할합니다.

  1. 분할 패턴 선택 및 사용한 패턴을 알립니다:

    • 워크플로우 단계 (생성 → 검토 → 게시)
    • 작업 (추가 / 편집 / 삭제)
    • 먼저 해피 패스, 그 다음 에지 케이스 (빈 상태, 중복, 제한 도달)
    • 기기 또는 역할별 (휴대폰 캡처 vs 웹사이트 관리)
    • 데이터 변형별 (항목 하나 → 여러 개, 통화 하나 → 여러 개)
    • 단순한 것 먼저, 그 다음 추가 기능 (일반 정렬 → 저장된 정렬 환경설정)

    각 하위 스토리는 여전히 고유한 가치가 있는 완전한 As a… I can… so that… 형식이어야 합니다.

  2. 하위 스토리 번호를 부모에서 파생: S3 → S3.1, S3.2, … 부모를 #story-text와 BEHAVIOUR 모두에서 제거하고 하위 스토리를 그 자리에 넣습니다. 셸의 readHash는 이전 #story=S3 링크를 S3.1로 보내므로 공유 링크가 계속 작동합니다.

  3. 분할, 중복 금지:

    • 수락 기준. 각 부모 AC는 원래 ID를 유지한 채 정확히 하나의 하위 스토리로 이동합니다 (S3-AC2는 S3.1 내에서 S3-AC2로 유지). AC가 두 하위 스토리에 걸쳐 있으면 두 개의 새 AC (S3.1-AC1, S3.2-AC1)로 다시 작성하고 대체하는 부모 ID를 기록합니다.
    • 기능 키. 상호작용이 분할되면 키도 분할합니다 (filter → filter-status, filter-counts). 하위 스토리는 위의 의존성 규칙처럼 형제 스토리를 기반으로 구축할 때 그 키를 나열할 수도 있습니다.
    • 기기. 각 하위 스토리는 실제로 사용하는 기기만 나열합니다.
    • 초기 데이터. 이후 하위 스토리의 seed()는 이전 하위 스토리가 남긴 상태에서 시작합니다(예: S3.2는 이미 저장된 일부 항목을 시드). 각 하위 스토리를 독립적으로 검토할 수 있습니다.
    • 메모. 각 하위 스토리에 적용되는 범위 외 항목, 가정 및 질문을 제공합니다. 사용자가 달리 말하지 않는 한 하위 스토리는 부모의 우선순위를 상속합니다.
  4. 화면 업데이트: 다른 키로 이동한 컨트롤을 다시 게이트합니다. 그런 다음 각 하위 스토리가 나열된 모든 기기에서 확인하고 부모 ID가 리디렉션되는지 확인합니다.

  5. 분할 보고를 짧은 표(하위 스토리 ID, 스토리, 우선순위, 기기, AC ID)로 작성하여 사용자가 모든 부모 AC가 어딘가에 배치되었는지 확인할 수 있도록 합니다. 사용자가 스토리를 보관하는 경우 백로그나 기능 문서에도 분할을 반영합니다.

규칙

  • 하나의 HTML 파일, 인라인 CSS/JS, 빌드 단계 없음, 프레임워크 없음, 백엔드 없음. 디스크에서 직접 엽니다.
  • 모든 데이터는 하나의 공유 인메모리 state에 있습니다. 모든 기기가 읽고 씁니다.
  • 렌더 함수는 기기 ID를 받아 state에서 다시 그립니다(셸 참조).
  • 가상의 중립적인 샘플 데이터를 사용합니다. 다른 프로젝트의 이름, 브랜드 또는 콘텐츠를 프로토타입에 복사하지 마십시오.
  • 모바일 프레임은 동일한 앱 마크업을 렌더링합니다. Android와 iPhone의 차이는 크롬(상태 표시줄, 노치/아일랜드, 제스처 바)일 뿐, 별도의 앱이 아닙니다. 사용자가 플랫폼별 UI를 요청하지 않는 한.

관련 스킬