第4章

生成AIと小さく実装する

仕様、既存コード、制約、確認方法を生成AIへ渡し、小さな差分をテストしながら実装する方法を学びます。

この章で学ぶこと

  • 生成AIへ実装を頼むための情報をそろえる
  • 画面、状態、データアクセスを分けて実装する
  • 小さな差分ごとに、確認・テスト・コミットを行う

1. 作業を縦に小さく切る

「アプリを全部作って」ではなく、利用者が体験できる細い機能を1本ずつ完成させます。

  1. 固定データでカード一覧を表示する。
  2. 作成画面からメモリ上の一覧へ追加する。
  3. 入力検証とエラー表示を追加する。
  4. Firebase Authenticationでログインする。
  5. Firestoreへ本人のカードを保存する。
  6. Security Rulesとルールのテストを追加する。
  7. 削除と再試行を追加する。

画面だけ、データベースだけを長く作るより、各段階で実際に操作できる状態を保ちやすくなります。

2. 最初のFlutterプロジェクトを作る

Flutter環境を確認し、プロジェクトを作ります。

flutter doctor
flutter create idea_pocket
cd idea_pocket
flutter run -d chrome

Androidのパッケージ名やiOSのBundle IDは公開後に変えにくいため、公開を考える段階でcom.exampleのままにしません。組織が管理する逆ドメイン形式のIDを決めます。

WebのFirebase App:   idea-pocket-web
Android applicationId: jp.example.ideapocket
iOS Bundle ID:         jp.example.ideapocket

AndroidとiOSで同じ文字列にする必要はありませんが、チームの命名規則を統一すると取り違えを減らせます。

3. 良い実装依頼の形

生成AIには、目的、現在地、制約、完了条件、確認コマンドを渡します。

目的:
  Flutterのカード一覧に、作成画面からカードを追加したい。

現在地:
  lib/main.dartに固定カードを表示している。
  関連ファイルを先に読み、既存の命名と構成を保つこと。

制約:
  この段階ではFirebaseや追加パッケージを使わない。
  保存中の二重送信を防ぐ。
  既存の変更を消さない。

完了条件:
  タイトルが空ならエラーを表示する。
  保存後に一覧へ戻り、新しいカードが見える。
  Widgetテストを追加する。

確認:
  dart format .
  flutter analyze
  flutter test

一度に多くの変更が出たら、「まずデータモデルとテストだけ」のように分割します。

4. 責務を分ける

小さなアプリでも、画面から直接すべてのFirebase APIを呼ぶとテストしにくくなります。

Widget(表示・入力)
   ↓ ユーザー操作
Controller / State(読み込み・成功・失敗)
   ↓
Repository(保存・取得・削除の抽象化)
   ├─ MemoryIdeaRepository(最初の実装・テスト)
   └─ FirestoreIdeaRepository(Firebase接続)

最小のデータモデル例です。

class Idea {
  const Idea({
    required this.id,
    required this.title,
    required this.body,
    required this.createdAt,
  });

  final String id;
  final String title;
  final String body;
  final DateTime createdAt;
}

Repositoryは画面が必要とする操作だけを定義します。

abstract interface class IdeaRepository {
  Stream<List<Idea>> watchMine();
  Future<void> create({required String title, required String body});
  Future<void> delete(String id);
}

この境界があると、生成AIへ「UIは変えずに保存先だけ置き換える」と頼みやすくなります。

5. 差分を必ず読む

生成AIが変更した後は、次を確認します。

git status
git diff --stat
git diff
dart format .
flutter analyze
flutter test

特に次の変化は見落とさないでください。

  • 依存パッケージやプラットフォーム設定が増えた
  • 認証なしでデータへアクセスするようになった
  • エラーを握りつぶして成功表示している
  • 秘密値がコードやログへ入った
  • 関係ないファイルが大量に書き換わった
  • テストを削除・スキップして通した

意味を説明できないコードは、そのまま公開しません。「この変更が必要な理由と、失敗する条件を説明して」と生成AIへ聞き、公式ドキュメントや実行結果でも確認します。

6. コミットを復帰地点にする

1つの完了条件を満たすたびにコミットします。

git add lib test pubspec.yaml
git commit -m "Add local idea creation flow"

Firebase設定、Android署名、iOS設定は別コミットにすると、問題の切り分けが容易です。秘密ファイルが含まれていないか、git diff --cachedで確認します。

やってみよう

  1. 固定データのカード一覧を実装する。
  2. 作成画面と空タイトルのWidgetテストを追加する。
  3. 生成AIに差分レビューを依頼し、「仕様違反」「セキュリティ」「テスト不足」だけを指摘させる。
  4. 自分でも差分とテスト結果を確認してからコミットする。