replica-architect
replica/recon.md と replica/features.csv を読み込みます。
replica/architecture.md を書き出します(テンプレート: このフォルダ内の architecture.md)。
もし recon マップが存在しない場合は、停止して最初に /replica-recon を実行してください。
記憶だけでアプリの機能を推測してクローンを計画すると、半分の機能を見逃すことになります。
ステップ1: スタック
ユーザーが既にスタックを持っている場合は、その知識を活用します。 そうでない場合はデフォルトを使用します。すべての部分が管理されており、ドキュメント化され、ユーザーゼロでも安価です。
| レイヤー | デフォルト | 代替候補 |
|---|---|---|
| Webアプリ | 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 | 生SQL |
| 認証 | Supabase Auth または Auth.js | Clerk |
| 決済 | Stripe Checkout + Billing | Lemon Squeezy, Paddle |
| メール | Resend または Postmark | SES |
| ジョブ | Vercel Cron, Inngest または Trigger.dev | Fly上のワーカー |
| ファイル | Supabase Storage または Cloudflare R2 | S3 |
| ホスティング | Vercel | Netlify, Fly, Render |
各選択肢について、その理由を一行で記述します。データベースは1つ。マイクロサービスは使いません。 クローンに必要なのは元のアプリのアーキテクチャではなく、元のアプリの機能です。
ステップ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行レベルセキュリティ、またはデータレイヤーでクエリごとに1回の認可チェック。どちらを使うか明記。
例(予約アプリの場合):
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);
次に、recon で見つかった厳しい制約です。2人のユーザーが同じスロットを予約するのはUIの問題ではなく、データベースの問題です(排他制約またはユニークインデックスで対処)。
ステップ3: API
recon マップのフローごとに1テーブル。各ルートまたはサーバーアクションについて:
method path | 何をするか | 誰が呼び出せるか | 入力 | 出力 | フロー
さらに、着信Webhook(Stripe、カレンダープロバイダー)、発信Webhook、およびバックグラウンドジョブ(リマインダー、同期、クリーンアップ)をスケジュールとともに記述します。
公式で公開されたAPIのみを使用し、ユーザー自身のキーを使います。たとえブラウザで見えても、元のアプリのプライベートエンドポイントは決して使いません。
ステップ4: 厄介な部分
該当するものそれぞれについて一行で記述: タイムゾーンと夏時間、冪等性(Webhookが2回届く)、競合状態、レート制限、ファイルサイズ制限、検索、リアルタイム、オフライン、メール到達性、マルチテナント、GDPRデータ削除。
ステップ5: ビルド順序
- 垂直スライス。コアループをエンドツーエンドで、見た目は悪くてよい: サインアップ、主要機能を1つ実行、結果を確認。スタックが機能することを証明します。
- Must-have(features.csv からエリア別)。
- Should-have、次に Could-have。
- 修正(replica-entrepreneur が実行後に見つけるもの)。
各マイルストーンには、その画面(S-ID)、テーブル、ルートをリストします。
出力
replica/architecture.md、replica/schema.sql のSQL(最初のマイグレーションとしても可)、および概要: スタックを一行、テーブル数、ルート数、最もリスクの高い3つの部分、そして次のステップ: /replica-design。