완벽보다 명확해야 한다.
디자이너가 화면을 보고 "이건 왜 이렇게 만들었지?"라고 물을 때, NOTE가 답한다. 개발자가 "이 버튼을 누르면 어떻게 되지?"라고 궁금해할 때, NOTE가 설명한다. 경영진이 "이 기능의 목적이 뭐지?"라고 질문할 때, NOTE가 근거를 제시한다.
NOTE는 단순한 주석이 아니다. 기획자의 사고 과정을 기록한 블랙박스이고, 개발자와의 비동기 커뮤니케이션 도구이며, 미래의 나에게 보내는 편지다. 잘 쓴 NOTE 하나가 회의 30분을 줄이고, 재작업 3일을 막는다.
이 장에서는 NOTE를 체계적으로 작성하는 방법과 색상으로 정보를 구조화하는 규칙을 다룬다. 기능, 상태, 데이터, 이벤트라는 4가지 유형별 작성법과 실무에서 바로 쓸 수 있는 템플릿을 제공한다.
NOTE는 목적에 따라 4가지로 분류한다. 각 유형은 고유한 질문에 답한다.
1. 기능 NOTE (Function): 무엇을 하는가?
목적: 이 요소가 존재하는 이유
사용자: 누가, 언제 사용하는가
핵심 가치: 어떤 문제를 해결하는가
예시: 장바구니 버튼의 목적
2. 상태 NOTE (State): 언제 어떻게 보이는가?
조건: 이 상태가 발생하는 경우
표시: 화면에 보이는 모습
전환: 다른 상태로 변하는 트리거
예시: Empty/Loading/Error
3. 데이터 NOTE (Data): 어떤 정보가 필요한가?
입력: 사용자가 제공하는 데이터
출력: 시스템이 보여주는 데이터
검증: 데이터의 유효성 규칙
예시: 상품 ID, 수량, 가격
4. 이벤트 NOTE (Event): 상호작용 시 무엇이 일어나는가?
트리거: 이벤트 발생 조건
액션: 시스템의 반응
결과: 최종 상태 변화
예시: 클릭 → API → UI 업데이트
기능 NOTE는 "왜"를 설명한다. 모든 UI 요소는 목적이 있어야 한다. 목적 없는 요소는 복잡도만 늘린다.
작성 템플릿
N.Function.[화면번호].[일련번호]
[요소명]
목적: [한 문장으로 핵심 기능]
대상: [주 사용자 그룹]
시나리오: [언제 사용하는지]
성공 지표: [측정 가능한 목표]
실제 예시: 장바구니 추천 상품
N.Function.P24.01
추천 상품 섹션
목적: 빈 장바구니 이탈 방지 및 추가 구매 유도
대상: 장바구니 비었거나 3개 미만 상품 보유 고객
시나리오: 장바구니 삭제 후 또는 첫 진입 시
성공 지표: 추천 클릭률 15%, 추가 구매 전환 5%
기능 NOTE 작성 원칙
한 문장 원칙: 목적은 한 문장으로. 두 문장이 필요하면 기능을 분리.
측정 가능성: "사용성 개선"이 아니라 "클릭 3회→2회 단축"
사용자 중심: "시스템이 처리한다"가 아니라 "사용자가 확인한다"
안티패턴과 개선
❌ 나쁜 예:
"이 버튼은 여러 기능을 수행하며 다양한 상황에서 유용하게 사용될 수 있는 다목적 인터페이스입니다"
✅ 좋은 예:
"상품을 장바구니에 추가. 로그인 사용자는 즉시 추가, 비로그인은 로그인 유도"
화면은 항상 완벽한 상태만 보여주지 않는다. 로딩 중일 수도, 에러가 날 수도, 데이터가 없을 수도 있다. 상태 NOTE는 이 모든 경우를 정의한다.
기본 4상태 + 확장 상태
기본 상태 (필수)
├─ Idle: 정상 상태
├─ Loading: 데이터 로딩 중
├─ Empty: 데이터 없음
└─ Error: 오류 발생
확장 상태 (선택)
├─ Disabled: 비활성화
├─ Success: 작업 성공
├─ Warning: 주의 필요
└─ Expired: 기한 만료
상태 전환 매트릭스
N.State.P24.01
장바구니 상태 전환
→ Idle | Loading | Empty | Error
Idle : - | API콜 | 전체삭제| 네트워크
Loading : 성공 | - |. 취소 | 타임아웃
Empty : 상품추가 | - | - | -
Error : 재시도 | 재시도중 | - | -
상태별 상세 정의
N.State.P24.02
Empty 상태 상세
조건: cart.items.length === 0
표시:
- 아이콘: 빈 장바구니 일러스트
- 텍스트: "장바구니가 비어있습니다"
- CTA: "쇼핑 계속하기" 버튼
- 추가: 추천 상품 4개 그리드
전환:
- 상품 추가 시 → Loading → Idle
- 페이지 이탈 시 → 유지 (세션 저장)
로딩 상태의 세분화
N.State.P24.03
로딩 단계별 처리
0-200ms: 변화 없음 (깜빡임 방지)
200ms-2s: 스켈레톤 UI
2s-5s: 스켈레톤 + "조금만 기다려주세요"
5s-10s: 스켈레톤 + "연결 상태를 확인하고 있습니다"
10s+: Error 상태로 전환
개발자가 가장 필요로 하는 정보다. 어떤 데이터를 받아서, 어떻게 가공하고, 무엇을 보여줄지 명확히 정의한다.
데이터 필드 정의
N.Data.P24.01
장바구니 아이템 데이터
{
아이디: 문자열 (필수, 고유값)
상품아이디: 문자열 (필수, 상품 ID)
상품이름: 문자열 (필수, 최대 50자)
가격: 숫자 (필수, 0 이상)
재고: 숫자 (필수, 1-99)
옵션: {
크기: 문자열 (선택, S/M/L/XL)
색상: 문자열 (선택, HEX 코드)
}
할인: {
타입: 'rate' | 'amount'
값: 숫자
}
}
입력 검증 규칙
N.Data.P24.02
수량 입력 검증
- 타입: 숫자 only
- 범위: 1-99
- 기본값: 1
- 증감 단위: 1 (버튼), 직접 입력 가능
- 검증 시점: 숫자가 바뀌었을 경우 (디바운스 500ms)
- 에러 처리:
- 0 입력: "1-99 사이 값을 입력하세요"
- 100 이상: 자동으로 99로 변경
- 문자 입력: 이전 값 유지
데이터 변환 로직
N.Data.P24.04
가격 표시 규칙
- 천 단위 콤마: 1000 → 1,000
- 원화 표시: 뒤에 "원" 붙임
- 할인가 계산:
- rate: 가격 * (1 - 할인값/100)
- amount: 가격 - 할인값
- 퍼센트: 소수점 버림
- 무료 배송: 30,000원 이상
사용자의 액션과 시스템의 반응을 시퀀스로 정의한다.
이벤트 시퀀스 다이어그램
N.Event.P24.01
장바구니 수량 변경 이벤트
1. 사용자: [+] 버튼 클릭
2. UI: 버튼 disabled + 로딩 스피너
3. API 호출
4. 성공 시:
- 수량 숫자 업데이트
- 소계 금액 업데이트 (애니메이션)
- 전체 합계 업데이트
- 버튼 enabled
5. 네트워크 중단 시: 재시도 버튼 표시
6. 실패 시:
- 이전 값 복원
- 에러 토스트 3초
- 버튼 enabled
이벤트 우선순위
N.Event.P24.02
동시 이벤트 처리
우선순위 1: 결제 진행 중 (다른 모든 액션 차단)
우선순위 2: 수량 변경 중 (해당 아이템만 잠금)
우선순위 3: 쿠폰 적용 중 (수량 변경 가능)
우선순위 4: 상품 삭제 (확인 필요)
충돌 시나리오:
- 수량 변경 중 삭제 시도 → "변경 중입니다" 토스트
- 결제 중 페이지 이탈 → "결제가 진행 중입니다" 모달
이벤트 로깅
N.Event.P24.03
분석 이벤트 (GA/Amplitude)
- add_to_cart: 상품 추가
- item_id, item_name, price, quantity
- remove_from_cart: 상품 제거
- item_id, removal_method (button/zero_quantity)
- update_quantity: 수량 변경
- item_id, old_quantity, new_quantity
- apply_coupon: 쿠폰 적용
- coupon_code, discount_amount
색상은 정보의 계층을 시각적으로 전달한다. 일관된 색상 규칙으로 NOTE의 가독성을 높인다.
우선순위 색상 체계
� 빨간색 (#FF3B30): 크리티컬
- 필수 구현 사항
- 보안/개인정보 관련
- 성능에 치명적 영향
- 법적 요구사항
� 노란색 (#FFB800): 중요
- 주요 비즈니스 로직
- UX 핵심 요소
- 데이터 검증 규칙
- 테스트 필수 항목
� 파란색 (#007AFF): 정보
- 참고 사항
- 개선 제안
- 대안 설명
- 컨텍스트 정보
⚫ 회색 (#8E8E93): 선택
- 차기 버전 고려사항
- 실험적 기능
- 낮은 우선순위
- 보류 중인 결정
상태별 색상 가이드
상태 표시 색상
├─ Success: 초록 (#34C759)
├─ Warning: 주황 (#FF9500)
├─ Error: 빨강 (#FF3B30)
├─ Info: 파랑 (#007AFF)
├─ Disabled: 회색 (#C7C7CC)
└─ Loading: 파랑 애니메이션
작성자별 역할 및 시점
기획자 : 와이어프레임 단계 -> 기능 NOTE 초안 작성
디자이너 : v0 생성 후 -> 상태 NOTE 추가 협업 (with 기획자)
개발자 : 개발 착수 전 -> 데이터/이벤트 NOTE 검토 및 주석 추가
QA : 엣지케이스 NOTE 보강 및 검증 체크리스트 수행
NOTE 리뷰 체크리스트
□ 모든 주요 요소에 기능 NOTE가 있는가?
□ 4가지 기본 상태가 정의되어 있는가?
□ 데이터 타입과 검증 규칙이 명확한가?
□ 이벤트 시퀀스에 빠진 단계가 없는가?
□ 색상 규칙을 일관되게 적용했는가?
□ 개발자가 이해할 수 있는 용어인가?
=== 장바구니 화면 NOTE 모음 ===
[기능]
N.Function.P24.01
장바구니 메인 기능
목적: 선택 상품 확인 및 구매 전 최종 검토
대상: 구매 의사 있는 모든 고객
성공 지표: 장바구니→결제 전환율 70%
[상태]
N.State.P24.01
Loading: 스켈레톤 UI (최대 2초)
Empty: 빈 장바구니 일러스트 + 추천 상품
Error: "일시적 오류" + 새로고침 버튼
Success: 체크 아이콘 1초 후 사라짐
[데이터] - 개발자가 주로 작성
N.Data.P24.01
필수: productId, name, price, quantity
선택: options, discount, gift_wrap
계산: subtotal = price * quantity - discount
API: GET /api/cart (헤더 인증 필요)
[이벤트] - 개발자와 기획자가 함께 작성
N.Event.P24.01
수량변경: onChange → debounce 500ms → API → UI 업데이트
삭제: 확인 모달 → API → 리스트에서 제거 (슬라이드 아웃)
쿠폰적용: 유효성 체크 → API → 금액 재계산
실수 1: 추상적 설명
❌ "사용자 경험을 개선하는 기능"
✅ "입력 실수 방지: 한글 입력 시 자동 영문 변환"
실수 2: 개발 용어 남발
❌ "Redux 스토어에서 dispatch하여 상태 업데이트"
✅ "수량 변경 시 전체 금액 자동 재계산"
실수 3: 불완전한 상태 정의
❌ "로딩 중에는 스피너 표시"
✅ "0-200ms: 무반응, 200ms-2s: 스피너, 2s+: 스피너+메시지"
잘 쓴 NOTE는 기획자의 존재 가치를 증명한다. 개발자는 NOTE를 보고 구현하고, 디자이너는 NOTE를 보고 개선하며, QA는 NOTE를 보고 테스트한다.
NOTE는 완벽할 필요 없다. 하지만 명확해야 한다. 짧되 충분해야 하고, 구체적이되 이해하기 쉬워야 한다.
무엇보다 NOTE는 살아있어야 한다. 한 번 쓰고 끝이 아니라, 프로젝트와 함께 진화해야 한다. 오늘 쓴 NOTE가 내일의 문제를 막고, 다음 달의 시간을 절약한다.