SaaS 론칭 체크리스트 534개 항목이 80개 서비스 분석, 12개 가이드라인, 5개 실전 실패 사례에서 도출된 과정과 항목별 우선순위(P0–P3) 결정 로직 기록
배경: 코드 밖에서 론칭이 밀린다
SaaS를 만들 때 코드는 전체의 절반 정도입니다. 나머지 절반은 개인정보처리방침, 결제 webhook의 멱등성 처리, OG 이미지 설정, 환불 정책 문서화, HTTP 보안 헤더 설정 같은 항목입니다. 코드를 작성하는 능력과는 별개의 영역이고, 대부분 “존재를 알아야 할 수 있는” 종류의 작업입니다.
WICHI(GEO 분석 SaaS) 상용화 과정에서 이 문제를 직접 겪었습니다. 기능 개발은 2주 만에 끝났지만 론칭까지 추가로 3주가 더 걸렸습니다. 원인은 코드 품질이 아니라, 코드 밖의 요구사항을 몰랐기 때문입니다.
이 글은 그 3주의 삽질이 어떻게 534개 항목의 체크리스트가 되었는지를 기록합니다. 수집 과정, 분류 기준, 카테고리 설계, 품질 관리 방법, 그리고 534라는 숫자가 어디서 수렴했는지까지 포함합니다.
시작은 7개의 메모였습니다
WICHI 상용화 과정에서 빠뜨린 항목을 고치면서, 동시에 적기 시작했습니다. 노션 페이지 하나에 불렛 리스트로.
처음 7개:
- 개인정보처리방침 작성
- 이용약관 작성
- 에러 모니터링 연동 (Sentry)
- 결제 webhook 멱등성 처리
- sitemap.xml + robots.txt 추가
- 입력 검증을 백엔드로 이동
- OG 이미지 설정
WICHI에서 실제로 빠뜨렸던 것들입니다. 고치는 데 각각 반나절도 안 걸렸는데, 존재를 몰라서 론칭이 3주 밀렸습니다.
이 7개 항목은 서로 관련이 없습니다. 법률 문서, 결제 인프라, SEO, 보안, 모니터링이 뒤섞여 있습니다. 공통점은 단 하나: 코드를 작성하는 과정에서는 자연스럽게 떠오르지 않는 항목이라는 것입니다. 기능 개발에 집중하면 보이지 않고, 론칭 직전이나 론칭 직후에야 발견됩니다.
7개를 적고 나니 “이것만은 아닐 텐데”라는 생각이 들었습니다. 그래서 체계적으로 찾아보기 시작했습니다.
수집 과정 — 3단계
전체 수집 과정은 경험, 리서치, 체계화의 세 단계로 진행되었습니다. 각 단계의 성격이 뚜렷하게 다릅니다.
graph LR
subgraph S1["1단계: 직접 경험"]
A1["WICHI 삽질 목록"]
A2["~50개"]
end
subgraph S2["2단계: 공개 자료"]
B1["YC, Indie Hackers,<br/>HN, Product Hunt"]
B2["~200개 추가"]
end
subgraph S3["3단계: 체계화"]
C1["OWASP, GDPR,<br/>Web Vitals, WCAG"]
C2["~280개 추가"]
end
S1 -->|"이것만은 아닐 텐데"| S2
S2 -->|"불렛으로는 관리 불가"| S3
S3 --> D["534개 / 15 카테고리"]
| 단계 | 소요 기간 | 수집 방법 | 결과 항목 수 | 누적 |
|---|---|---|---|---|
| 1단계: 직접 경험 | 3주 (WICHI 론칭 기간) | 실제 실패 → 수정 기록 | ~50 | 50 |
| 2단계: 공개 자료 | 2주 | 커뮤니티 포스트, 가이드 수집 | ~200 | 250 |
| 3단계: 체계화 | 3주 | 프레임워크 매핑, 갭 분석 | ~284 | 534 |
1단계: 직접 경험 (~50개)
WICHI를 만들면서 직접 겪은 항목들입니다. 이전 글에서 다룬 6개 카테고리(법적 고지, 결제, 보안, 모니터링, SEO, 기타)에서 추출했습니다.
이 단계의 특징은 실제로 빠뜨려서 문제가 발생한 항목이라는 것입니다. 이론적으로 필요하다고 판단한 게 아니라, 빠뜨린 결과를 직접 경험한 항목들입니다.
발견 패턴별 분류
50개 항목의 발견 경위를 분류하면 네 가지 패턴이 나옵니다.
| 패턴 | 비율 | 설명 | 예시 |
|---|---|---|---|
| 사용자 리포트 | ~35% | 실제 사용자 또는 베타 테스터가 문제를 알려줌 | ”화면이 하얘요” DM, “privacy policy 어디 있나요?” |
| 외부 서비스 경고 | ~25% | Google, Stripe 등 외부 플랫폼이 문제를 감지 | Search Console sitemap 경고, Stripe dispute 알림 |
| 셀프 테스트 | ~20% | 직접 서비스를 사용하면서 발견 | 모바일 레이아웃 붕괴, 프롬프트 인젝션 성공 |
| 연쇄 발견 | ~20% | 하나를 고치다가 같은 카테고리에서 추가로 발견 | 결제 webhook 고치다가 환불 처리 누락 발견 |
구체적 사례: WICHI에서 빠뜨린 것들
| 출처 | 항목 예시 | 발견 계기 | 수정 시간 | 론칭 영향 |
|---|---|---|---|---|
| 결제 장애 | webhook 멱등성 | 테스트 중 크레딧 이중 충전 발생 | 3시간 | 결제 기능 2일 지연 |
| 사용자 제보 | 에러 페이지 | ”화면이 하얘요” DM 수신 | 1시간 | 사용자 이탈 |
| 법무 검토 요청 | 개인정보처리방침 | ”privacy policy가 어디 있나요?” 질문 | 반나절 | 법적 리스크 |
| SEO 감사 | robots.txt, sitemap | Google Search Console 등록 시 경고 | 2시간 | 검색 노출 지연 |
| 보안 테스트 | 프롬프트 인젝션 | 직접 테스트 중 LLM 지시 변경 성공 | 반나절 | 보안 취약점 |
| 모바일 확인 | 반응형 깨짐 | 폰으로 접속했더니 레이아웃 붕괴 | 2시간 | UX 결함 |
| 결제 플로우 | 환불 정책 부재 | webhook 수정 중 관련 문서 확인 | 반나절 | Stripe dispute 리스크 |
| 인증 플로우 | 비밀번호 리셋 | ”비밀번호를 잊어버렸는데 리셋이 안 돼요” | 4시간 | 사용자 잠금 |
각 항목의 수정 시간은 대부분 반나절 이내입니다. 기술적으로 어려운 작업이 아닙니다. 문제는 “해야 한다는 걸 아는 것”입니다.
50개 항목의 총 수정 시간은 약 80시간이었습니다. 3주에 걸쳐 분산되었습니다. 하나도 빠뜨리지 않았다면 1주 안에 끝낼 수 있는 분량이었습니다. 차이는 순전히 발견 시점입니다.
WICHI 특수 항목: LLM 기반 서비스의 추가 요구사항
WICHI는 LLM을 사용하는 GEO 분석 서비스이므로, 일반 SaaS에는 없는 항목들이 추가로 필요했습니다.
- 프롬프트 인젝션 방어 (사용자 입력이 LLM 지시를 변경하지 못하도록)
- LLM API 호출 비용 상한 설정 (사용자 한 명이 과도한 비용을 발생시키지 않도록)
- LLM 응답의 할루시네이션 경고 표시
- API 키 로테이션 및 환경변수 관리
- LLM 서비스 장애 시 폴백(fallback) 처리
이 항목들은 나중에 3단계에서 “조건부 항목”으로 분류됩니다. 모든 SaaS에 해당하는 건 아니지만, LLM을 사용하는 서비스라면 반드시 확인해야 합니다.
2단계: 공개 자료 수집 (~200개 추가)
직접 경험만으로는 범위가 제한적입니다. WICHI는 B2B SaaS이므로 B2C에 해당하는 항목(예: 소셜 로그인, 리뷰 시스템)은 빠져 있었습니다. 그래서 다른 빌더들의 경험을 수집했습니다.
출처별 특성과 수집 결과
| 출처 | 유형 | 추출 항목 수 | 강점 | 약점 |
|---|---|---|---|---|
| YC Launch Checklist | 공식 가이드 | ~30 | 체계적, 검증됨 | 고수준. “결제를 붙여라” 수준 |
| Indie Hackers 포스트 | 커뮤니티 경험담 | ~50 | 실패 사례 중심, 구체적 | 솔로 빌더 편향, 재현 어려움 |
| Hacker News “Ask HN” | 스레드 | ~40 | ”론칭 때 뭘 빠뜨렸나” 류, 다양한 스택 | 의견 분산, 검증 안 됨 |
| Product Hunt 론칭 복기 | 블로그 | ~30 | 론칭 당일 문제 중심 | SEO/OG에 편중 |
| SaaS Checklist (GitHub) | 오픈 리스트 | ~25 | 기존 체크리스트의 합집합 | 유지보수 안 되는 경우 많음 |
| Dev.to / Medium | 기술 포스트 | ~25 | 특정 카테고리 딥다이브 | 광고성 포스트 혼재 |
graph TB
subgraph SOURCES["수집 출처"]
direction LR
S1["공식 가이드<br/>(YC, Google)"]
S2["커뮤니티<br/>(IH, HN, PH)"]
S3["오픈소스<br/>(GitHub lists)"]
S4["기술 블로그<br/>(Dev.to, Medium)"]
end
subgraph FILTER["필터링 기준"]
F1["SaaS 범용 적용 가능?"]
F2["실행 가능한 수준?"]
F3["기존 항목과 중복?"]
end
subgraph RESULT["결과"]
R1["200개 추가"]
R2["~80개 제외"]
end
S1 --> F1
S2 --> F1
S3 --> F2
S4 --> F2
F1 --> F3
F2 --> F3
F3 -->|통과| R1
F3 -->|탈락| R2
출처별 발견한 대표 항목
YC Launch Checklist에서:
YC 가이드는 고수준 항목이 많아서 그대로 가져오기보다 분해해서 사용했습니다. 예를 들어 “Set up billing”이라는 하나의 항목은 다음과 같이 분해됩니다:
- Stripe Checkout 또는 결제 페이지 구현
- 결제 성공/실패/취소 각 경로 처리
- webhook 서명 검증
- webhook 멱등성 보장
- 구독 상태와 접근 권한 동기화
- 환불 정책 문서화 및 페이지 게시
- 영수증 자동 발행
하나의 고수준 항목이 7개의 실행 가능한 항목이 됩니다. 이 분해 패턴은 3단계에서 본격적으로 적용합니다.
Indie Hackers에서:
Indie Hackers 포스트의 가치는 “실패 사례”에 있습니다. 성공 사례보다 실패 사례가 체크리스트에 더 유용합니다. “이걸 해서 잘 됐다”보다 “이걸 안 해서 망했다”가 필수 항목을 식별하는 데 정확합니다.
반복적으로 등장하는 패턴:
- “결제를 붙이고 나서야 환불 정책이 없다는 걸 알았다”
- “첫 고객이 비밀번호 리셋을 요청했는데 기능이 없었다”
- “CDN 없이 론칭했더니 해외 사용자 로딩이 8초”
- “Stripe 계정이 분쟁(dispute)으로 동결됐다 — 환불 정책이 없어서”
- “OG 태그 없이 Product Hunt에 올렸더니 공유 카드가 깨져 보였다”
Hacker News “Ask HN” 스레드에서:
HN 스레드는 다양한 기술 스택의 빌더들이 모이기 때문에 특정 프레임워크에 편향되지 않는 항목을 발견할 수 있었습니다. 특히 보안, 인프라, 법률 관련 항목은 HN 댓글에서 가장 많이 얻었습니다.
GitHub 오픈 리스트에서:
기존 SaaS 체크리스트를 GitHub에서 10개 이상 확인했습니다. 대부분 한 가지 카테고리(보안 또는 SEO)에 특화되어 있거나, 고수준 항목만 나열한 상태였습니다. “모든 카테고리를 실행 가능한 수준으로” 커버하는 체크리스트는 없었습니다. 일부는 수년간 업데이트가 없어서 현재 기술 스택에 맞지 않는 항목이 포함되어 있었고, 일부는 특정 프레임워크(Rails, Django)에 종속된 항목을 범용인 것처럼 나열하고 있었습니다.
| 기존 체크리스트 유형 | 발견 개수 | 문제점 |
|---|---|---|
| 보안 특화 | 4개 | OWASP 기반이지만 SaaS 범용 아님. 인프라 보안에 치중 |
| SEO 특화 | 3개 | 기술 SEO만 다루고 마케팅 인프라, 소셜 미리보기 빠짐 |
| 범용 론칭 | 2개 | 고수준. “결제 추가” 수준에서 끝남. 실행 불가능 |
| 특정 스택 한정 | 3개 | ”Rails 론칭 체크리스트” 등. 프레임워크 전환 시 무용 |
이 분석에서 얻은 결론: 기존 체크리스트의 가장 큰 문제는 “깊이”가 아니라 “일관성”이었습니다. 보안만 상세하고 법률은 한 줄이거나, SEO는 상세한데 접근성은 아예 없거나. 빌더가 실제로 론칭 전에 확인해야 하는 항목을 전 영역에 걸쳐 일관된 깊이로 제공하는 자료가 없었습니다.
추가하지 않은 항목: 제외 기준
수집 과정에서 약 80개의 항목을 의도적으로 제외했습니다. 제외 기준은 세 가지입니다.
| 제외 기준 | 설명 | 예시 | 제외 항목 수 |
|---|---|---|---|
| 마케팅/성장 전략 | 론칭 체크리스트가 아니라 성장 플레이북의 영역 | ”론칭 전 이메일 뉴스레터를 만들어라”, “Product Hunt 론칭 전략 수립” | ~30 |
| 비즈니스 모델 의존적 | 특정 비즈니스 모델에서만 유효 | ”마켓플레이스 수수료 구조 설계”, “어필리에이트 프로그램 구축” | ~25 |
| 확인 불가 | ”했다/안 했다”로 판단할 수 없는 항목 | ”사용자 경험을 개선한다”, “브랜드 이미지를 확립한다” | ~25 |
제외 판단이 가장 어려웠던 카테고리는 마케팅과 성장 전략 사이의 경계선이었습니다. “Google Search Console에 사이트를 등록한다”는 론칭 체크리스트 항목입니다. 하지만 “키워드 리서치를 수행한다”는 성장 전략입니다. 차이는 “없으면 론칭 자체가 불완전한가?”입니다. Search Console 미등록은 검색 인덱싱이 안 되므로 론칭 결함입니다. 키워드 리서치 미수행은 검색 유입이 적을 수 있지만 론칭 자체를 가로막지는 않습니다.
같은 논리로 “환불 정책 문서화”는 포함하지만 “고객 응대 매뉴얼 작성”은 제외합니다. 환불 정책이 없으면 Stripe dispute 시 계정이 동결될 수 있지만, 응대 매뉴얼이 없어도 당장은 문제가 안 됩니다.
제외 기준의 핵심: “이 항목이 없으면 론칭이 실패하거나 지연되는가?” 답이 “아니오”면 제외합니다. 체크리스트의 가치는 포함된 항목이 아니라, 포함되지 않은 항목에서 결정됩니다. 모든 걸 넣으면 아무도 안 읽습니다.
3단계: 체계화 (~280개 추가)
항목이 250개를 넘어가니 불렛 리스트로는 관리가 안 됐습니다. 검색도 안 되고, 중복 여부도 확인이 어렵고, 우선순위 판단도 불가능했습니다.
이 시점에서 방향을 바꿨습니다. 항목을 추가하는 게 아니라, 기존 항목을 산업 표준 프레임워크에 매핑하기 시작했습니다.
매핑에 사용한 프레임워크
graph TB
subgraph FRAMEWORKS["매핑에 사용한 프레임워크"]
F1["OWASP Top 10<br/>웹 보안 취약점"]
F2["GDPR / CCPA<br/>개인정보보호 규정"]
F3["WCAG 2.1<br/>웹 접근성 지침"]
F4["Core Web Vitals<br/>성능 지표"]
F5["12-Factor App<br/>클라우드 네이티브 원칙"]
end
subgraph RESULT["매핑 결과"]
R1["기존 항목 구조화"]
R2["누락 항목 발견"]
R3["카테고리 분류 기준 확보"]
end
F1 --> R1
F2 --> R2
F3 --> R2
F4 --> R1
F5 --> R3
| 프레임워크 | 매핑 대상 카테고리 | 기존 항목 중 커버 비율 | 새로 발견한 항목 수 |
|---|---|---|---|
| OWASP Top 10 | Security, Auth | ~40% | ~65 |
| GDPR / CCPA | Legal, Email | ~30% | ~45 |
| WCAG 2.1 | Accessibility, Frontend | ~20% | ~55 |
| Core Web Vitals | Performance, Frontend | ~50% | ~35 |
| 12-Factor App | Backend, DevOps, CI/CD | ~35% | ~50 |
| Google SEO Guide | SEO & Marketing | ~45% | ~35 |
매핑 과정: 고수준 항목의 분해
이 과정에서 “원래 있었지만 명시하지 않았던” 항목들이 대량으로 드러났습니다. 패턴은 동일합니다: 하나의 고수준 항목을 프레임워크 기준으로 풀면 여러 개의 실행 가능한 항목이 됩니다.
예시 1: “HTTP Security Headers”
원래 “보안 헤더를 설정하라”는 하나의 항목이었습니다. OWASP 기준으로 풀면:
- [ ] Content-Security-Policy 헤더 설정
- [ ] X-Content-Type-Options: nosniff 설정
- [ ] X-Frame-Options: DENY (또는 SAMEORIGIN) 설정
- [ ] Referrer-Policy: strict-origin-when-cross-origin 설정
- [ ] Permissions-Policy로 브라우저 기능 제한
- [ ] Strict-Transport-Security (HSTS) + includeSubDomains 설정
1개가 6개가 됩니다.
예시 2: “쿠키 동의”
“쿠키 동의를 구현하라”는 1개 항목이 GDPR 요건에 맞추면:
- [ ] 쿠키 동의 배너 구현
- [ ] 쿠키를 카테고리별로 분류 (필수, 분석, 마케팅)
- [ ] 카테고리별 옵트인/옵트아웃 허용
- [ ] 동의 설정 저장 및 이후 요청에 반영
- [ ] 동의 전에는 추적 스크립트를 로딩하지 않음
1개가 5개가 됩니다.
예시 3: “인증 구현”
“로그인/회원가입을 구현하라”는 1개 항목이 OWASP Auth 가이드에 맞추면:
- [ ] 이메일/비밀번호 인증 구현
- [ ] OAuth 소셜 로그인 구현 (Google, GitHub 등)
- [ ] 이메일 인증(verification) 플로우
- [ ] 비밀번호 강도 요구사항 (최소 길이, 복잡도)
- [ ] 일회용 이메일 차단 (필요시)
- [ ] 중복 계정 탐지 (같은 이메일, 다른 provider)
- [ ] 환영 이메일 발송
- [ ] 로그인 실패 시 계정 잠금
- [ ] 모든 로그인 시도 로깅 (IP, User Agent)
- [ ] "비밀번호 찾기" 시간 제한 토큰
- [ ] 비밀번호 리셋 요청 rate limiting
- [ ] 리셋 완료 시 사용자 알림
- [ ] 세션 전략 선택 (JWT vs 서버 사이드)
- [ ] 토큰 만료 시간 설정
- [ ] Refresh token rotation
- [ ] "모든 기기에서 로그아웃" 기능
1개가 16개가 됩니다.
이런 식으로 고수준 항목을 실행 가능한 단위로 분해하니 항목 수가 급격히 늘었습니다.
분해 비율: 프레임워크별 확장 배수
| 프레임워크 | 분해 전 (고수준) | 분해 후 (실행 가능) | 평균 확장 배수 |
|---|---|---|---|
| OWASP Top 10 | 10 | 65 | 6.5x |
| GDPR/CCPA | 8 | 45 | 5.6x |
| WCAG 2.1 | 10 | 55 | 5.5x |
| Core Web Vitals | 6 | 35 | 5.8x |
| 12-Factor App | 12 | 50 | 4.2x |
평균적으로 하나의 고수준 항목은 약 5개의 실행 가능한 항목으로 분해됩니다.
교차 검증과 중복 제거
프레임워크 매핑 후 중복이 대량 발생했습니다. 예를 들어:
- “모든 입력을 서버 사이드에서 검증한다”가 OWASP (Injection 방어)와 12-Factor App (서버 사이드 로직) 양쪽에서 나옵니다
- “데이터를 암호화한다”가 GDPR (전송 중 암호화)과 OWASP (데이터 노출 방지) 양쪽에서 나옵니다
- “에러 로깅”이 모니터링, 보안, DevOps 세 카테고리에서 나옵니다
중복 제거 원칙은 간단합니다: 항목이 가장 자연스럽게 속하는 카테고리 하나에만 배치합니다. “입력 검증”은 Security에, “데이터 암호화”는 Security에, “에러 로깅”은 Monitoring에 배치했습니다. 다른 카테고리에서는 참조로만 언급합니다.
중복 제거 전 총 항목 수는 약 620개였습니다. 중복 제거 후 534개로 줄었습니다. 약 14%가 중복이었습니다.
우선순위 할당
모든 항목에 우선순위를 부여했습니다. 기준은 두 가지: “빠뜨리면 론칭이 불가능한가?”와 “빠뜨리면 론칭 후 문제가 발생하는가?”
| 우선순위 | 기준 | 항목 비율 | 예시 |
|---|---|---|---|
| P0 (필수) | 이것 없이는 론칭 불가 | ~25% (약 134개) | 결제 처리, 인증, 개인정보처리방침 |
| P1 (중요) | 론칭 후 1주 내 문제 발생 가능 | ~35% (약 187개) | 에러 모니터링, 비밀번호 리셋, 환불 정책 |
| P2 (권장) | 품질/성장에 영향 | ~30% (약 160개) | 접근성, SEO 최적화, 성능 튜닝 |
| P3 (조건부) | 특정 스택/기능에만 해당 | ~10% (약 53개) | i18n, MFA, 특정 결제 provider |
15개 카테고리 구조
최종적으로 15개 카테고리, 3개 그룹으로 정리했습니다.
graph TB
subgraph BUILD["제품 구축 (198개)"]
B1["01 Frontend<br/>35개"]
B2["02 Backend<br/>46개"]
B3["03 Auth<br/>42개"]
B4["04 Billing<br/>36개"]
B5["11 Testing<br/>39개"]
end
subgraph LAUNCH["출시 준비 (194개)"]
L1["08 SEO & Marketing<br/>58개"]
L2["09 Legal<br/>35개"]
L3["06 Security<br/>35개"]
L4["10 Performance<br/>38개"]
L5["12 CI/CD<br/>28개"]
end
subgraph OPS["운영 (182개)"]
O1["07 Monitoring<br/>35개"]
O2["14 Analytics<br/>33개"]
O3["13 Email<br/>30개"]
O4["15 Accessibility<br/>39개"]
O5["05 DevOps<br/>45개"]
end
15개 카테고리 전체 정의
| # | 카테고리 | 그룹 | 항목 수 | 핵심 질문 | 참조 프레임워크 |
|---|---|---|---|---|---|
| 01 | Frontend | 제품 구축 | 35 | UI가 모든 상태에서 올바르게 동작하는가? | — |
| 02 | Backend | 제품 구축 | 46 | API가 안정적이고 확장 가능한가? | 12-Factor App |
| 03 | Auth | 제품 구축 | 42 | 인증/인가가 안전하고 완전한가? | OWASP Auth |
| 04 | Billing | 제품 구축 | 36 | 결제 플로우가 안전하고 법적으로 준수하는가? | PCI DSS (간접) |
| 05 | DevOps | 운영 | 45 | 인프라가 안정적이고 복구 가능한가? | 12-Factor App |
| 06 | Security | 출시 준비 | 35 | 알려진 취약점이 모두 방어되었는가? | OWASP Top 10 |
| 07 | Monitoring | 운영 | 35 | 문제가 발생하면 즉시 알 수 있는가? | — |
| 08 | SEO & Marketing | 출시 준비 | 58 | 검색 엔진과 소셜에서 발견 가능한가? | Google SEO Guide |
| 09 | Legal | 출시 준비 | 35 | 법적 요구사항을 충족하는가? | GDPR, CCPA |
| 10 | Performance | 출시 준비 | 38 | 사용자 경험을 저해하는 성능 병목이 없는가? | Core Web Vitals |
| 11 | Testing | 제품 구축 | 39 | 코드 변경이 기존 기능을 깨뜨리지 않는가? | — |
| 12 | CI/CD | 출시 준비 | 28 | 배포가 안전하고 반복 가능한가? | — |
| 13 | 운영 | 30 | 이메일이 정확하게 전달되는가? | — | |
| 14 | Analytics | 운영 | 33 | 사용자 행동을 측정하고 있는가? | — |
| 15 | Accessibility | 운영 | 39 | 모든 사용자가 서비스를 이용할 수 있는가? | WCAG 2.1 |
왜 이 15개인가: 카테고리 결정 과정
15개라는 숫자는 임의로 정한 게 아닙니다. 두 가지 제약 조건의 교차점에서 결정되었습니다.
제약 1: 하나의 세션에서 하나의 카테고리를 처리할 수 있는 크기
카테고리가 너무 크면 (예: “Backend + DevOps + CI/CD”를 하나로) 한 세션에 끝낼 수 없습니다. 카테고리가 너무 작으면 (예: “HTTP Headers”를 독립 카테고리로) 관리 오버헤드가 늘어납니다.
적정 범위는 카테고리당 25–58개 항목입니다. 이 범위에서 카테고리를 나누면 자연스럽게 15개가 됩니다.
제약 2: 카테고리 간 의존성이 최소화되는 경계
카테고리를 나누는 기준은 “다른 카테고리와 독립적으로 작업할 수 있는가”입니다. 예를 들어:
- Auth와 Security는 밀접하지만, Auth를 작업할 때 Security 전체를 볼 필요는 없습니다
- Frontend와 Performance는 겹치지만, 성능 최적화는 별도 세션으로 진행하는 게 효율적입니다
- Legal과 Email은 쿠키 동의/옵트아웃에서 겹치지만, 각각 독립적으로 체크 가능합니다
처음에는 12개 카테고리로 시작했습니다. Email과 Analytics가 각각 Monitoring과 합쳐져 있었고, Accessibility가 Frontend에 포함되어 있었습니다. 하지만 항목이 늘어나면서 이 세 영역을 독립 카테고리로 분리하는 게 더 명확했습니다.
분리 판단의 구체적 근거:
- Email 분리: Monitoring에 포함시켰을 때 항목이 65개를 넘어갔습니다. Email은 전달률(deliverability), SPF/DKIM 설정, 템플릿 관리 등 모니터링과는 성격이 다른 항목이 대부분이었습니다. 독립시키니 Monitoring 35개, Email 30개로 각각 관리 가능한 크기가 되었습니다.
- Analytics 분리: Monitoring과 합쳐져 있었지만, 에러 추적(Monitoring)과 사용자 행동 분석(Analytics)은 목적이 다릅니다. “서비스가 고장났는가?”를 확인하는 것과 “사용자가 어떻게 사용하는가?”를 추적하는 것은 다른 세션에서 작업합니다. 분리 후 각각 35개, 33개로 정리되었습니다.
- Accessibility 분리: Frontend에 포함시켰을 때 키보드 내비게이션, 스크린 리더 호환, 색 대비, ARIA 라벨 등 접근성 항목만 39개였습니다. Frontend 자체 항목 35개와 합치면 74개로, 한 세션에 처리하기엔 과도했습니다. WCAG 2.1이라는 명확한 참조 프레임워크가 있다는 점도 독립 카테고리의 근거가 되었습니다.
제품 구축 — 코드를 작성하는 영역 (198개)
| 카테고리 | 항목 수 | 핵심 섹션 | 참조 프레임워크 |
|---|---|---|---|
| Frontend | 35 | UI 상태, 폼 검증, 반응형, 에러 상태, 로딩 UX | — |
| Backend | 46 | API 설계, 데이터 모델, 에러 처리, 로깅, 페이지네이션 | 12-Factor App |
| Auth | 42 | 인증/인가, 세션, MFA, 비밀번호 리셋, 소셜 로그인 | OWASP Auth |
| Billing | 36 | 결제, 구독, webhook, 환불, 세금, 영수증 | PCI DSS (간접) |
| Testing | 39 | 단위, 통합, E2E, 접근성 테스트, 테스트 커버리지 | — |
이 그룹에서 가장 항목이 많은 건 **Backend (46개)**입니다. API 설계, 데이터 모델, 에러 처리, 로깅, 캐싱, 큐 처리 등 서버 사이드의 범위가 넓기 때문입니다. Auth(42개)가 근소하게 뒤따르는데, 인증 플로우의 분기(회원가입, 로그인, 소셜 로그인, 비밀번호 리셋, MFA)가 각각 별도 항목군을 형성하기 때문입니다.
출시 준비 — 코드 밖의 체크 (194개)
| 카테고리 | 항목 수 | 핵심 섹션 | 참조 프레임워크 |
|---|---|---|---|
| SEO & Marketing | 58 | 메타 태그, 사이트맵, OG, 구조화 데이터, 분석 도구 | Google SEO Guide |
| Legal | 35 | 개인정보처리방침, 약관, 쿠키, GDPR/CCPA | GDPR, CCPA |
| Security | 35 | OWASP Top 10, HTTP 헤더, 입력 검증, API 보안 | OWASP Top 10 |
| Performance | 38 | Core Web Vitals, 이미지 최적화, 캐시, CDN, 번들 크기 | Web Vitals |
| CI/CD | 28 | 파이프라인, 환경 분리, 롤백, 시크릿 관리 | — |
이 그룹에서 가장 항목이 많은 건 **SEO & Marketing (58개)**입니다. 메타 태그, 구조화 데이터, 소셜 공유, 분석 도구 연동, Search Console 등록, i18n SEO, OG 이미지까지 “검색에서 발견되기 위한” 항목이 예상보다 많습니다. 코드를 한 줄도 안 쓰지만 론칭 성공에 직접 영향을 미치는 영역입니다.
운영 — 론칭 이후 유지 (182개)
| 카테고리 | 항목 수 | 핵심 섹션 | 참조 프레임워크 |
|---|---|---|---|
| Monitoring | 35 | 에러 추적, 업타임, 로그 집계, 알림 채널 | — |
| Analytics | 33 | 이벤트 추적, 퍼널 분석, 전환 측정, 대시보드 | — |
| 30 | 트랜잭션 메일, 템플릿, 전달률, 옵트아웃, SPF/DKIM | — | |
| Accessibility | 39 | 키보드 내비게이션, 스크린 리더, 색 대비, ARIA | WCAG 2.1 |
| DevOps | 45 | 인프라, 환경변수, 백업, 스케일링, 로그 로테이션 | 12-Factor App |
이 그룹에서 가장 항목이 많은 건 **DevOps (45개)**입니다. 인프라 설정, 환경 분리, 백업, 모니터링 인프라, 스케일링 전략, 인시던트 대응 등 “서비스가 죽지 않게 하는” 항목이 집중됩니다.
카테고리 설계 원칙
원칙 1: 독립적으로 체크 가능한 단위
카테고리를 나누는 기준은 다른 카테고리와 독립적으로 작업할 수 있는가였습니다.
보안을 점검하면서 동시에 결제를 확인할 필요는 없습니다. 하지만 Auth를 작업하면서 Security를 함께 보면 빠뜨리는 게 줄어듭니다.
카테고리 간 의존성 맵:
| 카테고리 | 강한 연관 | 약한 연관 |
|---|---|---|
| Auth | Security | Backend, Email |
| Billing | Legal | Backend, Email |
| SEO & Marketing | Frontend | Analytics, Performance |
| DevOps | CI/CD | Monitoring, Backend |
| Legal | Auth, Billing |
강한 연관이 있는 카테고리 쌍은 같은 세션에서 함께 작업하면 효율적이지만, 반드시 함께 작업해야 하는 건 아닙니다.
원칙 2: 게이트 체크리스트 vs 블루프린트
MMU에는 두 종류의 체크리스트가 있습니다. 이 구분이 중요합니다.
graph LR
subgraph GATE["게이트 체크리스트"]
G1["15~20개 항목"]
G2["통과/실패 판정"]
G3["마일스톤 전환 기준"]
end
subgraph BLUEPRINT["블루프린트"]
B1["20~58개 항목"]
B2["구현 깊이 가이드"]
B3["카테고리별 상세"]
end
GATE -->|"통과 후"| NEXT["다음 마일스톤"]
BLUEPRINT -->|"구현 중 참조"| CODE["코드 작업"]
GATE -.->|"extends"| BLUEPRINT
| 게이트 체크리스트 | 블루프린트 | |
|---|---|---|
| 목적 | 단계 전환 가능 여부 판정 | 구현 수준 가이드 |
| 깊이 | 고수준 (15–20개) | 상세 (20–58개) |
| 사용 시점 | 마일스톤 전환 전 | 구현 작업 중 |
| 예시 | ”결제가 작동하는가?" | "webhook 서명 검증, 멱등성, 환불 처리…” |
| 실패 시 | 다음 단계 진행 불가 | 품질 저하, 기술 부채 |
| 파일 위치 | docs/checklists/ | docs/blueprints/ |
게이트 체크리스트가 “이 단계를 넘어가도 되는가?”를 판단하고, 블루프린트가 “이 카테고리에서 구체적으로 뭘 해야 하는가?”를 알려줍니다.
MMU의 6단계 게이트 구조:
| 게이트 | 이름 | 핵심 질문 | 게이트 항목 수 |
|---|---|---|---|
| M0 | Problem Fit | 누구를 위해, 왜 만드는가? | 4 |
| M1 | Build Fit | 핵심 기능이 end-to-end로 작동하는가? | 5 |
| M2 | Revenue Fit | 결제가 가능하고 환불이 가능한가? | 4 |
| M3 | Trust Fit | 법적 문서, 지원 채널, 로깅이 있는가? | 4 |
| M4 | Growth Fit | 검색에서 발견 가능한가? 공유 링크가 올바른가? | 4 |
| M5 | Scale Fit | 새벽 3시에 장애가 나면 어떻게 되는가? | 5 |
원칙 3: 실행 가능한 항목만
체크리스트의 각 항목은 “확인했다/안 했다”로 판단 가능한 수준으로 작성합니다.
# 나쁜 예: 추상적, 판단 기준 모호
- [ ] 보안을 강화한다
- [ ] 사용자 경험을 개선한다
- [ ] 성능을 최적화한다
# 좋은 예: 구체적, 실행/확인 가능
- [ ] Content-Security-Policy 헤더를 설정한다
- [ ] 모든 사용자 입력을 서버 사이드에서 검증한다
- [ ] 파일 업로드 시 타입, 크기를 제한하고 멀웨어를 스캔한다
- [ ] Lighthouse 성능 점수 90 이상 달성
- [ ] LCP(Largest Contentful Paint) 2.5초 미만
“보안을 강화한다”는 체크할 수 없습니다. “CSP 헤더를 설정한다”는 체크할 수 있습니다. 이 차이가 체크리스트의 실용성을 결정합니다.
항목 작성 테스트: 모든 항목은 다음 질문을 통과해야 합니다.
| 테스트 | 질문 | 통과 기준 |
|---|---|---|
| 이진 판정 | ”했다/안 했다”로 답할 수 있는가? | Yes |
| 실행 단위 | 한 사람이 하나의 세션에서 완료할 수 있는가? | Yes |
| 검증 가능 | 완료 여부를 제3자가 확인할 수 있는가? | Yes |
| 독립성 | 다른 항목에 의존하지 않고 단독 실행 가능한가? | 대부분 Yes |
원칙 4: 한 방향 의존성
카테고리 간 참조가 필요한 경우, 의존성의 방향을 하나로 고정합니다. 예를 들어:
- Auth 블루프린트에서 Security 항목을 참조할 수 있지만, Security 블루프린트에서 Auth 항목을 참조하지는 않습니다
- Billing에서 Legal(환불 정책)을 참조하지만, Legal에서 Billing의 구현 세부사항을 참조하지는 않습니다
- 게이트 체크리스트에서 블루프린트를 참조하지만, 블루프린트에서 게이트를 참조하지 않습니다
이렇게 하면 어떤 카테고리를 먼저 작업해도 순환 의존이 생기지 않습니다. 빌더가 자신의 우선순위에 따라 순서를 정할 수 있습니다.
원칙 5: 조건부 항목 시스템
534개 항목 중 약 100개는 조건부(<!-- if:flag -->)로 마킹되어 있습니다. 모든 SaaS에 해당하지 않는 항목입니다.
| 조건 플래그 | 해당 항목 수 | 설명 |
|---|---|---|
has_billing | ~25 | Stripe/결제 기능을 사용하는 경우 |
has_i18n | ~15 | 다국어 지원을 하는 경우 |
has_mfa | ~8 | MFA를 구현하는 경우 |
targets_eu | ~12 | EU 사용자를 대상으로 하는 경우 (GDPR) |
targets_california | ~6 | 캘리포니아 사용자 대상 (CCPA) |
has_file_upload | ~10 | 파일 업로드를 허용하는 경우 |
has_llm | ~8 | LLM/AI 기능을 사용하는 경우 |
has_native_mobile | ~12 | 네이티브 모바일 앱이 있는 경우 |
mmu init 시 스택 설정(.mmu/config.toml)에 따라 해당 플래그가 자동 설정되고, 해당되지 않는 항목은 점수 계산에서 제외됩니다.
품질 관리: 534개가 535개가 되지 않는 이유
체크리스트는 항목이 늘어나기 쉽습니다. “이것도 있으면 좋겠다”는 생각이 들 때마다 추가하면 금방 1000개가 됩니다. 아무도 읽지 않는 체크리스트가 됩니다.
추가 기준: 포함 조건
새 항목을 추가하려면 다음 네 가지를 모두 충족해야 합니다.
- 론칭 관련성: 이 항목이 없으면 론칭이 실패하거나, 론칭 후 1개월 내 문제가 발생하는가?
- 실행 가능성: “했다/안 했다”로 판단 가능한가?
- 범용성: 전체 SaaS의 50% 이상에 해당하는가? (아니면 조건부로)
- 비중복성: 기존 항목과 실질적으로 같은 내용이 아닌가?
네 기준 중 가장 판단이 어려운 건 3번 범용성입니다. “비밀번호 리셋 플로우”는 거의 모든 SaaS에 해당하므로 명확합니다. 하지만 “TOTP 기반 MFA 구현”은 B2B SaaS에서는 필수에 가까운 반면 개인 프로젝트에서는 과도합니다. 이런 항목은 조건부로 분류해서 해당 플래그가 켜진 프로젝트에서만 활성화합니다.
범용성 판단에 사용한 기준은 “Indie Hackers에서 월 MRR $1,000 이상인 SaaS 50개를 무작위로 골랐을 때, 이 항목이 필요한 서비스가 25개 이상인가?”였습니다. 정확한 통계가 아니라 경험 기반의 추정이지만, 경계선상의 항목을 걸러내는 데는 충분히 유용했습니다.
제거 기준: 삭제 조건
기존 항목도 주기적으로 검토합니다. 다음 중 하나에 해당하면 삭제 또는 병합합니다.
- 프레임워크/라이브러리가 기본으로 처리하는 항목 (예: Next.js가 기본으로 X-Frame-Options을 설정하는 경우)
- 다른 항목에 사실상 포함되는 항목 (예: “비밀번호를 해시한다”는 “Auth 프로바이더를 설정한다”에 포함)
- 론칭 이후 6개월이 지나야 의미가 있는 항목 (체크리스트가 아니라 운영 가이드의 영역)
- 기술 발전으로 더 이상 수동 설정이 불필요한 항목 (예: 대부분의 호스팅이 자동 HTTPS를 제공하는 현재, “SSL 인증서 설치”는 별도 항목이 아님)
실제로 3단계 체계화 과정에서 제거된 항목의 사례:
| 제거된 항목 | 제거 사유 | 대체/병합 위치 |
|---|---|---|
| SSL 인증서를 설치한다 | Vercel, Netlify 등이 자동 처리 | DevOps의 “HTTPS 강제 리다이렉트” 항목에 흡수 |
| 비밀번호를 bcrypt로 해시한다 | Auth 프로바이더가 처리 | Auth의 “프로바이더 설정” 항목에 포함 |
| jQuery를 최신 버전으로 업데이트한다 | 현대 프레임워크에서는 해당 없음 | 삭제 |
| 데이터베이스 인덱스를 생성한다 | 너무 구체적이며 스키마에 의존 | Backend의 “쿼리 성능 검증” 항목에 포함 |
체크리스트의 가치는 “포함된 항목의 수”가 아니라 “포함되지 않은 항목에 대한 판단”에서 결정됩니다. 534개가 535개가 되지 않도록 지키는 것이, 534개를 만드는 것보다 어렵습니다.
기존 체크리스트와의 차이
“SaaS 체크리스트”는 이미 존재합니다. GitHub에서 검색하면 수십 개가 나옵니다. MMU가 다른 점 세 가지:
1. 깊이
기존 체크리스트 대부분은 고수준 항목을 나열합니다. “결제를 붙여라”, “보안을 점검하라”, “SEO를 설정하라”. 이건 “해야 할 일의 목록”이지 “체크리스트”가 아닙니다.
| 구분 | 기존 체크리스트 | MMU |
|---|---|---|
| 결제 | ”Set up billing” (1개) | webhook 서명 검증, 멱등성, 환불 처리, 구독 상태 동기화… (36개) |
| 보안 | ”Secure your app” (1개) | CSP 헤더, HSTS, 입력 검증, rate limiting, API 키… (35개) |
| SEO | ”Add meta tags” (1개) | title, description, canonical, OG, sitemap, robots.txt, 구조화 데이터, hreflang… (58개) |
2. 실행 가능성
모든 항목이 “했다/안 했다”로 판단 가능합니다. 추상적인 지침이 아닙니다.
3. 조건부 적용
프로젝트 스택에 따라 해당되지 않는 항목을 자동으로 제외합니다. i18n을 안 하는 프로젝트에 hreflang 항목을 보여주지 않습니다. EU 대상이 아닌 서비스에 GDPR 데이터 접근권 워크플로우를 강제하지 않습니다. 이 조건부 시스템 덕분에 534개 항목이 부담이 아니라, “내 프로젝트에 해당하는 항목만” 필터링되어 보입니다.
기존 체크리스트 대부분은 “이 중에서 해당하는 것만 골라서 하세요”라고 합니다. 문제는 초보 빌더가 “어떤 것이 해당하는지”를 판단하기 어렵다는 것입니다. 조건부 시스템은 이 판단을 스택 설정으로 대체합니다. 빌더는 “내 프로젝트에 결제가 있는가?”만 답하면 됩니다. 나머지는 시스템이 필터링합니다.
항목 수 534개의 의미: 수렴 과정
534는 계획한 숫자가 아닙니다. 3단계 체계화 과정에서 “새로 발견되는 항목”과 “중복 제거되는 항목”이 균형을 이루는 지점에서 멈춘 숫자입니다.
수렴 과정:
| 시점 | 총 항목 수 | 주간 추가 | 주간 제거 | 순증 |
|---|---|---|---|---|
| 3단계 1주차 | 320 | 70 | 0 | +70 |
| 3단계 2주차 | 450 | 80 | 12 | +68 |
| 3단계 3주차 (중복 제거) | 530 | 45 | 35 | +10 |
| 3단계 4주차 | 538 | 12 | 16 | -4 |
| 최종 정리 | 534 | 3 | 7 | -4 |
3주차부터 “새 항목 추가”와 “기존 항목 제거/병합”이 거의 같은 속도로 발생했습니다. 4주차에는 순증이 마이너스로 전환되었습니다. 이 시점에서 수집을 멈췄습니다.
534개가 많아 보이지만, 하나의 SaaS에 534개가 전부 해당되지는 않습니다.
- i18n을 안 하는 프로젝트는 관련 항목 ~15개를 건너뜁니다
- Stripe을 안 쓰는 프로젝트는 Stripe-specific 항목 ~10개를 건너뜁니다
- B2B SaaS는 소셜 로그인, 리뷰 시스템 등 B2C 항목을 건너뜁니다
- EU 대상이 아닌 프로젝트는 GDPR 항목 ~12개를 건너뜁니다
실제로 WICHI에 해당하는 항목은 약 430개 정도였습니다. 나머지 약 100개는 조건부(<!-- if:flag -->) 마커로 표시되어 있어서, 스택 설정에 따라 자동으로 제외됩니다.
534가 “마법의 숫자”인 건 아닙니다. 완전성(completeness)이 수렴한 지점일 뿐입니다. 새 항목을 추가해도 기존 항목과 겹치거나 범용성 기준에 미달하는 시점에서 멈춘 것입니다.
범용성 — 80%는 공통 항목
534개 항목 중 WICHI에만 해당하는 건 약 20%입니다. GEO 분석 특화 항목(멀티엔진 쿼리, LLM 응답 파싱 등)이 여기에 해당합니다.
나머지 80%는 SaaS를 만드는 사람이라면 누구나 확인해야 하는 공통 항목입니다.
“비밀번호 리셋 플로우가 있는가?”
“결제 webhook에 서명 검증이 있는가?”
“개인정보처리방침에 서드파티 서비스 목록이 있는가?”
“404 페이지가 커스텀되어 있는가?”
“환불 정책이 명시되어 있는가?”
이런 질문은 WICHI든, 프로젝트 관리 도구든, 이커머스 플랫폼이든 동일하게 적용됩니다.
범용 항목과 프로젝트 특수 항목의 분포:
| 카테고리 | 범용 비율 | 조건부 비율 | 프로젝트 특수 |
|---|---|---|---|
| Frontend | 90% | 10% | — |
| Backend | 85% | 10% | 5% |
| Auth | 75% | 20% | 5% |
| Billing | 70% | 25% | 5% |
| SEO & Marketing | 80% | 15% | 5% |
| Security | 95% | 5% | — |
| Legal | 60% | 35% | 5% |
| Performance | 90% | 5% | 5% |
| DevOps | 85% | 10% | 5% |
| 전체 평균 | ~80% | ~15% | ~5% |
Security가 범용 비율 95%로 가장 높습니다. 보안 항목은 거의 모든 SaaS에 해당합니다. Legal이 60%로 가장 낮습니다. GDPR, CCPA 등 지역별 규정 항목이 조건부로 분류되기 때문입니다.
다음 글에서
이 체크리스트를 나만 쓸 이유가 없었습니다. 왜 오픈소스로 공개하기로 했는지, 그리고 왜 웹 대시보드 SaaS가 아니라 CLI로 만들었는지는 다음 글에서 이야기합니다.
관련 글

코드는 됐는데 나머지가 안 됐다
기능 구현(12%) 이후 론칭까지 추가로 소요된 3주간의 작업(결제 안정성, 보안, 법적 문서, SEO 등)을 통해 '코드 완료'와 '제품 완료'의 차이를 분석

왜 오픈소스로 만들었나 — 체크리스트를 닫으면 안 되는 이유
MMU를 유료 SaaS 대시보드가 아닌 MIT 오픈소스 CLI로 공개한 이유 분석. 1인 빌더의 워크플로우(터미널 중심)와 비용 구조(구독 피로도)를 고려한 결정 과정, 그리고 'What(무료)-How(유료)-Auto(SaaS)'로 이어지는 3단계 수익 모델 설계 및 검증 지표 정리.

Self-Tuning Loop 직접 만들기 — 레퍼런스 구현 가이드
Self-Tuning Loop 4단계(Generate → Capture → Analyze → Evolve)를 범용 모듈로 추출. Supabase DDL, diff 캡처 유틸, 분석/진화 프롬프트 전문, 이메일/블로그 적용 예시, GitHub 레퍼런스 구현.