mcpField
A
aif-best-practices

aif-best-practices

github.com/lee-to開発1.1k97 回インストール今日更新
リポジトリ

aif-best-practices について

aif-best-practicesは、言語やフレームワークを問わず使えるコード品質ガイドです。命名、構造、エラー処理、テスト、レビューを扱い、プロジェクトのアーキテクチャや固有ルールも反映します。

主な機能

  1. 01命名規約の提示
  2. 02関数とモジュール構成の指針
  3. 03エラー処理の説明
  4. 04テストとコードレビューの網羅

活用シーン

  1. 01新しいコードの命名と構造を統一
  2. 02エラー処理とテストの重点を確認
  3. 03コードレビューで品質チェックリストを活用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lee-to/ai-factory --skill aif-best-practices

インストール後、Claude Code で/aif-best-practicesを入力して読み込まれたか確認します。

詳細

ベストプラクティスガイド

あらゆる言語やフレームワークに適用できる、汎用的なコード品質ガイドラインです。

コンテキスト: .ai-factory/ARCHITECTURE.md が存在する場合は、このガイドラインに加えて、そのフォルダー構成、依存関係のルール、モジュール境界に従ってください。

.ai-factory/skill-context/aif-best-practices/SKILL.md を読む — ファイルが存在する場合は必須です。

このファイルには、パッチ、コードベースの規約、技術スタックの分析をもとに /aif-evolve が蓄積した、プロジェクト固有のルールが含まれています。これらのルールは、現在のプロジェクトに合わせて調整されています。

skill-context のルールの適用方法:

  • これらのルールは、このスキルの一般的な指示に対するプロジェクトレベルの上書き設定として扱ってください
  • skill-context のルールが、この SKILL.md に記載された一般的なルールと競合する場合は、 skill-context のルールを優先してください(より具体的なコンテキストが優先されます。ネストされた CLAUDE.md ファイルと同じ原則です)
  • 競合がない場合は、SKILL.md の一般的なルールと skill-context のプロジェクトルールの両方を適用してください
  • skill-context のルールがこのスキルの既定値と矛盾しているように見えても、無視してはいけません。 これらのルールが存在するのは、プロジェクトでの経験から既定値では不十分だと判明したためです
  • 重要: skill-context のルールは、このスキルのすべての出力に適用されます。提示する推奨事項、 例、チェックリストも含みます。skill-context のルールで「ベストプラクティスでは X を必ず優先する」 または「例では必ず規約 Y に従う」と定められている場合は、必ず従ってください。skill-context のルールに 反するガイダンスを提示することは不具合です。

遵守の確認: 出力成果物を生成した後は、すべての skill-context のルールに照らして確認してください。 ルールに違反している場合は、ユーザーに提示する前に出力を修正してください。

クイックリファレンス

  • /aif-best-practices — 全体の概要
  • /aif-best-practices naming — 命名規則
  • /aif-best-practices structure — コード構成
  • /aif-best-practices errors — エラー処理
  • /aif-best-practices testing — テストの実践方法
  • /aif-best-practices review — コードレビューのチェックリスト

命名規則

変数と関数
✅ Good                          ❌ Bad
─────────────────────────────────────────────
getUserById(id)                  getUser(i)
isValidEmail                     checkEmail
maxRetryCount                    max
calculateTotalPrice              calc
handleSubmit                     submit

ルール:

  • 意図が伝わる、説明的な名前を使います
  • 略語は避けます(広く知られている id、url、api を除く)
  • ブール値の変数:is、has、can、should を接頭辞にします
  • 関数:動詞 + 名詞(fetchUser、validateInput)
  • 定数:SCREAMING_SNAKE_CASE
  • クラス/型:PascalCase
  • 変数/関数:camelCase(JS/TS/PHP)または snake_case(Python/Rust)
ファイルとディレクトリ
✅ Good                          ❌ Bad
─────────────────────────────────────────────
user-service.ts                  userService.ts (inconsistent)
UserRepository.ts                user_repository.ts (mixed)
/components/Button/              /Components/button/
/services/auth/                  /Services/Auth/

ルール:

  • プロジェクト内ではファイルの命名規則を統一します(kebab-case または PascalCase)
  • ディレクトリ:小文字とハイフンを使用します
  • テストファイル:*.test.ts または *.spec.ts(どちらかに統一)
  • インデックスファイル:再エクスポートのみに使用し、ロジックは記述しません

コード構成

関数の設計
// ✅ Good: Single responsibility, clear inputs/outputs
function calculateDiscount(price: number, discountPercent: number): number {
  if (discountPercent < 0 || discountPercent > 100) {
    throw new Error('Discount must be between 0 and 100');
  }
  return price * (1 - discountPercent / 100);
}

// ❌ Bad: Multiple responsibilities, side effects
function processOrder(order) {
  validateOrder(order);           // validation
  order.discount = getDiscount(); // mutation
  saveToDatabase(order);          // persistence
  sendEmail(order.user);          // notification
  return order;
}
// ✅ Good: PHP with type declarations
function calculateDiscount(float $price, float $discountPercent): float
{
    if ($discountPercent < 0 || $discountPercent > 100) {
        throw new InvalidArgumentException('Discount must be between 0 and 100');
    }
    return $price * (1 - $discountPercent / 100);
}

ルール:

  • 単一責任:1 つの関数につき 1 つの役割にします
  • 1 つの関数は最大 20~30 行にします
  • 引数は最大 3~4 個にします(それ以上の場合はオブジェクトを使います)
  • 純粋関数には副作用を持たせません
  • ガード節には早期リターンを使います
モジュール構成
feature/
├── index.ts          # Public exports only
├── types.ts          # Types and interfaces
├── constants.ts      # Constants
├── utils.ts          # Pure utility functions
├── hooks.ts          # React hooks (if applicable)
├── service.ts        # Business logic
└── repository.ts     # Data access

ルール:

  • 種類別ではなく機能別にまとめます
  • index.ts を介して明確な公開 API を提供します
  • 内部モジュールには _ を付けるか、internal/ に配置します
  • 循環依存を避けます

エラー処理

推奨事項と禁止事項
// ✅ Good: Specific errors, meaningful messages
class UserNotFoundError extends Error {
  constructor(userId: string) {
    super(`User not found: ${userId}`);
    this.name = 'UserNotFoundError';
  }
}

async function getUser(id: string): Promise<User> {
  const user = await db.users.find(id);
  if (!user) {
    throw new UserNotFoundError(id);
  }
  return user;
}

// ❌ Bad: Generic errors, swallowed exceptions
async function getUser(id) {
  try {
    return await db.users.find(id);
  } catch (e) {
    console.log(e);  // Swallowed!
    return null;     // Hides the problem
  }
}

ルール:

  • ドメインエラーには、用途に応じたエラークラスを作成します
  • ログを記録せずに例外を握りつぶしてはいけません
  • ユーザー ID やリクエスト ID などのコンテキストを含めてエラーをログに記録します
  • システムの境界でエラーバウンダリーを使用します
  • 予期される失敗には Result 型を返します(任意)
エラーメッセージ
✅ Good: "Failed to create user: email '[email protected]' already exists"
❌ Bad: "Error occurred"
❌ Bad: "Something went wrong"

テストの実践方法

テスト構成(AAA パターン)
describe('calculateDiscount', () => {
  it('should apply percentage discount to price', () => {
    // Arrange
    const price = 100;
    const discount = 20;

    // Act
    const result = calculateDiscount(price, discount);

    // Assert
    expect(result).toBe(80);
  });

  it('should throw for invalid discount percentage', () => {
    expect(() => calculateDiscount(100, -10)).toThrow();
    expect(() => calculateDiscount(100, 150)).toThrow();
  });
});

ルール:

  • 1 つのテストにつき、1 つのアサーション概念を検証します
  • テスト名は説明的にします:「条件 [condition] のとき、[expected behavior] となること」
  • 実装ではなく振る舞いをテストします
  • テストデータにはファクトリー/フィクスチャを使います
  • プライベートメソッドを直接テストすることは避けます
テストカバレッジの優先順位
1. Critical business logic      ████████████ Must have
2. Edge cases and boundaries    ████████░░░░ Important
3. Integration points           ██████░░░░░░ Important
4. Happy paths                  ████░░░░░░░░ Basic
5. UI components                ██░░░░░░░░░░ Optional

コードレビューのチェックリスト

レビュー依頼前
  • diff を自分でレビューした
  • ローカルでテストが通る
  • デバッグコードがない (console.log、debugger)
  • コメントアウトされたコードがない
  • 必要に応じてドキュメントを更新した
  • コミットメッセージが明確である
レビュアーチェックリスト
  • 正確性: 主張どおりに動作しますか?
  • エッジケース: 何がうまくいかない可能性がありますか?
  • セキュリティ: 脆弱性はありませんか? (/aif-security-checklist を参照)
  • パフォーマンス: 明らかなボトルネックはありませんか?
  • 可読性: 5 分で理解できますか?
  • テスト: 重要なパスはカバーされていますか?
  • 一貫性: プロジェクトの規約に従っていますか?
レビューコメント
✅ Good feedback:
"This could throw if `user` is null. Consider adding a null check
or using optional chaining: `user?.profile?.name`"

❌ Bad feedback:
"This is wrong"
"I don't like this"
"Why did you do it this way?"

クイックルールまとめ

領域ルール
命名説明的で一貫性があり、意図が分かる
関数小さく、単一の目的で、副作用がない
エラー具体的な型を使用し、握りつぶさず、コンテキストをログに記録する
テストAAA パターン、振る舞いをテスト、説明的な名前
レビュー具体的に、解決策を提案し、親切に

成果物の所有権と設定ポリシー

  • 主な所有権: なし。このスキルは助言および参照専用です。
  • 書き込みポリシー: デフォルトではプロジェクトの成果物を作成または変更しません。
  • 設定ポリシー: 設計上、設定に依存しません。config.yaml を読む代わりに、リポジトリのコンテキスト、.ai-factory/ARCHITECTURE.md、およびスキルコンテキストのオーバーライドに従ってください。

コメント