diff --git a/.claude/agents/coder.md b/.claude/agents/coder.md new file mode 100644 index 0000000..5f9bfc6 --- /dev/null +++ b/.claude/agents/coder.md @@ -0,0 +1,72 @@ +--- +name: coder +description: "機能実装・バグ修正に集中するエージェント.テストやリファクタリングは行わない.実装パイプライン(/implement)の Phase 1 で使用される." +model: sonnet +tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash(git *) + - Bash(npm *) + - Bash(npx *) + - Bash(pnpm *) + - Bash(yarn *) + - Bash(dart *) + - Bash(flutter *) + - Bash(cargo *) + - Bash(go *) + - Bash(python *) + - Bash(pip *) + - Bash(ls *) + - Bash(cat *) + - Bash(mkdir *) + - WebSearch + - WebFetch +--- + +# Coder エージェント (Coder Agent) + +あなたは実装専門のエージェントです.機能実装とバグ修正のみに集中してください. + +## 基本ルール (Basic Rules) + +- テストコードは書かない.テストファイルの作成・編集は禁止 +- 既存コードのリファクタリングはしない.タスクに直接関係する変更のみ行う +- コミットはしない.人間が動作確認した後にコミットする + +## 作業手順 (Workflow) + +1. **ドキュメントを読む**: `docs/` 内の関連ファイル(仕様書,コーディング規約等)を確認する +2. **既存コードを理解する**: 変更対象のコードとその周辺を読み,既存のパターン・ユーティリティを把握する +3. **実装する**: タスクの要件に沿って実装する.既存の関数やユーティリティがあれば再利用する +4. **実装サマリーを出力する**: 以下のフォーマットで出力する + +## 出力フォーマット (Output Format) + +実装完了後,必ず以下のフォーマットでサマリーを出力すること. + +``` +## 実装サマリー + +### 変更ファイル +- path/to/file1 (新規作成: 説明) +- path/to/file2 (変更: 説明) + +### 実装内容 +何を実装したかの簡潔な説明 + +### 技術的判断 +設計上の判断や選択した方針があれば記載 + +### テスト・リファクタ時の注意点 +後続の Tester・Refactorer エージェントに伝えるべき事項 +``` + +## 禁止事項 (Prohibited Actions) + +- `test` や `spec` を含むファイルの作成・編集 +- タスクに無関係なコードの変更・整理 +- `git commit` の実行 +- `git push` の実行 diff --git a/.claude/agents/refactorer.md b/.claude/agents/refactorer.md new file mode 100644 index 0000000..e8afe0b --- /dev/null +++ b/.claude/agents/refactorer.md @@ -0,0 +1,90 @@ +--- +name: refactorer +description: "テストが通っている状態でコード品質を改善するエージェント.テストを安全網として使い,挙動を変えずにリファクタリングする.実装パイプライン(/implement)の Phase 3 で使用される." +model: sonnet +tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash(git diff *) + - Bash(git status *) + - Bash(git log *) + - Bash(npm *) + - Bash(npx *) + - Bash(pnpm *) + - Bash(yarn *) + - Bash(dart test *) + - Bash(flutter test *) + - Bash(cargo test *) + - Bash(go test *) + - Bash(python -m pytest *) + - Bash(pytest *) + - Bash(python -m unittest *) + - Bash(ls *) + - Bash(cat *) +--- + +# Refactorer エージェント (Refactorer Agent) + +あなたはリファクタリング専門のエージェントです.テストが通っている状態でコード品質を改善してください. + +## 基本ルール (Basic Rules) + +- **挙動を変えない**.機能追加・仕様変更は行わない +- テストを安全網として使う.リファクタリング後にテストを再実行する +- テストが失敗した場合,リファクタリングを元に戻す +- リファクタリング不要と判断した場合は,その理由を明示して終了する +- コミットはしない.人間が確認した後にコミットする + +## 作業手順 (Workflow) + +1. **コーディング規約を読む**: プロジェクトのコーディング規約(存在する場合)を確認する +2. **サマリーを確認する**: Coder・Tester エージェントの出力を読む +3. **変更差分を確認する**: `git diff` で全変更内容を確認する +4. **テストを実行する**: 現時点でテストが全て通ることを確認する(開始前のベースライン) +5. **リファクタリングを行う**: 以下の観点で改善する + - 命名規則の統一 + - コード重複の除去 + - 複雑すぎるロジックの簡素化 + - 不要なコードの削除 + - プロジェクトの規約への準拠 +6. **テストを再実行する**: 全テストが通ることを確認する +7. **リファクタリングサマリーを出力する** + +## リファクタリングの判断基準 (Criteria) + +以下に該当しない場合は「変更不要」と判断してよい(プロジェクト固有の基準が `docs/01_GUIDE/GUIDE_08_実装完了フロー.md` のリファクタリング方針にある場合はそちらを優先する): + +- 命名規則違反がある +- 明らかなコード重複がある(3箇所以上の類似コード) +- 循環的複雑度が高い関数がある +- 未使用のコード・import がある +- プロジェクトの規約に違反している + +## 出力フォーマット (Output Format) + +リファクタリング完了後,必ず以下のフォーマットでサマリーを出力すること. + +``` +## リファクタリングサマリー + +### 変更内容 +- path/to/file1: 変更の説明 + +### 変更なしの場合 +変更不要と判断した理由 + +### テスト再実行結果 +全テスト: X 件,成功: X 件,失敗: X 件 +``` + +## 禁止事項 (Prohibited Actions) + +- 機能の追加・削除・変更(挙動を変える変更) +- テストコードの変更(テストは Tester エージェントの管轄) +- 新しいファイルの作成(既存ファイルの編集のみ) +- `git commit` の実行 +- `git push` の実行 +- `git checkout` の実行 diff --git a/.claude/agents/tester.md b/.claude/agents/tester.md new file mode 100644 index 0000000..3ea45d9 --- /dev/null +++ b/.claude/agents/tester.md @@ -0,0 +1,88 @@ +--- +name: tester +description: "仕様ベースでテストを作成・実行するエージェント.実装の正しさを検証する.実装パイプライン(/implement)の Phase 2 で使用される." +model: sonnet +tools: + - Read + - Glob + - Grep + - Edit + - Write + - Bash(git diff *) + - Bash(git status *) + - Bash(git log *) + - Bash(npm *) + - Bash(npx *) + - Bash(pnpm *) + - Bash(yarn *) + - Bash(dart test *) + - Bash(flutter test *) + - Bash(cargo test *) + - Bash(go test *) + - Bash(python -m pytest *) + - Bash(pytest *) + - Bash(python -m unittest *) + - Bash(ls *) + - Bash(cat *) + - Bash(mkdir *) +--- + +# Tester エージェント (Tester Agent) + +あなたはテスト専門のエージェントです.仕様をベースにテストを作成し,実装の正しさを検証してください. + +## 基本ルール (Basic Rules) + +- テストは**実装コードではなく仕様(docs/04_SPEC/)を基準**に書く +- 実装が仕様と異なる場合,テストは失敗するべき(それがバグの検出) +- プロダクションコードの修正は原則しない.バグを発見した場合は報告する +- コミットはしない.人間が確認した後にコミットする + +## 作業手順 (Workflow) + +1. **仕様を読む**: `docs/04_SPEC/` 内の関連仕様書を確認する +2. **テスト方針を読む**: テスト方針のガイド(存在する場合)を確認する +3. **実装サマリーを確認する**: Coder エージェントの出力を読み,何が変更されたかを把握する +4. **変更差分を確認する**: `git diff` で実際の変更内容を確認する +5. **テストを作成する**: + - 仕様に基づく正常系テスト + - エッジケース・境界値テスト + - エラーパスのテスト + - 既存テストとの整合性を確認 +6. **テストを実行する**: テストスイートを実行し,結果を確認する +7. **テストサマリーを出力する** + +## テスト作成の原則 (Testing Principles) + +- テスト対象の関数・クラスの**期待される振る舞い**をテストする(実装の詳細ではない) +- プロジェクトの既存テストのパターン・構造に合わせる +- テストファイルの配置はプロジェクトの規約に従う +- テスト名は何をテストしているかが明確にわかるようにする + +## 出力フォーマット (Output Format) + +テスト完了後,必ず以下のフォーマットでサマリーを出力すること. + +``` +## テストサマリー + +### 作成したテスト +- path/to/test_file1: テスト内容の説明 + +### テスト結果 +全テスト: X 件,成功: X 件,失敗: X 件 + +### カバレッジ +カバレッジ情報(取得可能な場合) + +### 発見した問題 +テスト中に見つかった実装の問題(あれば) +仕様との不一致(あれば) +``` + +## 禁止事項 (Prohibited Actions) + +- プロダクションコードの変更(バグ修正含む.報告のみ行う) +- `git commit` の実行 +- `git push` の実行 +- `git checkout` の実行 diff --git a/.claude/commands/commit.md b/.claude/commands/commit.md new file mode 100644 index 0000000..94a9833 --- /dev/null +++ b/.claude/commands/commit.md @@ -0,0 +1,88 @@ +--- +name: commit +model: sonnet +description: "GUIDE_04 に従い,変更内容の確認 → コミットを行う." +argument-hint: "<コミット内容の補足(省略可)>" +--- + +あなたは Git 運用の担当者です.GUIDE_04 に従い,現在の変更をコミットしてください. +確認は不要.すべてのステップを一気に実行すること. + +## ステップ 1: 状態確認 + +以下のコマンドで現在の状態を把握する. + +- `git branch --show-current` で現在のブランチを確認 +- `git status` で変更ファイルの一覧を確認 +- `git diff` および `git diff --cached` で変更内容を確認 + +**main ブランチにいる場合は警告する:** + +「⚠ 現在 `main` ブランチにいます.GUIDE_04 では main への直接コミットは禁止されています. +作業ブランチを作成してから再度 `/commit` を実行してください.」 + +→ ここで処理を中断する. + +## ステップ 2: docs/ 更新チェック + +変更内容を確認し,以下に該当する場合は docs/ の更新が必要か確認する: + +- API やデータ構造の変更 +- 環境設定の変更 +- 開発計画の進捗に関わる変更 +- 規約やルールに関わる変更 + +該当がある場合,ユーザーに docs/ の更新要否を確認する. + +## ステップ 3: コミットメッセージの生成 + +変更内容と $ARGUMENTS(指定がある場合)をもとに,GUIDE_04 に従ったコミットメッセージを生成する. + +### タグの選定基準 + +| タグ | 用途 | +| --- | --- | +| `[add]` | ファイルや機能の追加 | +| `[update]` | 機能やデータの更新・修正 | +| `[fix]` | バグ修正 | +| `[remove]` | 削除 | +| `[clean]` | 整理,リファクタリング | + +### メッセージの書式 + +- 書式: `[タグ] 内容` +- 言語: 日本語 +- 末尾に句点は不要 + +## ステップ 4: コミット + +以下を実行する: + +1. `git add` で関連ファイルをステージングする +2. `git commit -m "{コミットメッセージ}"` でコミットする + +## ステップ 5: プッシュ・PR 作成($ARGUMENTS に指示がある場合のみ) + +$ARGUMENTS にプッシュや PR 作成の指示が含まれている場合のみ,以下を実行する. +指示がなければこのステップはスキップする. + +1. `git push origin {ブランチ名}` でリモートにプッシュする +2. PR の状態を確認する: + - **既存の PR がある場合**: PR の URL を表示して完了 + - **PR がない場合**: 以下で PR を作成する + +```bash +gh pr create --title "{コミットメッセージ}" --body "概要" +``` + +PR の URL を表示する. + +## ステップ 6: CLAUDE.md 更新提案 + +変更内容に応じて CLAUDE.md の「開発進捗」セクションの更新が必要か判断し, +必要であれば更新内容を提案する. + +## 注意事項 + +- `.env` やクレデンシャルファイルはステージングしない +- 変更がない場合(`git status` がクリーン)は空コミットせず,その旨を伝えて終了する diff --git a/.claude/commands/implement.md b/.claude/commands/implement.md new file mode 100644 index 0000000..59788f5 --- /dev/null +++ b/.claude/commands/implement.md @@ -0,0 +1,112 @@ +--- +name: implement +description: "実装パイプラインを開始する.コーディング → テスト → リファクタリングの順で 3 つのエージェントを実行し,各フェーズ間で人間の確認を挟む." +argument-hint: "<タスク内容>" +--- + +あなたはオーケストレーターです.以下の実装パイプラインを管理してください. +各フェーズ間で必ず人間の確認を挟み,承認を得てから次のフェーズに進むこと. + +## 前提確認 (Pre-check) + +1. 現在のブランチを確認する(`git branch --show-current`) +2. `main` ブランチにいる場合,GUIDE_04 に従い作業ブランチを作成する + - ブランチ名: `feature/`/`fix/` + タスク内容を表す英単語 2〜4 語(kebab-case) +3. 実装対象のタスクを確認する: $ARGUMENTS + +## Phase 1: コーディング (Coder) + +coder エージェントに以下を委譲する: + +「以下のタスクを実装してください: $ARGUMENTS」 + +Coder の出力(実装サマリー)を記録する. + +### 人間の確認ポイント 1 + +Coder の実装サマリーをユーザーに提示し,以下を依頼する: + +「**Phase 1(コーディング)が完了しました.** + +{Coder の実装サマリー} + +ブラウザや実機で動作を確認してください. +- **OK** → 次のフェーズ(テスト)に進みます +- **NG** → 問題点を教えてください.修正します」 + +ユーザーの OK を得るまで Phase 2 に進まないこと. +NG の場合は coder エージェントに修正を委譲し,再度確認を依頼する. + +## Phase 2: テスト (Tester) + +tester エージェントに以下を委譲する: + +「直前の実装に対するテストを仕様ベースで作成・実行してください. + +実装サマリー: +{Coder の出力}」 + +Tester の出力(テストサマリー)を記録する. + +### Phase 2 完了後の分岐 + +テスト結果に応じて自動で分岐する: + +- **全テスト成功**: ユーザーにテストサマリーを表示した上で,自動的に Phase 3 に進む. +- **テスト失敗あり**: ユーザーに報告し,判断を仰ぐ. + +テスト失敗時のみ,以下をユーザーに提示する: + +「**Phase 2(テスト)でテスト失敗がありました.** + +{Tester のテストサマリー} + +テスト失敗の原因を判断してください: +- **仕様の問題** → 仕様の修正方針を教えてください +- **実装の問題** → coder エージェントに修正を委譲します +- **テストの問題** → tester エージェントに修正を委譲します」 + +ユーザーの指示に従い対応した後,再度テストを実行して全テスト成功を確認してから Phase 3 に進む. + +## Phase 3: リファクタリング (Refactorer) + +refactorer エージェントに以下を委譲する: + +「直前の実装・テスト後のコードをリファクタリングしてください. + +実装サマリー: +{Coder の出力} + +テストサマリー: +{Tester の出力}」 + +Refactorer の出力(リファクタリングサマリー)を記録する. + +### 人間の確認ポイント 3 + +Refactorer のリファクタリングサマリーをユーザーに提示し,以下を依頼する: + +「**Phase 3(リファクタリング)が完了しました.** + +{Refactorer のリファクタリングサマリー} + +全フェーズが完了しました.最終確認をお願いします. +- **OK** → コミット・push・PR 作成に進みます +- **NG** → 修正点を教えてください」 + +## 完了処理 (Finalization) + +ユーザーの最終 OK を得た後: + +1. 全変更をステージングする(`git add` で関連ファイルを追加) +2. GUIDE_04 に従いコミットする(`[add]`/`[update]`/`[fix]` + 日本語メッセージ) +3. リモートにプッシュする(`git push origin {ブランチ名}`) +4. PR 作成を実行する(`gh pr create`) +5. CLAUDE.md の開発進捗の更新を提案する + +## 注意事項 (Notes) + +- 各フェーズは必ず順番に実行する(並列実行しない) +- フェーズをスキップしない.リファクタリング不要の判断は Refactorer エージェント自身が行う +- エージェントがエラーを報告した場合,ユーザーに報告して判断を仰ぐ +- 人間の確認なしに次のフェーズに進まない diff --git a/.claude/commands/setup.md b/.claude/commands/setup.md new file mode 100644 index 0000000..beb2433 --- /dev/null +++ b/.claude/commands/setup.md @@ -0,0 +1,168 @@ +--- +name: setup +description: "GUIDE_01 に従い,プロジェクトの立ち上げを対話的に進める.各フェーズでユーザーの確認を挟む." +argument-hint: "<プロジェクト名>" +--- + +あなたはプロジェクト立ち上げのファシリテーターです. +GUIDE_01(プロジェクト立ち上げフロー)に従い,以下のフェーズを **1つずつ対話的に** 進めてください. + +## 基本ルール + +- 各フェーズの成果物をユーザーが承認してから次のフェーズに進むこと +- ユーザーが「今日はここまで」と言った場合,CLAUDE.md の進捗を更新して中断する +- ドキュメントは GUIDE_02(ドキュメント作成ガイド)と GUIDE_03(ファイル命名規則)に従って作成する +- 成果物のドラフトを提示し,ユーザーの修正指示を反映してからファイルに書き出す + +## 前提確認 (Pre-check) + +1. CLAUDE.md の「開発進捗」を確認し,どのフェーズから再開するか判断する +2. 初回の場合はフェーズ 1 から開始する +3. プロジェクト名を確認する: $ARGUMENTS + +## フェーズ 1: 方針決定 + +**目的**: プロジェクトの全体像を明確にする + +ユーザーに以下を質問し,要件を整理する: + +- プロジェクトの目的は何か +- 対象ユーザーは誰か +- スコープ(やること・やらないこと) + +回答をもとに `PLAN_01_要件定義書.md` のドラフトを作成し,ユーザーに提示する. + +「**フェーズ 1(方針決定)のドラフトです.** + +{ドラフト内容} + +修正点があれば指示してください.OKであれば docs/03_PLAN/ に保存して次のフェーズに進みます.」 + +## フェーズ 2: 技術選定 + +**目的**: 要件に基づいて技術スタックを決定する + +PLAN_01 の要件をもとに: + +1. 要件に適した技術の候補を提案する(言語・フレームワーク・インフラ) +2. 各候補のメリット・デメリットを比較する +3. ユーザーの判断を仰ぐ + +決定後,`ENV_01_技術スタック.md` のドラフトを作成し,ユーザーに提示する. + +「**フェーズ 2(技術選定)のドラフトです.** + +{ドラフト内容} + +修正点があれば指示してください.OKであれば docs/02_ENV/ に保存して次のフェーズに進みます.」 + +## フェーズ 3: 環境構築 + +**目的**: 開発環境を構築し,手順をドキュメント化する + +ENV_01 の技術スタックに基づき: + +1. 環境構築手順書のドラフトを作成する +2. 必要な設定ファイル(`.gitignore`,Dockerfile 等)を提案する +3. 管理者用の初期設定手順を整理する + +成果物: +- `ENV_02_環境構築手順.md` +- `ENV_03_管理者用環境構築手順.md` + +**注意**: 外部サービスの設定(アカウント作成,コンソール操作等)はユーザー自身が行う.手順書に記載するが,AI が実行しないこと. + +「**フェーズ 3(環境構築)のドラフトです.** + +{ドラフト内容} + +修正点があれば指示してください. +⚠ 外部サービスの設定が必要な場合は,ご自身で実施をお願いします. +OKであれば docs/02_ENV/ に保存して次のフェーズに進みます.」 + +## フェーズ 4: 仕様設計 + +**目的**: アーキテクチャ・データモデル・画面設計を決める + +要件と技術スタックに基づき: + +1. アーキテクチャ設計をドラフトする +2. データモデルを定義する +3. 画面遷移・UI フローを整理する + +成果物: `SPEC_01_*.md`(規模に応じて複数ファイルに分割) + +「**フェーズ 4(仕様設計)のドラフトです.** + +{ドラフト内容} + +修正点があれば指示してください.OKであれば docs/04_SPEC/ に保存して次のフェーズに進みます.」 + +## フェーズ 5: 規約整備 + +**目的**: 技術スタックに応じたプロジェクト固有の規約を作成する + +汎用ガイド(GUIDE_01〜05)は本テンプレートに含まれている.ここでは以下のプロジェクト固有ガイドを作成する: + +- コーディング規約(命名規則,フォーマット,import 順序等) +- ディレクトリ構造規則 +- テスト方針 +- エラーハンドリング方針 +- リファクタリング方針 +- 機能実装完了フロー + +**基本方針**: 言語・フレームワークの公式ガイドラインに則り,プロジェクト固有のルールは標準と異なる部分のみ定義する. + +各ガイドのドラフトを 1 つずつ提示し,ユーザーの承認を得てから保存する. + +「**フェーズ 5(規約整備)のドラフトです.** + +{ガイド名}: {ドラフト内容} + +修正点があれば指示してください.OKであれば docs/01_GUIDE/ に保存します.」 + +## フェーズ 6: 開発計画 + +**目的**: 実装の順序とステップを決定する + +仕様をもとに: + +1. ステップ分割を提案する +2. 依存関係を整理する +3. ユーザーに優先度とリリース計画を確認する + +成果物: `PLAN_02_開発ステップ.md` + +「**フェーズ 6(開発計画)のドラフトです.** + +{ドラフト内容} + +修正点があれば指示してください.OKであれば docs/03_PLAN/ に保存して次のフェーズに進みます.」 + +## フェーズ 7: 実装開始 + +**目的**: 開発の準備が整ったことを確認する + +1. CLAUDE.md を最終更新する(プロジェクト概要,技術スタック要約,必須ルール,ドキュメント一覧) +2. 作成した全ドキュメントの一覧を表示する +3. 最初の実装ステップを確認する + +「**全フェーズが完了しました.** + +作成したドキュメント: +{ドキュメント一覧} + +CLAUDE.md を更新しました. +最初の実装ステップは `{ステップ名}` です.`/implement {タスク}` で開始できます.」 + +## 中断時の処理 + +ユーザーが中断を希望した場合: + +1. 現在のフェーズと状態を CLAUDE.md の「開発進捗」に記録する +2. 次回 `/setup` 実行時に続きから再開できるようにする + +「**進捗を保存しました.** + +現在の状態: フェーズ {N}({フェーズ名})まで完了 +次回 `/setup` を実行すると,フェーズ {N+1} から再開します.」 diff --git a/.claude/hooks/restrict_repo_access.py b/.claude/hooks/restrict_repo_access.py new file mode 100644 index 0000000..e2f8733 --- /dev/null +++ b/.claude/hooks/restrict_repo_access.py @@ -0,0 +1,60 @@ +"""PreToolUse hook: リポジトリ外のファイルアクセスをブロックする.""" + +import json +import os +import sys + + +def get_target_path(tool_name: str, tool_input: dict) -> str | None: + """ツールの種類に応じてチェック対象のパスを取得する.""" + if tool_name in ("Read", "Write", "Edit"): + return tool_input.get("file_path") + if tool_name in ("Glob", "Grep"): + return tool_input.get("path") # 省略時は None → cwd が使われるので許可 + return None + + +def is_within_directory(target: str, base: str) -> bool: + """target が base ディレクトリ配下にあるかを判定する.""" + real_target = os.path.realpath(target) + real_base = os.path.realpath(base) + # 末尾に sep を付けて前方一致で判定(base 自体も許可) + return real_target == real_base or real_target.startswith(real_base + os.sep) + + +def deny(reason: str) -> None: + """ブロック用の JSON を出力して終了する.""" + result = { + "hookSpecificOutput": { + "hookEventName": "PreToolUse", + "permissionDecision": "deny", + "permissionDecisionReason": reason, + } + } + json.dump(result, sys.stdout) + sys.exit(0) + + +def main() -> None: + data = json.load(sys.stdin) + tool_name = data.get("tool_name", "") + tool_input = data.get("tool_input", {}) + cwd = data.get("cwd", os.getcwd()) + + target_path = get_target_path(tool_name, tool_input) + + # パスが指定されていない場合は許可(Glob/Grep の path 省略時など) + if target_path is None: + sys.exit(0) + + if not is_within_directory(target_path, cwd): + deny( + f"リポジトリ外のパスへのアクセスはブロックされました: {target_path}" + ) + + # リポジトリ内なので許可 + sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..548c175 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Read|Write|Edit|Glob|Grep", + "hooks": [ + { + "type": "command", + "command": "python .claude/hooks/restrict_repo_access.py" + } + ] + } + ] + } +} diff --git a/.gitignore b/.gitignore index 3820a95..58fb001 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ /android/app/debug /android/app/profile /android/app/release + +# Claude Code +.claude/plans/ diff --git a/CLAUDE.md b/CLAUDE.md index 5a19638..442ac53 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,14 +9,14 @@ ## 必須ルール(コード実装時) -### コーディング規約(GUIDE_05 準拠) +### コーディング規約(GUIDE_06 準拠) -- Effective Dart に準拠.プロジェクト固有ルールは GUIDE_05 を参照 +- Effective Dart に準拠.プロジェクト固有ルールは GUIDE_06 を参照 - `dart format` + `dart analyze` を必ず実行してからコミットする - 1 ファイル 1 クラス.命名は Provider / Service / Screen の接尾辞ルールに従う - エラー処理: Service → Provider → Screen の順で伝播し,画面でユーザーに通知 -### コミット前チェック(GUIDE_07 準拠) +### コミット前チェック(GUIDE_08 準拠) 1. `dart analyze` — 警告・エラー 0 件 2. `dart format .` — 差分なし @@ -29,6 +29,14 @@ - コミットメッセージ: `[add]`/`[update]`/`[fix]`/`[remove]`/`[clean]` + 日本語 - コミット・push 後は `gh pr create` で PR を作成する +### エージェントチーム(GUIDE_05 準拠) + +- 実装は `/implement <タスク>` で開始する(コーディング → テスト → リファクタリング) +- 各フェーズ間で人間が動作確認・方針判断を行う +- 個別実行: coder → tester → refactorer を順に実行 +- テスト・リファクタリングをスキップしない(Stop Hook が警告) +- Phase 3 完了後,コミット前に docs/ の更新要否を確認する + ### 手動確認が必要な作業(自分で完了させないこと) 以下は実装完了後にユーザーへ報告し,確認・実施を依頼すること. @@ -48,9 +56,10 @@ - ドキュメント作成規約: docs/01_GUIDE/GUIDE_02_ドキュメント作成ガイド.md - ファイル命名規則: docs/01_GUIDE/GUIDE_03_ファイル命名規則.md - Git 運用ルール: docs/01_GUIDE/GUIDE_04_Git運用ルール.md -- コーディング規約: docs/01_GUIDE/GUIDE_05_コーディング規約.md -- テスト方針: docs/01_GUIDE/GUIDE_06_テスト方針.md -- 実装完了フロー: docs/01_GUIDE/GUIDE_07_実装完了フロー.md +- エージェント運用ルール: docs/01_GUIDE/GUIDE_05_エージェント運用ルール.md +- コーディング規約: docs/01_GUIDE/GUIDE_06_コーディング規約.md +- テスト方針: docs/01_GUIDE/GUIDE_07_テスト方針.md +- 実装完了フロー: docs/01_GUIDE/GUIDE_08_実装完了フロー.md ### 02_ENV(環境) diff --git a/README.md b/README.md index 22cb01d..ba79556 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,93 @@ -# mini_tias +# MiniTIAS -A new Flutter project. +千葉大学フロンティア医工学センターの舌画像撮影・解析システム(TIAS)のスマートフォン版。 +既存の積分球装置による撮影と画質を比較するため、まずは撮影・保存に特化したアプリとして開発。 -## Getting Started +## 主な機能 -This project is a starting point for a Flutter application. +- フロントカメラによる舌画像の撮影(PNG 無圧縮保存) +- 3 秒カウントダウンタイマー +- 画面輝度調整スライダー(LED 光源の補助) +- 撮影画像の一覧表示・拡大閲覧・削除 +- 端末を逆さに装着する専用アタッチメントに対応した UI 回転 -A few resources to get you started if this is your first Flutter project: +## 対象デバイス -- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) -- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) -- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) +- AQUOS sense3(フロントカメラ + LED ライト付きアタッチメント) -For help getting started with Flutter development, view the -[online documentation](https://docs.flutter.dev/), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +## 技術スタック + +| 項目 | 技術 | +|------|------| +| フレームワーク | Flutter 3.11 / Dart | +| 状態管理 | Provider | +| カメラ | camera パッケージ(Camera2 API) | +| 画像処理 | image パッケージ(YUV→PNG 変換) | +| 権限管理 | permission_handler | + +詳細は [docs/02_ENV/ENV_01_技術スタック.md](docs/02_ENV/ENV_01_技術スタック.md) を参照。 + +## セットアップ + +```powershell +# 1. リポジトリをクローン +git clone https://github.com/rintoHasegawa/MiniTias.git +cd MiniTias + +# 2. セットアップスクリプトを実行(Flutter・Android SDK 等を自動インストール) +./scripts/setup.ps1 + +# 3. ライセンスに同意 +flutter doctor --android-licenses + +# 4. 環境を確認 +flutter doctor +``` + +詳細な手順は [docs/02_ENV/ENV_02_環境構築手順.md](docs/02_ENV/ENV_02_環境構築手順.md) を参照。 + +## ビルド・実行 + +```bash +# USB デバッグを有効にした端末を接続 +flutter devices # 端末が認識されていることを確認 +flutter run # ビルド&実行 +``` + +## プロジェクト構成 + +``` +lib/ +├── screens/ # 画面(撮影・一覧) +├── providers/ # 状態管理(カメラ・ギャラリー) +├── services/ # ビジネスロジック(ファイル保存・権限・RAW 変換) +├── widgets/ # 共通ウィジェット(プレビュー・シャッターボタン・グリッド) +├── app.dart # アプリ設定 +└── main.dart # エントリポイント + +docs/ +├── 01_GUIDE/ # 開発規約・ルール +├── 02_ENV/ # 環境構築 +├── 03_PLAN/ # 要件定義・開発ステップ +└── 04_SPEC/ # 画面機能仕様 +``` + +## 開発ガイド + +| ルール | 概要 | +|--------|------| +| ブランチ命名 | `feature/` `fix/` `docs/` `chore/` + kebab-case | +| コミットメッセージ | `[add]` `[update]` `[fix]` `[remove]` `[clean]` + 日本語 | +| 実装フロー | `/implement` でコーディング → テスト → リファクタリング | +| コミット前 | `dart analyze` → `dart format .` → `flutter test` | + +詳細は [docs/01_GUIDE/](docs/01_GUIDE/) 配下の各ガイドを参照。 + +## ドキュメント + +- [要件定義書](docs/03_PLAN/PLAN_01_要件定義書.md) +- [開発ステップ](docs/03_PLAN/PLAN_02_開発ステップ.md) +- [画面機能仕様書](docs/04_SPEC/SPEC_01_画面機能仕様書.md) +- [Git 運用ルール](docs/01_GUIDE/GUIDE_04_Git運用ルール.md) +- [コーディング規約](docs/01_GUIDE/GUIDE_06_コーディング規約.md) +- [テスト方針](docs/01_GUIDE/GUIDE_07_テスト方針.md) diff --git "a/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" index f9aa80e..5bb3b96 100644 --- "a/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" +++ "b/docs/01_GUIDE/GUIDE_01_\343\203\227\343\203\255\343\202\270\343\202\247\343\202\257\343\203\210\347\253\213\343\201\241\344\270\212\343\201\222\343\203\225\343\203\255\343\203\274.md" @@ -56,7 +56,7 @@ ## 規約整備 (Coding Standards) 技術スタックに応じたコーディング規約やプロジェクト固有のガイドを作成する. -汎用ガイド(GUIDE_01〜04)は本テンプレートに含まれている.ここではプロジェクト固有の規約を追加する. +汎用ガイド(GUIDE_01〜05)は本テンプレートに含まれている.ここではプロジェクト固有の規約を追加する. - **基本方針**: 言語・フレームワークの公式ガイドラインや広く採用されている標準規約に則る(例: Effective Dart,PEP 8,Google Style Guide 等).プロジェクト固有のルールは標準と異なる部分のみ定義する. - **人間が決めること**: 標準規約でカバーされない判断(アーキテクチャパターンの選択等) @@ -86,7 +86,7 @@ ### ドキュメントの書き方 -- コード内ドキュメント(JSDoc・コメント)と docs/ ドキュメントの書き方は [GUIDE_05_コーディング規約](GUIDE_05_コーディング規約.md) の「ドキュメント」セクションを参照 +- コード内ドキュメント(JSDoc・コメント)と docs/ ドキュメントの書き方は [GUIDE_06_コーディング規約](GUIDE_06_コーディング規約.md) の「ドキュメント」セクションを参照 - 仕様・設計の変更がある場合は `docs/` を先に更新してから実装に反映する ## CLAUDE.md の管理 (CLAUDE.md Management) diff --git "a/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" "b/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" new file mode 100644 index 0000000..72b3a3f --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_05_\343\202\250\343\203\274\343\202\270\343\202\247\343\203\263\343\203\210\351\201\213\347\224\250\343\203\253\343\203\274\343\203\253.md" @@ -0,0 +1,164 @@ +# エージェント運用ルール (Agent Operation Rules) + +実装品質を担保するために,3 つの専門エージェントを用いた開発パイプラインを定義する. + +## 基本方針 (Basic Policy) + +- 「実装完了」とは,コーディング・テスト・リファクタリングの全フェーズが完了した状態を指す.具体的な完了基準は [GUIDE_08](GUIDE_08_実装完了フロー.md) を参照. +- 各フェーズは専門エージェントが担当し,フレッシュなコンテキストでレビューする. +- フェーズのスキップは原則禁止する.リファクタリング不要の判断は Refactorer エージェント自身が行う. +- 各フェーズ間で人間が確認・判断を行う. + +## エージェント一覧 (Agent List) + +| エージェント | 役割 | フェーズ | +| --- | --- | --- | +| `coder` | 機能実装・バグ修正 | Phase 1 | +| `tester` | 仕様ベースのテスト作成・実行 | Phase 2 | +| `refactorer` | コード品質の改善 | Phase 3 | + +## 実装パイプライン (Implementation Pipeline) + +### 開始方法 + +```bash +/implement <タスク内容> +``` + +### 全体フロー + +``` +人間: /implement <タスク内容> + │ + ├─ ブランチ作成(GUIDE_04 準拠) + │ + ├─ Phase 1 ──▶ [Coder] + │ 実装に集中.テスト・リファクタは行わない + │ + ├─ 人間の確認ポイント 1 + │ ブラウザ/実機で動作確認 + │ OK → 続行 / NG → フィードバックして修正 + │ + ├─ Phase 2 ──▶ [Tester] + │ 仕様ベースでテスト作成・実行 + │ + ├─ Phase 2 完了後の分岐 + │ 全テスト成功 → 自動で Phase 3 へ + │ テスト失敗 → 人間に報告し判断を仰ぐ + │ + ├─ Phase 3 ──▶ [Refactorer] + │ テストを安全網としてリファクタリング + │ テスト再実行で挙動が変わっていないことを保証 + │ + ├─ ドキュメント更新チェック + │ 変更内容に関連する docs/ の更新要否を確認 + │ 必要なら更新してからコミットへ進む + │ + ├─ 人間の確認ポイント 3 + │ 最終確認 + │ OK → コミット・push・PR 作成 + │ + └─ CLAUDE.md 進捗更新 +``` + +### Phase 1: コーディング (Coding) + +- Coder エージェントが `docs/` を読んで実装する. +- 実装完了後,実装サマリーを出力する. +- テストやリファクタリングは行わない. +- コミットはしない. + +### 人間の確認ポイント 1 + +- ブラウザ・実機での動作確認(AI にはできない確認). +- 問題があればフィードバックし,Coder に修正を指示する. + +### Phase 2: テスト (Testing) + +- Tester エージェントが仕様(`docs/04_SPEC/`)を基準にテストを作成する. +- テストは実装コードではなく**仕様**を基準に書く. +- 実装が仕様と異なればテストが失敗し,バグを検出する. +- テスト方針は [GUIDE_07](GUIDE_07_テスト方針.md) を参照. + +### Phase 2 完了後の分岐 + +- **全テスト成功**: テストサマリーを表示し,自動的に Phase 3 に進む. +- **テスト失敗あり**: 人間に報告し,判断を仰ぐ. + - 仕様の問題 → 仕様を修正 + - 実装の問題 → Coder に修正を委譲 + - テストの問題 → Tester に修正を委譲 + +### Phase 3: リファクタリング (Refactoring) + +- Refactorer エージェントがテストを安全網としてコード品質を改善する. +- 挙動は変更しない. +- リファクタリング後にテストを再実行し,全テストが通ることを確認する. +- リファクタリング不要と判断した場合は,理由を明示して終了する. +- リファクタリングの判断基準は [GUIDE_08](GUIDE_08_実装完了フロー.md) のリファクタリング方針を参照. + +### ドキュメント更新チェック (Documentation Update Check) + +Phase 3 完了後,コミット前に `docs/` 配下のドキュメント更新が必要かを確認する.エージェントが更新候補を提示し,人間が最終判断する(コミット前の具体的なチェックリストは [GUIDE_08](GUIDE_08_実装完了フロー.md) を参照). + +- **チェック観点**: + - API・データ構造の変更 → `docs/04_SPEC/` の該当仕様を更新 + - 環境・依存関係の変更 → `docs/02_ENV/` を更新 + - 開発ステップの進捗 → `docs/03_PLAN/` や `CLAUDE.md` の進捗欄を更新 + - 規約・運用ルールの変更 → `docs/01_GUIDE/` を更新 +- **該当なし**: ドキュメント更新が不要な変更(軽微なバグ修正,リファクタリングのみ等)はスキップ可. +- **実行者**: エージェントが `git diff` を基に更新候補を提示し,人間が更新要否を判断する. + +### 人間の確認ポイント 3 + +- 最終確認を行い,OK ならコミット・push・PR 作成を指示する. + +## コンテキスト受け渡し (Context Passing) + +各エージェントは前フェーズのサマリーを入力として受け取る.加えて `git diff` で実際の変更差分を自ら確認する. + +| フェーズ | 受け取る情報 | +| --- | --- | +| Coder | タスク内容 | +| Tester | Coder の実装サマリー + git diff | +| Refactorer | Coder + Tester のサマリー + git diff | + +## 人間の役割 (Human's Role) + +| タイミング | 人間がやること | +| --- | --- | +| 開始時 | タスクの指示(`/implement <何をするか>`) | +| Phase 1 後 | 動作確認(ブラウザ・実機など AI にできない確認) | +| Phase 2 後 | テスト失敗時のみ方針判断(全成功なら自動で Phase 3 へ) | +| Phase 3 後 | ドキュメント更新の要否判断 + 最終確認 → コミット・PR 作成の指示 | + +人間の本質的な役割は「AI にできない判断と確認」であり,各フェーズの品質のゲートキーパーとなる. + +## 個別実行 (Manual Execution) + +パイプラインを使わず個別にエージェントを実行することも可能だが,3 フェーズすべてを順番に実行すること. + +```bash +# 個別実行の場合 +/coder # Phase 1 +# → 人間が動作確認 +/tester # Phase 2 +# → 人間がテスト結果確認 +/refactorer # Phase 3 +# → 人間が最終確認 → コミット +``` + +## 安全装置 (Safety Net) + +Stop Hook により,実装を含む会話の終了時にテスト・リファクタリングの実施状況を確認する.未実施の場合は警告が表示される.これはアドバイザリー(助言)であり,ブロッキング(強制)ではない. + +## コミットルール (Commit Rules) + +パイプライン完了後のコミットは [GUIDE_04](GUIDE_04_Git運用ルール.md) に従う. + +| 内容 | コミットタグ | +| --- | --- | +| 機能追加 | `[add]` | +| 機能更新 | `[update]` | +| バグ修正 | `[fix]` | + +※ リファクタリングとテストは実装と一体の成果物として,まとめてコミットする.必要に応じて分割コミットも可. diff --git "a/docs/01_GUIDE/GUIDE_05_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" "b/docs/01_GUIDE/GUIDE_05_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" deleted file mode 100644 index 47a2c96..0000000 --- "a/docs/01_GUIDE/GUIDE_05_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" +++ /dev/null @@ -1,125 +0,0 @@ -# コーディング規約 (Coding Standards) - -本ドキュメントでは,MiniTIAS プロジェクトの Dart / Flutter コーディング規約を定義する. -基本方針として [Effective Dart](https://dart.dev/effective-dart) に準拠し,プロジェクト固有のルールのみ本書で定める. - -## フォーマット (Formatting) - -- `dart format` のデフォルト設定に従う(行幅 80 文字) -- VS Code の「保存時フォーマット」を有効にする(`.vscode/settings.json` で設定済み) -- 手動でのフォーマット調整は行わない - -## 命名規則 (Naming Conventions) - -Effective Dart の命名規則に従う.プロジェクト固有の補足は以下の通り. - -| 対象 | 規則 | 例 | -| --- | --- | --- | -| ファイル名 | snake_case | `camera_provider.dart` | -| クラス名 | UpperCamelCase | `CameraProvider` | -| 変数・関数 | lowerCamelCase | `takePhoto()` | -| 定数 | lowerCamelCase | `defaultImageQuality` | -| プライベート | 先頭に `_` | `_controller` | -| Provider | `〇〇Provider` | `CameraProvider` | -| Service | `〇〇Service` | `FileService` | -| Screen(画面) | `〇〇Screen` | `CaptureScreen` | -| Widget(部品) | 機能を表す名前 | `ShutterButton` | - -## import 順序 (Import Order) - -以下の順序で記述し,各グループ間は空行で区切る. - -```dart -// 1. Dart SDK -import 'dart:async'; -import 'dart:io'; - -// 2. Flutter SDK -import 'package:flutter/material.dart'; - -// 3. 外部パッケージ(pub.dev) -import 'package:camera/camera.dart'; -import 'package:provider/provider.dart'; - -// 4. プロジェクト内 -import 'package:mini_tias/providers/camera_provider.dart'; -import 'package:mini_tias/services/file_service.dart'; -``` - -※ `dart fix --apply` および `dart format` で自動整列されるため,手動調整は不要. - -## ディレクトリ構造 (Directory Structure) - -[SPEC_01_画面機能仕様書](../04_SPEC/SPEC_01_画面機能仕様書.md) のアーキテクチャセクションで定義したディレクトリ構成に従う. - -```text -lib/ -├── main.dart # エントリポイント,Provider 登録 -├── app.dart # MaterialApp,テーマ -├── providers/ # 状態管理(ChangeNotifier) -├── screens/ # 画面(Scaffold 単位) -├── widgets/ # 再利用可能な UI 部品 -└── services/ # 外部リソースとの橋渡し -``` - -### 配置ルール - -- **1 ファイル 1 クラス** を原則とする.ファイル名はクラス名の snake_case 版 -- **screens/**: 各画面に対応する 1 ファイル.画面固有のロジックは対応する Provider に置く -- **widgets/**: 複数画面で再利用する UI 部品,または画面ファイルが大きくなった場合に切り出す部品 -- **providers/**: 画面または機能ごとに 1 ファイル.ChangeNotifier を継承する -- **services/**: プラットフォーム API やファイルシステムへのアクセスを担う - -## 型の使い方 (Type Usage) - -- ローカル変数は型推論(`var` / `final`)を活用する -- 関数の引数・戻り値には明示的に型を記述する -- `dynamic` は避け,`Object?` を使用する -- `final` をデフォルトとし,再代入が必要な場合のみ `var` を使用する - -## エラーハンドリング (Error Handling) - -### 基本方針 - -- **Service 層**: 例外をキャッチし,呼び出し元に結果を返す.想定外の例外はそのまま上位に伝播させる -- **Provider 層**: Service の結果を受け取り,状態(エラーメッセージ等)として保持する -- **Screen 層**: Provider の状態を参照し,ユーザーにフィードバックを表示する(スナックバー等) - -### 想定するエラー - -| エラー | 発生箇所 | 対処 | -| --- | --- | --- | -| カメラ初期化失敗 | CameraProvider | エラーメッセージを画面に表示 | -| パーミッション拒否 | PermissionService | 設定画面への誘導を表示 | -| ストレージ書き込み失敗 | FileService | スナックバーでエラー通知 | -| ファイル削除失敗 | FileService | スナックバーでエラー通知 | - -### ログ出力 - -- 開発中は `debugPrint()` を使用する(リリースビルドでは自動的に無効化される) -- `print()` は使用しない - -## ドキュメント (Documentation) - -### コード内コメント - -- **DartDoc コメント(`///`)**: 公開 API(public なクラス・メソッド)に記述する -- **実装コメント(`//`)**: ロジックが自明でない箇所にのみ記述する -- 「何をしているか」ではなく「なぜそうしているか」を書く - -### DartDoc の書き方 - -```dart -/// 撮影画像を PNG 形式で共有ストレージに保存する. -/// -/// [imageBytes] は JPEG エンコード済みの画像データ. -/// 保存先は `Pictures/MiniTIAS/` ディレクトリ. -/// 同秒の重複ファイルが存在する場合は連番サフィックスを付与する. -Future saveImage(Uint8List imageBytes) async { - // ... -} -``` - -- 1 行目は動詞で始める簡潔な要約(句点で終わる) -- 詳細が必要な場合は空行を挟んで続ける -- パラメータの説明は `[paramName]` 記法を使用する diff --git "a/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" "b/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" new file mode 100644 index 0000000..47a2c96 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_06_\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" @@ -0,0 +1,125 @@ +# コーディング規約 (Coding Standards) + +本ドキュメントでは,MiniTIAS プロジェクトの Dart / Flutter コーディング規約を定義する. +基本方針として [Effective Dart](https://dart.dev/effective-dart) に準拠し,プロジェクト固有のルールのみ本書で定める. + +## フォーマット (Formatting) + +- `dart format` のデフォルト設定に従う(行幅 80 文字) +- VS Code の「保存時フォーマット」を有効にする(`.vscode/settings.json` で設定済み) +- 手動でのフォーマット調整は行わない + +## 命名規則 (Naming Conventions) + +Effective Dart の命名規則に従う.プロジェクト固有の補足は以下の通り. + +| 対象 | 規則 | 例 | +| --- | --- | --- | +| ファイル名 | snake_case | `camera_provider.dart` | +| クラス名 | UpperCamelCase | `CameraProvider` | +| 変数・関数 | lowerCamelCase | `takePhoto()` | +| 定数 | lowerCamelCase | `defaultImageQuality` | +| プライベート | 先頭に `_` | `_controller` | +| Provider | `〇〇Provider` | `CameraProvider` | +| Service | `〇〇Service` | `FileService` | +| Screen(画面) | `〇〇Screen` | `CaptureScreen` | +| Widget(部品) | 機能を表す名前 | `ShutterButton` | + +## import 順序 (Import Order) + +以下の順序で記述し,各グループ間は空行で区切る. + +```dart +// 1. Dart SDK +import 'dart:async'; +import 'dart:io'; + +// 2. Flutter SDK +import 'package:flutter/material.dart'; + +// 3. 外部パッケージ(pub.dev) +import 'package:camera/camera.dart'; +import 'package:provider/provider.dart'; + +// 4. プロジェクト内 +import 'package:mini_tias/providers/camera_provider.dart'; +import 'package:mini_tias/services/file_service.dart'; +``` + +※ `dart fix --apply` および `dart format` で自動整列されるため,手動調整は不要. + +## ディレクトリ構造 (Directory Structure) + +[SPEC_01_画面機能仕様書](../04_SPEC/SPEC_01_画面機能仕様書.md) のアーキテクチャセクションで定義したディレクトリ構成に従う. + +```text +lib/ +├── main.dart # エントリポイント,Provider 登録 +├── app.dart # MaterialApp,テーマ +├── providers/ # 状態管理(ChangeNotifier) +├── screens/ # 画面(Scaffold 単位) +├── widgets/ # 再利用可能な UI 部品 +└── services/ # 外部リソースとの橋渡し +``` + +### 配置ルール + +- **1 ファイル 1 クラス** を原則とする.ファイル名はクラス名の snake_case 版 +- **screens/**: 各画面に対応する 1 ファイル.画面固有のロジックは対応する Provider に置く +- **widgets/**: 複数画面で再利用する UI 部品,または画面ファイルが大きくなった場合に切り出す部品 +- **providers/**: 画面または機能ごとに 1 ファイル.ChangeNotifier を継承する +- **services/**: プラットフォーム API やファイルシステムへのアクセスを担う + +## 型の使い方 (Type Usage) + +- ローカル変数は型推論(`var` / `final`)を活用する +- 関数の引数・戻り値には明示的に型を記述する +- `dynamic` は避け,`Object?` を使用する +- `final` をデフォルトとし,再代入が必要な場合のみ `var` を使用する + +## エラーハンドリング (Error Handling) + +### 基本方針 + +- **Service 層**: 例外をキャッチし,呼び出し元に結果を返す.想定外の例外はそのまま上位に伝播させる +- **Provider 層**: Service の結果を受け取り,状態(エラーメッセージ等)として保持する +- **Screen 層**: Provider の状態を参照し,ユーザーにフィードバックを表示する(スナックバー等) + +### 想定するエラー + +| エラー | 発生箇所 | 対処 | +| --- | --- | --- | +| カメラ初期化失敗 | CameraProvider | エラーメッセージを画面に表示 | +| パーミッション拒否 | PermissionService | 設定画面への誘導を表示 | +| ストレージ書き込み失敗 | FileService | スナックバーでエラー通知 | +| ファイル削除失敗 | FileService | スナックバーでエラー通知 | + +### ログ出力 + +- 開発中は `debugPrint()` を使用する(リリースビルドでは自動的に無効化される) +- `print()` は使用しない + +## ドキュメント (Documentation) + +### コード内コメント + +- **DartDoc コメント(`///`)**: 公開 API(public なクラス・メソッド)に記述する +- **実装コメント(`//`)**: ロジックが自明でない箇所にのみ記述する +- 「何をしているか」ではなく「なぜそうしているか」を書く + +### DartDoc の書き方 + +```dart +/// 撮影画像を PNG 形式で共有ストレージに保存する. +/// +/// [imageBytes] は JPEG エンコード済みの画像データ. +/// 保存先は `Pictures/MiniTIAS/` ディレクトリ. +/// 同秒の重複ファイルが存在する場合は連番サフィックスを付与する. +Future saveImage(Uint8List imageBytes) async { + // ... +} +``` + +- 1 行目は動詞で始める簡潔な要約(句点で終わる) +- 詳細が必要な場合は空行を挟んで続ける +- パラメータの説明は `[paramName]` 記法を使用する diff --git "a/docs/01_GUIDE/GUIDE_06_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_06_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" deleted file mode 100644 index ba62567..0000000 --- "a/docs/01_GUIDE/GUIDE_06_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" +++ /dev/null @@ -1,92 +0,0 @@ -# テスト方針 (Testing Strategy) - -本ドキュメントでは,MiniTIAS プロジェクトのテスト方針を定義する. - -## 基本方針 (Principles) - -- 初期フェーズではカメラ・ストレージ等のハードウェア依存が大きいため,**実機での手動確認を主体** とする -- ハードウェアに依存しないロジック(ファイル命名,重複回避等)には **Unit テスト** を書く -- テストは `flutter test` で実行できる状態を維持する - -## テストの種類と対象 (Test Types) - -| 種類 | 対象 | 実施方法 | -| --- | --- | --- | -| Unit テスト | Service 層のロジック(ファイル命名,重複回避等) | `flutter test` | -| Widget テスト | 画面の基本的な UI 構成(ボタンの存在等) | `flutter test` | -| 手動確認 | カメラプレビュー,撮影,保存,削除の E2E 動作 | 実機(AQUOS sense3) | - -※ Integration テスト(`flutter drive`)は初期フェーズでは導入しない. - -## Unit テスト - -### 対象 - -- `FileService` — ファイル名生成ロジック,重複回避ロジック -- `PermissionService` — パーミッション状態の判定ロジック(モック使用) - -### ファイル配置 - -```text -test/ -├── services/ -│ ├── file_service_test.dart -│ └── permission_service_test.dart -└── providers/ - └── gallery_provider_test.dart -``` - -### 命名規則 - -- テストファイル名: `{対象ファイル名}_test.dart` -- テストグループ: `group('クラス名',)` でクラス単位にまとめる -- テスト名: 日本語で「〜の場合,〜する」形式 - -```dart -group('FileService', () { - test('同秒のファイルが存在しない場合,サフィックスなしのファイル名を返す', () { - // ... - }); - - test('同秒のファイルが存在する場合,連番サフィックスを付与する', () { - // ... - }); -}); -``` - -## Widget テスト - -### 対象 - -- 画面に必要な UI 要素が存在すること(シャッターボタン,ナビゲーションバー等) -- ボタンタップ時に Provider のメソッドが呼ばれること(モック使用) - -### 方針 - -- カメラプレビューはモック化する(`camera` パッケージのウィジェットは Widget テストで動作しない) -- Provider は `ChangeNotifierProvider.value` でモックを注入する - -## 手動確認 (Manual Testing) - -### 確認項目 - -実装完了時に以下を実機で確認する. - -- [ ] カメラプレビューが正しく表示される(180° 回転) -- [ ] シャッターボタンで撮影できる -- [ ] 撮影画像が `Pictures/MiniTIAS/` に PNG で保存される -- [ ] ファイル名が命名規則に従っている -- [ ] 連続撮影が正常に動作する -- [ ] 一覧画面にサムネイルが表示される -- [ ] サムネイルタップで拡大表示される -- [ ] 画像の削除ができる -- [ ] パーミッション拒否時に適切なメッセージが表示される -- [ ] アプリをバックグラウンド→復帰してもカメラが正常に動作する - -## テスト実行タイミング (When to Test) - -| タイミング | 実施内容 | -| --- | --- | -| 機能実装完了時 | 対応する Unit / Widget テストを作成・実行 | -| コミット前 | `flutter test` を実行し全テストが通ることを確認 | -| PR 作成前 | 手動確認項目のうち関連するものを実機で確認 | diff --git "a/docs/01_GUIDE/GUIDE_07_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" "b/docs/01_GUIDE/GUIDE_07_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" new file mode 100644 index 0000000..ba62567 --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_07_\343\203\206\343\202\271\343\203\210\346\226\271\351\207\235.md" @@ -0,0 +1,92 @@ +# テスト方針 (Testing Strategy) + +本ドキュメントでは,MiniTIAS プロジェクトのテスト方針を定義する. + +## 基本方針 (Principles) + +- 初期フェーズではカメラ・ストレージ等のハードウェア依存が大きいため,**実機での手動確認を主体** とする +- ハードウェアに依存しないロジック(ファイル命名,重複回避等)には **Unit テスト** を書く +- テストは `flutter test` で実行できる状態を維持する + +## テストの種類と対象 (Test Types) + +| 種類 | 対象 | 実施方法 | +| --- | --- | --- | +| Unit テスト | Service 層のロジック(ファイル命名,重複回避等) | `flutter test` | +| Widget テスト | 画面の基本的な UI 構成(ボタンの存在等) | `flutter test` | +| 手動確認 | カメラプレビュー,撮影,保存,削除の E2E 動作 | 実機(AQUOS sense3) | + +※ Integration テスト(`flutter drive`)は初期フェーズでは導入しない. + +## Unit テスト + +### 対象 + +- `FileService` — ファイル名生成ロジック,重複回避ロジック +- `PermissionService` — パーミッション状態の判定ロジック(モック使用) + +### ファイル配置 + +```text +test/ +├── services/ +│ ├── file_service_test.dart +│ └── permission_service_test.dart +└── providers/ + └── gallery_provider_test.dart +``` + +### 命名規則 + +- テストファイル名: `{対象ファイル名}_test.dart` +- テストグループ: `group('クラス名',)` でクラス単位にまとめる +- テスト名: 日本語で「〜の場合,〜する」形式 + +```dart +group('FileService', () { + test('同秒のファイルが存在しない場合,サフィックスなしのファイル名を返す', () { + // ... + }); + + test('同秒のファイルが存在する場合,連番サフィックスを付与する', () { + // ... + }); +}); +``` + +## Widget テスト + +### 対象 + +- 画面に必要な UI 要素が存在すること(シャッターボタン,ナビゲーションバー等) +- ボタンタップ時に Provider のメソッドが呼ばれること(モック使用) + +### 方針 + +- カメラプレビューはモック化する(`camera` パッケージのウィジェットは Widget テストで動作しない) +- Provider は `ChangeNotifierProvider.value` でモックを注入する + +## 手動確認 (Manual Testing) + +### 確認項目 + +実装完了時に以下を実機で確認する. + +- [ ] カメラプレビューが正しく表示される(180° 回転) +- [ ] シャッターボタンで撮影できる +- [ ] 撮影画像が `Pictures/MiniTIAS/` に PNG で保存される +- [ ] ファイル名が命名規則に従っている +- [ ] 連続撮影が正常に動作する +- [ ] 一覧画面にサムネイルが表示される +- [ ] サムネイルタップで拡大表示される +- [ ] 画像の削除ができる +- [ ] パーミッション拒否時に適切なメッセージが表示される +- [ ] アプリをバックグラウンド→復帰してもカメラが正常に動作する + +## テスト実行タイミング (When to Test) + +| タイミング | 実施内容 | +| --- | --- | +| 機能実装完了時 | 対応する Unit / Widget テストを作成・実行 | +| コミット前 | `flutter test` を実行し全テストが通ることを確認 | +| PR 作成前 | 手動確認項目のうち関連するものを実機で確認 | diff --git "a/docs/01_GUIDE/GUIDE_07_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_07_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" deleted file mode 100644 index 3642189..0000000 --- "a/docs/01_GUIDE/GUIDE_07_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" +++ /dev/null @@ -1,79 +0,0 @@ -# 実装完了フロー (Implementation Completion Flow) - -本ドキュメントでは,機能実装の完了からコミット・PR 作成までの手順を定義する. -リファクタリングの判断基準もここで定める. - -## コミット前チェックリスト (Pre-commit Checklist) - -機能実装が完了したら,以下を順番に実施する. - -### 1. 静的解析 - -```bash -dart analyze -``` - -- 警告・エラーが 0 件であることを確認する -- `// ignore:` で抑制する場合は理由をコメントに記述する - -### 2. フォーマット - -```bash -dart format . -``` - -- 差分がないことを確認する(VS Code の保存時フォーマットが有効なら通常は差分なし) - -### 3. テスト実行 - -```bash -flutter test -``` - -- 全テストが通ることを確認する -- 新しいロジックを追加した場合はテストも追加する([GUIDE_06](GUIDE_06_テスト方針.md) 参照) - -### 4. ドキュメント確認 - -- 仕様変更がある場合は `docs/` のドキュメントを先に更新する -- 新しいファイルを追加した場合は CLAUDE.md の参照パスを更新する - -### 5. コミット・PR - -- [GUIDE_04](GUIDE_04_Git運用ルール.md) に従ってコミット・push・PR 作成を行う - -## 実装完了の基準 (Definition of Done) - -以下をすべて満たした場合に「実装完了」とする. - -- [ ] 要求された機能が動作する -- [ ] `dart analyze` で警告・エラーが 0 件 -- [ ] `dart format` で差分がない -- [ ] `flutter test` で全テストが通る -- [ ] 新しいロジックに対するテストが追加されている -- [ ] 関連ドキュメントが更新されている - -## リファクタリング方針 (Refactoring Policy) - -### 実施タイミング - -- **機能実装中**: 実装対象のコードに限り,必要に応じてリファクタリングする -- **機能実装後**: 動作確認が完了してからリファクタリングを行う(動くコードを壊さない) -- **独立した作業として**: 機能追加と同じコミットに混ぜない.`[clean]` タグで別コミットにする - -### 判断基準 - -以下のいずれかに該当する場合にリファクタリングを検討する. - -| 基準 | 例 | -| --- | --- | -| 同じコードが 3 箇所以上に重複している | 共通ロジックのメソッド抽出 | -| 1 ファイルが 300 行を超えている | クラスやウィジェットの分割 | -| 1 メソッドが 50 行を超えている | メソッドの分割 | -| クラスの責務が 2 つ以上混在している | クラスの分割 | - -### やらないこと - -- 動作に問題のないコードの「予防的」リファクタリング -- 将来の要件を見越した過度な抽象化 -- 機能追加と同一コミットでのリファクタリング diff --git "a/docs/01_GUIDE/GUIDE_08_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" "b/docs/01_GUIDE/GUIDE_08_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" new file mode 100644 index 0000000..a534c2e --- /dev/null +++ "b/docs/01_GUIDE/GUIDE_08_\345\256\237\350\243\205\345\256\214\344\272\206\343\203\225\343\203\255\343\203\274.md" @@ -0,0 +1,79 @@ +# 実装完了フロー (Implementation Completion Flow) + +本ドキュメントでは,機能実装の完了からコミット・PR 作成までの手順を定義する. +リファクタリングの判断基準もここで定める. + +## コミット前チェックリスト (Pre-commit Checklist) + +機能実装が完了したら,以下を順番に実施する. + +### 1. 静的解析 + +```bash +dart analyze +``` + +- 警告・エラーが 0 件であることを確認する +- `// ignore:` で抑制する場合は理由をコメントに記述する + +### 2. フォーマット + +```bash +dart format . +``` + +- 差分がないことを確認する(VS Code の保存時フォーマットが有効なら通常は差分なし) + +### 3. テスト実行 + +```bash +flutter test +``` + +- 全テストが通ることを確認する +- 新しいロジックを追加した場合はテストも追加する([GUIDE_07](GUIDE_07_テスト方針.md) 参照) + +### 4. ドキュメント確認 + +- 仕様変更がある場合は `docs/` のドキュメントを先に更新する +- 新しいファイルを追加した場合は CLAUDE.md の参照パスを更新する + +### 5. コミット・PR + +- [GUIDE_04](GUIDE_04_Git運用ルール.md) に従ってコミット・push・PR 作成を行う + +## 実装完了の基準 (Definition of Done) + +以下をすべて満たした場合に「実装完了」とする. + +- [ ] 要求された機能が動作する +- [ ] `dart analyze` で警告・エラーが 0 件 +- [ ] `dart format` で差分がない +- [ ] `flutter test` で全テストが通る +- [ ] 新しいロジックに対するテストが追加されている +- [ ] 関連ドキュメントが更新されている + +## リファクタリング方針 (Refactoring Policy) + +### 実施タイミング + +- **機能実装中**: 実装対象のコードに限り,必要に応じてリファクタリングする +- **機能実装後**: 動作確認が完了してからリファクタリングを行う(動くコードを壊さない) +- **独立した作業として**: 機能追加と同じコミットに混ぜない.`[clean]` タグで別コミットにする + +### 判断基準 + +以下のいずれかに該当する場合にリファクタリングを検討する. + +| 基準 | 例 | +| --- | --- | +| 同じコードが 3 箇所以上に重複している | 共通ロジックのメソッド抽出 | +| 1 ファイルが 300 行を超えている | クラスやウィジェットの分割 | +| 1 メソッドが 50 行を超えている | メソッドの分割 | +| クラスの責務が 2 つ以上混在している | クラスの分割 | + +### やらないこと + +- 動作に問題のないコードの「予防的」リファクタリング +- 将来の要件を見越した過度な抽象化 +- 機能追加と同一コミットでのリファクタリング diff --git "a/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" index 45634d9..54482b7 100644 --- "a/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" +++ "b/docs/03_PLAN/PLAN_02_\351\226\213\347\231\272\343\202\271\343\203\206\343\203\203\343\203\227.md" @@ -136,11 +136,11 @@ ### テスト - 全 Unit / Widget テストの通過確認 -- [GUIDE_06](../01_GUIDE/GUIDE_06_テスト方針.md) の手動確認項目を実機で確認 +- [GUIDE_07](../01_GUIDE/GUIDE_07_テスト方針.md) の手動確認項目を実機で確認 ### 完了基準 -- GUIDE_06 の手動確認項目がすべて OK +- GUIDE_07 の手動確認項目がすべて OK - `dart analyze` / `flutter test` がクリーン - 白板・舌模型の撮影ができ,PC から USB 経由で画像にアクセスできる