個人開発でも、IssueとACだけは書くことにした
前回の記事では、サービスを作るための技術スタックを決めました。 今回は、その道具を使ってどう開発を進めるかです。
個人開発で開発プロセスを決めるのは、やりすぎではないか。最初はそう思いました。 それでも、機能ごとにIssueを作り、受入条件(AC)を書くことだけは決めておくことにしました。その理由と、軽く定義した開発の流れをまとめます。 (2026年9月時点の方針です)
個人開発でもIssueとACを書く理由
ACは、Claude Codeへの指示とテストを兼ねる
開発は、Claude Codeでのバイブコーディングを基本にします。
Claudeは、与えられた情報だけを頼りに実装します。「こういう機能がほしい」とだけ伝えると、それらしいものはできても、欲しかったものと少しずれることがあります。
そこで、Issueに**受入条件(AC:Acceptance Criteria)**を書いておきます。「〜したとき、〜になる」という、機能ができたと判断するための条件です。 ACがあれば、「このIssueを実装して。ACをテストにして」と頼むだけで、指示と確認が1回で済みます。
将来の自分は、他人と同じ
作るサービスは、70歳ぐらいまで続けるつもりです。 数年後に「なぜこういう仕様にしたんだっけ」と思ったとき、Issueをたどれば理由が分かる。10年保守する前提なら、この差は大きいと考えています。
ブログの材料になる
Issueの背景欄に、迷ったことや判断の理由を書いておけば、そのまま開発記録の記事の元になります。
やらないこと
チーム開発のような重いプロセスにはしません。次のものはやらないと決めました。
- 見積もり、スプリント、ベロシティ
- 詳細な設計書
- すべてのIssueに Given/When/Then 形式を強制すること
- 細かすぎるラベル体系
Issueのテンプレート
機能追加のIssueは、次のテンプレートで書きます。
## 背景・やりたいこと
なぜ必要か。迷ったことがあればここに書く。
## 仕様
- 画面や動きの要点を箇条書きで
## 受入条件(AC)
- [ ] 〜したとき、〜になる
- [ ] 〜の場合は、〜と表示される
## 対象外
今回やらないこと(スコープが膨らむのを防ぐ)
一番効くと思っているのは、最後の**「対象外」**の欄です。 個人開発には締め切りがないので、つい「ついでにこれも」と作り込みすぎてしまいます。今回やらないことを先に書いておくと、それを防げます。
テンプレートは .github/ISSUE_TEMPLATE/ に置いておけば、Issueを作るときに自動で使われます。
書く量はIssueの種類で変える
すべてのIssueをきっちり書く必要はありません。
| 種類 | 書くもの |
|---|---|
| 機能追加 | テンプレートを全部使う |
| バグ修正 | 再現手順と、期待する動き(これがそのままACになる) |
| 小さな改善・雑務 | タイトルと一言だけでよい |
ラベルとマイルストーン
- ラベル:
feature/bug/choreの3つだけ - マイルストーン:「MVP」「ステップ1」「ステップ2」など、サービスごとの段階に対応させる
例:コンテナの一括チェック
最初に作るキャンプ道具のチェックリストアプリで、実際に書く予定のIssueです。
## 背景・やりたいこと
コンテナに入れたギアを1つずつチェックするのが手間。
コンテナを積んだら、中身がまとめてチェックされるようにしたい。
## 受入条件(AC)
- [ ] コンテナをチェックすると、中のギアが全部チェック済みになる
- [ ] コンテナのチェックを外すと、中のギアのチェックも全部外れる
- [ ] コンテナをタップすると、中身の一覧が表示される
- [ ] チェックリストには、プランに含まれるギアだけが表示される
## 対象外
- コンテナの入れ子(コンテナの中のポーチ)
ACとテストの振り分け
ACは、そのままテストにします。ただし、すべてを同じ道具でテストするわけではありません。
| 種類 | 確かめること | 道具 | 量 |
|---|---|---|---|
| ユニットテスト | 関数単体の正しさ | Vitest | 多い |
| 結合テスト | サーバー側の処理とDBを組み合わせた動き | Vitest + Workers向けテスト環境 | 中くらい |
| E2Eテスト | ブラウザで操作したときの動き | Playwright | 少数 |
振り分けのルールは単純です。
- 計算や判定のACは、Vitestでテストする
- 画面の動きのACは、Playwrightでテストする
- E2Eは、主要な操作の流れだけに絞る
上の例でいえば、「コンテナのチェック状態から中身の状態を決める」処理はVitestで、「コンテナをタップすると中身が表示される」はPlaywrightで確かめます。
E2Eは、Cloudflare Accessで保護した開発環境ではなく、CIの中で立ち上げたアプリに向けて実行します。保護された環境に向けると、ログインを突破する仕組みが必要になって面倒だからです。
家計簿アプリでは、後半にPlaywrightを入れたことで、他人のデータを操作できてしまう漏れがないかを確かめられました。個人開発でも、主要な流れだけならE2Eはやりすぎにならないと考えています。
開発の流れ
前回書いたとおり、develop ブランチは開発用アカウント、main ブランチは本番用アカウントに自動でデプロイされます。これに合わせて、開発の流れは次のようにしました。
1. Issueを作る(ACまで書く)
↓
2. develop から feature ブランチを作り、Claude Codeで実装する(ACはテストにする)
↓
3. develop 向けにPRを作る(テストが自動で走る)
↓
4. develop にマージ → 開発用アカウントに自動デプロイ
↓
5. 開発環境でアプリを触ってACを確認する(受入判断)
↓
6. develop → main のPRをマージ → 本番用アカウントに自動デプロイ
受入判断を、本番に出す前の開発環境でできるのが、環境を分けた一番の利点です。
1つ注意点があります。PRに Closes #12 のように書くとIssueが自動で閉じますが、これはデフォルトブランチ(通常は main)にマージされたときだけ動きます。develop にマージした時点で閉じたい場合は、develop をデフォルトブランチにするか、手動で閉じる必要があります。
AIとの役割分担
バイブコーディングでは、どこまでをAIに任せ、どこを自分で決めるかが大事だと思っています。今のところ、次のように分けるつもりです。
| 作業 | 人(自分) | AI(Claude Code) |
|---|---|---|
| Issueの背景・やりたいこと | 書く(一言メモでもよい) | テンプレートに沿って整える |
| AC | 最終的に決める | 候補を出す。抜けや曖昧さを指摘する |
| 実装とテスト | 確認する | 書く |
| PRの説明文 | 確認する | 書く |
| レビュー | 読んで理解してからマージする | 先にセルフレビューする |
| 受入判断 | 開発環境で触って決める | ― |
太字の3つは、人が手放さない部分です。 将来このコードを保守するのは自分です。何を作るかを決め、書かれたコードを理解し、出来上がったものを自分の目で確かめる。この3つだけは、AIに任せないことにしました。
よく使う指示はスキルにする
「Issueを読んで実装してPRまで作って」のような、何度も使う指示は、Claude Codeのスキルとして保存しておく予定です。
/issue:ざっくりしたメモから、テンプレートに沿ってIssueの下書きを作る/implement 12:Issue #12を読んで、ブランチ作成から実装・テスト・PRまで進める
どちらもGitHubにIssueやPRを作る操作なので、Claudeが勝手に動かさず、自分で呼んだときだけ動くように設定します。
また、「Issueを読んでから実装する」「ACごとにテストを書く」といった毎回守ってほしいルールは、リポジトリの CLAUDE.md に書いておきます。
最初から共通化はしない
スキルも CLAUDE.md もIssueのテンプレートも、どのサービスでも使えるものにしたい気持ちはあります。
ただ、実際に使ってみないと、どんな形がちょうど良いのかは分かりません。
そこで、最初から共通化はせず、キャンプアプリの開発の中で試行錯誤しながら育てることにしました。2つ目のサービスを作るときに、実際に役立った部分だけを共通として切り出すつもりです。
そのため、Claude Codeへの具体的な指示の出し方や、スキルの中身は、まだ書けることがありません。キャンプアプリで実際に使ってみて、うまくいったこと、ずれたことを、開発記録の中で書いていきます。
おわりに
決めたことを並べてみると、個人開発の開発プロセスとしては、これくらいがちょうど良いと思っています。
- 機能ごとにIssueを作り、ACを書く
- ACはテストにする
- 開発環境で確かめてから、本番に出す
- 何を作るか・コードの理解・受入判断は、自分で持つ
これで、「なぜ作るのか」「何を作るのか」「どう作るのか」がひと通りそろいました。 次回からは、いよいよ最初のサービス、キャンプ道具のチェックリストアプリの話に入ります。