--- name: coding-standards description: コードの品質問題、アンチパターン、可読性を検査。機能実装、コードレビュー、リファクタリング時に使用。 --- # 普遍的コーディング規約 ## 技術的アンチパターン(赤信号パターン) 以下のパターンを検出したら即座に停止し、設計を見直すこと: ### コード品質のアンチパターン 1. **同じようなコードを3回以上書いた** - Rule of Threeに違反 2. **単一ファイルに複数の責務が混在** - 単一責任原則(SRP)違反 3. **同じ内容を複数ファイルで定義** - DRY原則違反 4. **依存関係を確認せずに変更** - 予期しない影響の可能性 5. **コメントアウトでコード無効化** - バージョン管理を活用すべき 6. **エラーの握りつぶし** - 問題の隠蔽は技術的負債 7. **型アサーション(as)の多用** - 型安全性の放棄 ### 設計のアンチパターン - **「一旦動くように」という思考** - 技術的負債の蓄積 - **継ぎ足し実装** - 既存コードへの無計画な追加 - **不確実技術の楽観的実装** - 未知要素を「たぶん動く」前提で設計 - **対処療法的修正** - 根本原因を解決しない表面的な修正 - **無計画な大規模変更** - 段階的アプローチの欠如 ## 基本原則 - **積極的なリファクタリング** - 技術的負債を防ぎ、健全性を維持 - **使われない「念のため」のコード禁止** - YAGNI原則(Kent Beck)に反する ## コメント記述ルール - **機能説明重視**: コードが「何をするか」を記述 - **履歴情報禁止**: 開発履歴は記載しない - **タイムレス**: いつ読んでも有効な内容のみ記述 - **簡潔性**: 必要最小限の説明にとどめる ## エラーハンドリングの基本原則 ### Fail-Fast原則 エラー時は速やかに失敗させ、不正な状態での処理継続を防ぐ。エラーの握りつぶしは禁止。 詳細な実装方法(Result型、カスタムエラークラス、層別エラー処理など)は各言語・フレームワークのルールを参照。 ## Rule of Three - コード重複の判断基準 Martin Fowler「Refactoring」に基づく重複コードの扱い方: | 重複回数 | 対応 | 理由 | |---------|------|------| | 1回目 | インライン実装 | 将来の変化が予測できない | | 2回目 | 将来の統合を意識 | パターンが見え始める | | 3回目 | 共通化実施 | パターンが確立された | ### 共通化の判断基準 **共通化すべきケース** - ビジネスロジックの重複 - 複雑な処理アルゴリズム - 一括変更が必要になる可能性が高い箇所 - バリデーションルール **共通化を避けるべきケース** - 偶然の一致(たまたま同じコード) - 将来異なる方向に進化する可能性 - 共通化により可読性が著しく低下 - テストコード内の簡単なヘルパー ## 参照の代表性 **失敗パターン**: 近隣2-3ファイルのパターンや依存バージョンをリポジトリ全体での使用状況を確認せずに採用すると、古いパターン、バージョン不一致、アーキテクチャ不整合が発生する。 ### 採用前の確認 既存コードからパターン、API、依存を採用する場合: - **IF** 参照が近隣2-3ファイルのみ → **THEN** Grepでリポジトリ全体を検索し、異なるディレクトリの3ファイル以上で同じパターンが使われている場合に採用可能 - **IF** Grepで参照元以外に1-2件のみ検出 → **THEN** それが正規の実装かレガシーの残存か調査してから採用を判断 - **IF** Grepで参照元以外に0件 → **THEN** ローカル規約として扱い、明示的な理由がある場合のみ採用(例: 周辺コードとの整合性、破壊的変更の回避) - **IF** リポジトリ内に複数のアプローチが共存 → **THEN** 多数派パターン(最多ファイル数)を特定して採用。少数派を選ぶ場合は理由を明記 - **IF** 外部依存(ライブラリ、プラグイン、SDK)を採用 → **THEN** 同じ依存のリポジトリ全体での使用分布を確認。リポジトリの状態だけでは適切なバージョンが判断できない場合はエスカレーション - **IF** 既存パターンに従う → **THEN** 代替が存在する場合はその理由を明記(例: 周辺コードとの整合性、破壊的変更の回避、統一的なアップデートを予定) ### 原則 近隣コードは調査の起点。採用の根拠にするにはリポジトリ全体での使用状況(異なるディレクトリの3ファイル以上)を確認すること。 ## よくある失敗パターンと回避方法 ### パターン1: エラー修正の連鎖 **症状**: エラーを修正すると新しいエラーが発生 **原因**: 根本原因を理解せずに表面的な修正 **回避方法**: 5 Whysで根本原因を特定してから修正 ### パターン2: 型安全性の放棄 **症状**: any型やasの多用 **原因**: 型エラーを回避したい衝動 **回避方法**: unknown型と型ガードで安全に処理 ### パターン3: テスト不足での実装 **症状**: 実装後にバグ多発 **原因**: Red-Green-Refactorプロセスの無視 **回避方法**: 必ず失敗するテストから開始 ### パターン4: 技術的不確実性の無視 **症状**: 新技術導入時の想定外エラー多発 **原因**: 事前調査なしで「公式ドキュメント通りなら動くはず」 **回避方法**: - タスクファイル冒頭に確実性評価を記載 - 確実性lowの場合、最初に最小限の動作確認コードを作成 ### パターン5: 既存コード調査不足 **症状**: 重複実装、アーキテクチャ不整合、結合時の障害、古いパターンの採用 **原因**: 実装前の既存コード理解不足、近隣ファイルのみ参照し代表性を確認していない **回避方法**: - 実装前に類似機能の存在を必ず検索(同じドメイン、責務、設定パターンをキーワードに) - 類似機能を発見 → その実装を使用する(新規実装は行わない) - 類似機能が技術的負債 → ADRで改善提案を作成してから実装 - 類似機能が存在しない → 既存の設計思想に沿って新規実装 - すべての判断と根拠をDesign Docの「既存コードベース分析」セクションに記録 - **参照の代表性チェック**: 上記「参照の代表性」セクションのIF-THEN閾値を参照 ## デバッグ手法 ### 1. エラー分析手順 1. エラーメッセージ(最初の行)を正確に読む 2. スタックトレースの最初と最後に注目 3. 自分のコードが現れる最初の行を特定 ### 2. 5 Whys - 根本原因分析 ``` 症状: TypeScriptのビルドエラー Why1: 型定義が一致しない → Why2: インターフェースが更新された Why3: 依存関係の変更 → Why4: パッケージ更新の影響 Why5: 破壊的変更を含むメジャーバージョンアップ 根本原因: package.jsonでのバージョン指定が不適切 ``` ### 3. 最小再現コード 問題を切り分けるため、最小限のコードで再現を試みる: - 関連のない部分を削除 - モックで外部依存を置き換え - 問題が再現する最小構成を作成 ## 型安全性の基礎 **型安全の原則**: `unknown`型と型ガードを使用する。`any`型は型チェックを無効化し、実行時エラーの原因となる。 **any型の代替手段(優先順位順)** 1. **unknown型 + 型ガード**: 外部入力の検証に使用 2. **ジェネリクス**: 型の柔軟性が必要な場合 3. **ユニオン型・インターセクション型**: 複数の型の組み合わせ 4. **型アサーション(最終手段)**: 型が確実な場合のみ **型ガードの実装パターン** ```typescript function isUser(value: unknown): value is User { return typeof value === 'object' && value !== null && 'id' in value && 'name' in value } ``` **型の複雑性管理** - フィールド数: 20個まで(超えたら責務で分割、外部API型は例外) - オプショナル率: 30%まで(超えたら必須/任意で分離) - ネスト深さ: 3階層まで(超えたらフラット化) - 型アサーション: 3回以上使用したら設計見直し - **外部API型の扱い**: 制約を緩和し、実態に合わせて定義(内部では適切に変換) ## リファクタリング手法 **基本方針** - 小さなステップ: 段階的改善により、常に動作する状態を維持 - 安全な変更: 一度に変更する範囲を最小限に抑制 - 動作保証: 既存の動作を変えないことを確認しながら進める **実施手順**: 現状把握 → 段階的変更 → 動作確認 → 最終検証 **優先順位**: 重複コード削除 > 長大な関数分割 > 複雑な条件分岐簡素化 > 型安全性向上 ## 実装作業の完全性担保 ### 影響範囲調査の必須手順 **完了定義**: 以下3段階すべての完了 #### 1. 検索(Discovery) ```bash Grep -n "TargetClass\|TargetMethod" -o content Grep -n "DependencyClass" -o content Grep -n "targetData\|SetData\|UpdateData" -o content ``` #### 2. 読解(Understanding) **必須**: 発見した全ファイルを読み込み、作業に必要な部分をコンテキストに含める: - 呼び出し元の目的と文脈 - 依存関係の方向 - データフロー: 生成→変更→参照 #### 3. 特定(Identification) 影響範囲の構造化報告(必須): ``` ## 影響範囲分析 ### 直接影響: ClassA、ClassB(理由明記) ### 間接影響: SystemX、PrefabY(連携経路明記) ### 処理フロー: 入力→処理1→処理2→出力 ``` **重要**: 検索のみで完了とせず、3段階すべてを実行すること ### 未使用コード削除ルール 未使用コード検出時 → 使用予定? - Yes → 即実装(保留禁止) - No → 即削除(Git履歴に残る) 対象: コード・ドキュメント・設定ファイル ## Red-Green-Refactorプロセス(テストファースト開発) **推奨原則**: コード変更は必ずテストから始める **開発ステップ**: 1. **Red**: 期待する動作のテストを書く(失敗する) 2. **Green**: 最小限の実装でテストを通す 3. **Refactor**: テストが通る状態を維持しながらコード改善 **NGケース(テストファースト不要)**: - 純粋な設定ファイル変更(.env、config等) - ドキュメントのみの更新(README、コメント等) - 緊急本番障害対応(ただし事後テスト必須) ## テスト設計原則 ### テストケースの構造 - テストは「準備(Arrange)」「実行(Act)」「検証(Assert)」の3段階で構成 - 各テストの目的が明確に分かる命名 - 1つのテストケースでは1つの振る舞いのみを検証 ### テストデータ管理 - テストデータは専用ディレクトリで管理 - 環境変数はテスト用の値を定義 - 機密情報は必ずモック化 - テストデータは最小限に保ち、テストケースの検証目的に直接関連するデータのみ使用 ### モックとスタブの使用方針 **推奨: 単体テストでの外部依存モック化** - メリット: テストの独立性と再現性を確保 - 実践: DB、API、ファイルシステム等の外部依存をモック化 **避けるべき: 単体テストでの実際の外部接続** - 理由: テスト速度が遅くなり、環境依存の問題が発生するため ### テスト失敗時の対応判断基準 **テストを修正**: 間違った期待値、存在しない機能参照、実装詳細への依存、テストのためだけの実装 **実装を修正**: 妥当な仕様、ビジネスロジック、重要なエッジケース **判断に迷ったら**: ユーザーに確認 ## テストの粒度原則 ### 原則:観測可能な振る舞いのみ **テスト対象**:公開API、戻り値、例外、外部呼び出し、永続化された状態 **テスト対象外**:privateメソッド、内部状態、アルゴリズム詳細 ## Security Principles ### Secure Defaults - 認証情報とシークレットは環境変数または専用のシークレットマネージャーで管理 - すべてのデータベースアクセスにパラメータ化クエリ(プリペアドステートメント)を使用 - 言語またはフレームワークが提供する確立された暗号ライブラリを使用 - セキュリティ上重要な値(トークン、ID、nonce)は暗号学的に安全な乱数生成器で生成 - 機密データは標準プロトコルを使用して保存時・転送時に暗号化 ### Input and Output Boundaries - システムのエントリポイントで、期待される形式・型・長さについてすべての外部入力を検証 - 出力をレンダリングコンテキスト(HTML、SQL、シェル、URL)に応じて適切にエンコード - エラーレスポンスには呼び出し元に必要な情報のみを返却し、詳細な診断情報はサーバーサイドでログに記録 ### Access Control - ユーザーデータを扱うまたは状態変更をトリガーするすべてのエントリポイントに認証を適用 - エントリポイントだけでなく、各リソースアクセスで認可を検証 - 操作に必要な権限のみを付与(ファイル、データベース接続、APIスコープ) ### Knowledge Cutoff Supplement (2026-03) - OWASP Top 10:2025は症状から根本原因にシフトし、「Software Supply Chain Failures」(A03)と「Mishandling of Exceptional Conditions」(A10)が追加 - 最近の研究でAI生成コードがAccess Controlの欠落を高い発生率で示す — 認証と認可を高優先度のレビュー対象として扱う - OpenSSFが「Security-Focused Guide for AI Code Assistant Instructions」を公開 — 汎用的なアドバイスより言語固有のアクション可能な制約を推奨 - 詳細な検出パターンは`references/security-checks.md`を参照