この記事は、ひとりでつくるSaaS - 設計・実装・運用の記録 Advent Calendar 2025 の23日目の記事です。
昨日の記事では「マルチテナントSaaSの設計」について書きました。この記事では、Claude Codeを使った開発の実践について紹介します。
Claude Codeの基本的な使い方は、公式ドキュメントや他の記事で詳しく解説されています。この記事では、私が個人開発で実践している進め方や、使い続ける中で気づいたことを中心に書いています。
参考ドキュメント
🛠️ 建築現場のイメージで進める
Claude Codeとの開発を続ける中で、建築現場のイメージで進めるとうまくいくことに気づきました。
1. 設計図を描く(要件定義)
2. 足場を組む(基本/詳細設計)
3. 建てる(実装)
4. 壁に「なぜこう建てたか」の理由を書く(コメント、README、CLAUDE.md)
5. 足場を解体(設計書を実装に統合)
設計図を描く(要件定義)
最初にやるのは、「何を作るか」を明確にすることです。
## 機能概要
ユーザーが学習コンテンツを作成・管理できる機能
## ユースケース
- コンテンツの作成・編集・削除ができる
- 一覧画面で自分のコンテンツを確認できる
- Markdown形式で本文を記述できる
## 制約
- 他テナントのコンテンツは見えない
- タイトルは必須、本文は任意
この設計図をClaude Codeに渡すことで、AIは全体像を理解した上でコードを生成できます。
足場を組む(基本/詳細設計)
要件が決まったら、次は「どう作るか」を決めます。具体的には、ファイル構成や処理フローを日本語で整理します。
## ファイル構成
- src/types/content.ts - 型定義
- src/app/api/contents/route.ts - APIエンドポイント
- src/client/components/ContentForm.tsx - 入力フォーム
## APIエンドポイント
### GET /api/contents
- 認証チェック
- tenant_idでフィルタ
- 更新日時の降順で返す
### POST /api/contents
- 認証チェック
- バリデーション(title必須、bodyは任意)
- DBに保存して作成したレコードを返す
この設計書があると、Claude Codeは「何をどう実装すればいいか」を理解しやすくなります。
建てる(実装)
足場ができたら、実装です。ここがClaude Codeの本領発揮です。
src/app/api/contents/route.ts を実装してください。
以下の仕様に従ってください:
- GET: tenant_idでフィルタしてコンテンツ一覧を返す
- POST: 新規コンテンツを作成
- エラーハンドリングは既存の src/app/api/labels/route.ts を参考に
既存コードを参考にさせると、プロジェクト内の一貫性が保たれます。
理由を書く
実装が終わったら、「なぜこう実装したか」をコメントやREADMEで残します。
// RLSに加えてアプリケーション層でもtenant_idをチェック
// 万が一RLSの設定漏れがあった場合の多層防御として
const contents = await db
.select()
.from(contentsTable)
.where(eq(contentsTable.tenantId, tenantId));
この記録は、将来の自分やAIが「なぜこうなっているのか」を理解するのに役立ちます。
足場を解体
最後に、設計書の内容を実装に統合します。一時的なTODOコメントを削除し、型定義を整理し、不要になった仕様書を片付けます。
これは「Contextの汚染を防ぐ」ためでもあります。古い設計書や仮のコメントが残っていると、AIがそれを読んで混乱することがあります。ソースコードをSingle Source of Truth(信頼できる唯一の情報源)にすることで、AIの誤読を減らせます。
💬 CLAUDE.mdによる文脈共有
Claude Codeでは、プロジェクトルートにCLAUDE.mdを置くと、AIがプロジェクトの文脈を理解してくれます。
# プロジェクト概要
Memoreru - 知識を整理し、思考を育てるツール
# 技術スタック
- Next.js 15 (App Router)
- TypeScript 厳密モード
- Drizzle ORM + PostgreSQL (Supabase)
- Hono (API)
- shadcn/ui
# コーディング規約
- 関数コンポーネントを使用
- Named exportを優先
- エラーハンドリングは Result型 パターン
# ディレクトリ構成
src/
├── app/ # Next.js App Router
├── client/ # クライアントサイドロジック
├── server/ # サーバーサイドロジック
├── database/ # DB スキーマ・クエリ
└── shared/ # 共通ユーティリティ
これを一度書いておくと、毎回説明する必要がなくなります。
実装パターンの明示
CLAUDE.mdには、プロジェクト固有の実装パターンも書いておくと便利です。
# APIエンドポイントのパターン
## 認証が必要なエンドポイント
1. セッションからユーザーIDを取得
2. tenant_idへのアクセス権を確認
3. RLSコンテキストを設定
4. 処理を実行
## エラーレスポンスの形式
{ error: string, code?: string }
⚡ 拡張機能の活用
Claude Codeには、MCPやSkillsといった拡張機能があります。
MCP
MCP(Model Context Protocol)は、外部ツールとの連携を可能にするプロトコルです。私が使っているのは以下の3つです。
- Playwright: ブラウザ操作、E2Eテスト
- Supabase: データベーススキーマの確認
- Serena: IDE連携
MCPは便利ですが、使いすぎるとContextを圧迫します。AIが処理する情報量が増えるため、応答速度や精度に影響することがあります。必要なものだけに絞るのがおすすめです。
Skills
Skillsは、特定のタスクに対する指示をテンプレート化する仕組みです。.claude/skills/ディレクトリにSKILL.mdファイルを置いて使います。
私はまだ本格的に活用できていませんが、チームでレビュー観点などのルールを共有するのに便利そうです。公式のSkillsマーケットプレイスも公開されています。
💡 AIとのやり取りのコツ
具体的に伝える
曖昧な指示では、期待と違う結果が返ってきます。何をどうしたいか、具体的に伝えます。
❌ 「もっといい感じにして」
✅ 「一覧の並び順を更新日時の降順にして」
段階的に依頼する
大きな機能は分割して依頼します。一度に依頼すると、途中で方向性がずれても修正が大変です。
1. まずContentsテーブルのスキーマを定義して
2. 次にCRUDのAPIエンドポイントを作って
3. 最後にフロントエンドのフォームを作って
制約を明示する
やってほしくないことも伝えておくと、意図しない変更を防げます。
以下の制約で実装してください:
- 既存のAPIレスポンス形式を変更しない
- 新しいライブラリを追加しない
- パフォーマンスより可読性を優先
過剰な実装を防ぐ
Claude Codeは後方互換性を考慮して、ロジックを複雑にしがちです。シンプルに保つための指示を明示します。
❌ AIが勝手にやりがちなこと:
- 古いAPIを残して新しいAPIを追加
- 非推奨の警告を出すラッパー関数を作成
- フィーチャーフラグで新旧を切り替え
✅ 明示的に伝える:
「後方互換性は不要です。既存コードを直接変更してください」
🧠 役割分担
半年間の開発で見えてきた、人間とAIの役割分担です。
人間が判断すること
- プロダクトの方向性: 何を作るか、何を作らないか
- アーキテクチャ: 技術選定、ディレクトリ構成
- セキュリティ: 認証・認可の設計、脆弱性チェック
- ユーザー体験: 使いやすさ、分かりやすさ
- 最終確認: 実際に動かして問題がないか
AIに任せること
- パターンに沿ったコード生成: CRUDのAPI、フォームコンポーネント
- リファクタリング: 命名統一、ディレクトリ整理
- ボイラープレート作成: 型定義、テストの雛形
- エラー調査: スタックトレースからの原因推測
AIが変えたのは「How」の部分です。「What」と「Why」は、依然として人間の仕事です。
コードレビューは必ず行う
AIが生成したコードは、必ず自分でレビューします。
- セキュリティ: ユーザーIDをリクエストから直接受け取っていないか
-
型安全性:
any型やas anyで型エラーを回避していないか - エッジケース: 配列が空の場合、nullの場合などを考慮しているか
AIは「動く」コードを生成しますが、「安全な」コードとは限りません。
この役割分担を意識するようになってから、AIとの協働がスムーズになりました。「全部任せる」のではなく「一緒に作る」という感覚です。
✅ まとめ
Claude Codeを使った開発について、私の実践を紹介しました。
| ポイント | 内容 |
|---|---|
| 建築現場のイメージ | 設計図 → 足場 → 建てる → 理由 → 解体 |
| CLAUDE.md | プロジェクトの文脈をAIに共有 |
| 拡張機能の活用 | MCP/Skills(必要最小限で) |
| やり取りのコツ | 具体的に、段階的に、制約を明示 |
| 役割分担 | How=AI、What/Why=人間、レビュー必須 |
AIは強力なツールですが、使いこなすのは人間です。「任せる」のではなく「協働する」という意識で、開発を続けています。
明日は「進捗駆動開発(PDD)」について解説します。
シリーズの他の記事
- 12/22: 個人開発でマルチテナントSaaSを作る:エンタープライズ品質への挑戦
- 12/24: 進捗駆動開発(PDD)のすすめ:AIエージェントと進める個人開発