전문가용 시작
이 매뉴얼은 React와 TypeScript와 React Router가 일상이고, Supabase 또는 Stripe SDK를 한두 번이라도 만져본 적 있고, Claude Code 또는 Codex로 코드를 맡겨본 적 있는 독자를 가정합니다. FSD라는 이름은 들어봤다는 정도면 충분합니다. 6레이어 의존 방향과 API 어댑터, 행 수준 접근 정책(RLS)은 다음 섹션 architecture에서 설명합니다.
여기서 다루는 것은 참고용 명령 목록이 아니라 “왜 이 모양인지”에 대한 설명입니다. 뼈대가 왜 이렇게 잡혔는지 한 번 읽고 architecture로 넘어가야 그 뒤의 build-and-package와 distribution이 의미 있게 읽힙니다.
풀려는 문제 한 줄
섹션 제목: “풀려는 문제 한 줄”AI에게 SaaS를 맡기면 첫 두세 프롬프트는 멀쩡하게 나옵니다. 그다음부터 구조가 어긋나기 시작합니다. service_role 키가 클라이언트 번들로 노출되고, 같은 라우트 path 문자열이 다섯 군데에 흩어지고, 행 수준 접근 정책을 Supabase Studio에서 손으로 만들고 나면 다음 환경에서는 그 정책이 사라집니다. saas-base는 그런 곳들에 guardrail을 걸어 둔 출발점입니다.
guardrail 세 개
섹션 제목: “guardrail 세 개”FSD 6레이어 + eslint-plugin-boundaries + jsx-a11y
섹션 제목: “FSD 6레이어 + eslint-plugin-boundaries + jsx-a11y”폴더 구조는 Feature-Sliced Design을 따르고, eslint-plugin-boundaries가 빌드 시점에 import 방향을 강제합니다. AI가 임의로 레이어를 가로지르면 빌드가 실패합니다. jsx-a11y가 같은 단계에서 접근성 위반을 함께 막습니다. alt 가 빠진 <img>, 라벨 없는 <input>이 여기서 걸러집니다.
API 어댑터 기준 문서
섹션 제목: “API 어댑터 기준 문서”src/shared/api/server/에 어댑터 전략이 들어 있습니다. 기본값은 Supabase Edge Functions (supabase.functions.invoke(...))입니다. 선택지로는 Hono on Node 또는 Cloudflare 어댑터가 있습니다. features 슬라이스는 어떤 어댑터인지 모르는 채로 같은 인터페이스를 호출합니다. 어댑터 결정이 .claude/state/api-adapter.json에 한 번 기록된 다음에는 호출 코드를 바꾸지 않고 백엔드 런타임만 바꿀 수 있습니다.
행 수준 접근 정책 기준 문서
섹션 제목: “행 수준 접근 정책 기준 문서”모든 행 수준 접근 정책은 api/migrations/<timestamp>_<name>.sql에서 정의합니다. Supabase Studio의 화면에서 정책을 만들지 않습니다. git 추적이 안 되고 환경 사이에 차이가 생기기 때문입니다. supabase db push가 같은 SQL을 어떤 환경에든 동일하게 적용합니다.
ADR 습관
섹션 제목: “ADR 습관”되돌리기 비싼 결정은 docs/adr/에 한 장씩 쌓습니다. 라우팅 모드를 왜 marketing-app으로 정했는지, API 어댑터를 edge-functions로 정한 근거는 무엇인지, 가격 플랜을 monthly와 annual로 나눈 결정은 어땠는지를 남깁니다. 코드는 무엇을 했는지를 보여주고, ADR은 왜 그랬는지를 보여줍니다. 다음 세션 또는 다음 사람이 들어왔을 때 결과만 보고 의도를 거꾸로 추론하는 비용을 아낍니다.
ADR 양식과 작성 시점은 docs/adr/README.md에 짧게 정리돼 있습니다.
자동화 진입점은 한 곳을 가리킨다
섹션 제목: “자동화 진입점은 한 곳을 가리킨다”Claude Code 쪽 진입점은 .claude/agents/와 .claude/skills/입니다. Codex 쪽 진입점은 저장소 루트의 AGENTS.md입니다. 두 경로 모두 결국 같은 파일 하나를 읽습니다.
바로 AI_AUTOMATION.md입니다. 도메인 규칙과 FSD 슬라이스 매핑, SaaS 금지 패턴, 여섯 관점 리뷰 체크리스트, Phase 1~6 흐름이 전부 여기 모여 있습니다. 두 자동화 도구의 진입점이 한 canonical 문서를 공유하기 때문에, Claude Code에서 내린 결정이 Codex 세션에서도 그대로 통합니다.
지금 빠져 있는 것
섹션 제목: “지금 빠져 있는 것”이 base는 솔직히 미완성인 부분이 있습니다. 매뉴얼과 랜딩 페이지는 공개돼 있지만, 템플릿 자체는 상업 라이선스 모델입니다. 그런데 결제 흐름과 구매자 webhook이 아직 연결되지 않았습니다. COMMERCIAL-LICENSE.md도 초안 상태이고 변호사 검토가 끝나지 않았습니다. 실제 판매 전에는 둘 다 마무리해야 합니다.
기술 쪽에도 빠진 것이 있습니다. saas-base의 src/는 phase 5(/5-customize-saas) 이전까지는 자리 표시 값 수준의 골격만 들어 있습니다. 사용자가 본인 SaaS를 채우기 전까지는 라우트 트리도, 도메인 entity도, 행 수준 접근 정책도 실제 코드가 아닙니다. 이 매뉴얼이 가르치는 것은 그 빈 골격이 phase 흐름을 거치며 어떻게 채워지는지에 대한 절차이지, saas-base 자체의 참고용 코드가 아닙니다.
이 매뉴얼이 가정하지 않는 것
섹션 제목: “이 매뉴얼이 가정하지 않는 것”운영체제별 설치 분기, Node 버전 매니저 선택, Supabase 또는 Stripe 계정 만들기 화면 캡처, 터미널이 처음인 사람을 위한 단계별 안내는 여기 없습니다. 그쪽이 필요하면 비개발자용 매뉴얼을 봅니다. 같은 base를 다른 방식으로 설명한 한 쌍입니다.
다음 섹션은 architecture입니다. FSD 6레이어가 어떤 의존 방향으로 묶여 있는지, 라우트 기준 문서와 Supabase client 기준 문서가 코드에서 어떻게 생겼는지, Stripe Checkout 3단 분리가 어떻게 도는지를 다이어그램 두 개와 함께 봅니다.