replica-architect
replica/recon.md와 replica/features.csv를 읽습니다. replica/architecture.md를 작성합니다 (템플릿: 이 폴더의 architecture.md).
리콘 맵이 없으면 중단하고 먼저 /replica-recon을 실행하세요. 앱이 하는 일을 기억만으로 클론을 계획하는 것은 절반을 놓치는 지름길입니다.
1단계: 스택
사용자가 이미 스택을 가지고 있다면 그 스택을 사용하세요. 그렇지 않으면 기본값을 사용합니다. 모든 부분이 관리되고, 문서화되어 있으며, 사용자가 없을 때 비용이 저렴하기 때문입니다:
| 계층 | 기본값 | 대체 가능 |
|---|---|---|
| 웹 앱 | Next.js (App Router) + TypeScript | Remix, SvelteKit, Rails |
| 스타일링 | Tailwind, replica-design의 토큰 | CSS modules |
| 모바일 | Expo (React Native) | SwiftUI, Kotlin |
| 데이터베이스 | Supabase 또는 Neon의 Postgres | PlanetScale, SQLite (Turso) |
| ORM | Drizzle 또는 Prisma | raw SQL |
| 인증 | Supabase Auth 또는 Auth.js | Clerk |
| 결제 | Stripe Checkout + Billing | Lemon Squeezy, Paddle |
| 이메일 | Resend 또는 Postmark | SES |
| 작업 | Vercel Cron, Inngest 또는 Trigger.dev | Fly의 worker |
| 파일 | Supabase Storage 또는 Cloudflare R2 | S3 |
| 호스팅 | Vercel | Netlify, Fly, Render |
각 선택에 대해 한 줄로 이유를 작성하세요. 하나의 데이터베이스. 마이크로서비스 없음. 클론은 원본의 아키텍처가 아니라 원본의 기능이 필요합니다.
2단계: 스키마
추론된 데이터 모델을 SQL로 변환합니다. 모든 테이블에 대해:
id uuid primary key default gen_random_uuid(),created_at,updated_at- 사용자가 소유하는 모든 항목에 소유자 컬럼 (
user_id또는org_id) - 기본값이 아닌 결정된
on delete규칙이 있는 외래 키 - 모든 외래 키와 필터링 또는 정렬하는 모든 컬럼에 인덱스
- 상태 필드에 대한 enum 또는 check 제약 조건
- 시간은 항상
timestamptz, UTC로 저장 - 금액은 정수 센트 + 통화 컬럼
- 접근 규칙: Supabase의 Postgres 행 수준 보안, 또는 데이터 계층의 쿼리당 하나의 인가 검사. 어떤 것을 사용할지 작성하세요.
예시, 예약 앱의 경우:
create table bookings (
id uuid primary key default gen_random_uuid(),
event_type_id uuid not null references event_types(id) on delete cascade,
host_id uuid not null references users(id) on delete cascade,
start_at timestamptz not null,
end_at timestamptz not null,
guest_name text not null,
guest_email text not null,
guest_timezone text not null,
status text not null default 'confirmed'
check (status in ('confirmed','cancelled','rescheduled')),
answers jsonb not null default '{}',
created_at timestamptz not null default now(),
constraint no_zero_length check (end_at > start_at)
);
create index on bookings (host_id, start_at);
그런 다음 리콘이 찾은 하드 제약 조건을 추가합니다. 두 명의 게스트가 같은 슬롯을 예약하는 것은 데이터베이스 문제(배타 제약 조건 또는 고유 인덱스)이지 UI 문제가 아닙니다.
3단계: API
리콘 맵의 각 흐름에 대해 하나의 테이블을 사용합니다. 모든 라우트 또는 서버 액션에 대해:
메서드 경로 | 기능 | 호출 가능한 사용자 | 입력 | 출력 | 흐름
또한 수신 웹훅 (Stripe, 캘린더 제공자) 및 발신 웹훅, 그리고 백그라운드 작업 (알림, 동기화, 정리)을 스케줄과 함께 포함합니다.
사용자 자신의 키를 사용하는 공식 공개 API만 사용하세요. 브라우저에서 보이더라도 원본 앱의 비공개 엔드포인트는 절대 사용하지 마세요.
4단계: 까다로운 부분
해당되는 각 항목에 대해 한 줄씩 작성하세요: 시간대 및 일광 절약 시간, 멱등성 (웹훅이 두 번 도착함), 경쟁 조건, 속도 제한, 파일 크기 제한, 검색, 실시간, 오프라인, 이메일 전달 가능성, 멀티 테넌시, GDPR 삭제.
5단계: 빌드 순서
- 수직 슬라이스. 핵심 루프를 처음부터 끝까지, 투박하게: 가입, 한 가지 작업 수행, 결과 확인. 스택을 입증합니다.
- 필수 기능
features.csv에서 영역별로. - 있으면 좋은 기능, 그 다음 있으면 더 좋은 기능.
- 수정 사항 replica-entrepreneur가 실행된 후 찾은 것.
각 마일스톤은 해당 화면 (S-ID), 테이블 및 라우트를 나열합니다.
출력
replica/architecture.md, replica/schema.sql의 SQL (또는 첫 번째 마이그레이션), 그리고 요약: 스택 한 줄, 테이블 수, 라우트 수, 가장 위험한 세 부분, 그리고 다음 단계: /replica-design.