Tips & Tricks

Code Review Checklist:Claude Code 实战指南

A practical code review checklist:Claude Code 实战 for improving code quality.

通过 Claude Codeコードレビューを效率化する

コードレビューは品質を維持するための重要な进程ですが、レビュアーの負担が大きいのが課題です。Claude Codeを活用すれば、体系的なチェック列表に基づいた効率的なレビューが可能になります。

安全チェック

> 这个PRのコードを安全の観点でレビューして。
> XSS、SQLインジェクション、认证の脆弱性を确认して。
// 安全チェック列表
const securityChecks = {
  // 1. 输入验证
  inputValidation: {
    check: 'ユーザー入力がサニタイズされているか',
    bad: `element.innerHTML = userInput;`,
    good: `element.textContent = userInput;`,
  },

  // 2. SQLインジェクション
  sqlInjection: {
    check: 'パラメータ化クエリが使われているか',
    bad: `db.query(\`SELECT * FROM users WHERE id = \${userId}\`);`,
    good: `db.query('SELECT * FROM users WHERE id = ?', [userId]);`,
  },

  // 3. 认证・授权
  auth: {
    check: 'APIエンドポイントに認証ミドルウェアがあるか',
    bad: `app.get('/api/admin/users', handler);`,
    good: `app.get('/api/admin/users', requireAuth, requireAdmin, handler);`,
  },

  // 4. 秘密情報の露出
  secrets: {
    check: '環境変数がクライアントに漏れていないか',
    bad: `const apiKey = "sk-1234567890abcdef";`,
    good: `const apiKey = process.env.API_KEY;`,
  },
};

性能チェック

// 性能チェック列表
const performanceChecks = [
  {
    item: 'N+1クエリが発生していないか',
    bad: `
      const users = await db.user.findMany();
      for (const user of users) {
        const posts = await db.post.findMany({ where: { userId: user.id } });
      }`,
    good: `
      const users = await db.user.findMany({
        include: { posts: true },
      });`,
  },
  {
    item: '不必要な再レンダリングがないか',
    bad: `
      function Component() {
        const handler = () => doSomething();
        return <Child onClick={handler} />;
      }`,
    good: `
      function Component() {
        const handler = useCallback(() => doSomething(), []);
        return <Child onClick={handler} />;
      }`,
  },
  {
    item: '大きなリストに仮想化が適用されているか',
    check: '1000件以上のリスト → react-virtualを検討',
  },
];

可読性・可维护性チェック

> 这个コードの可読性を改善する提案をして。
> 命名規則、函数の長さ、评论の適切さを确认して。
// 可読性チェックのポイント

// 1. 函数の長さ(30行以下が理想)
// ❌ 1つの函数で全処理
async function processOrder(order: Order) {
  // 100行の処理...
}

// ✅ 責務ごとに分割
async function processOrder(order: Order) {
  const validated = validateOrder(order);
  const priced = calculateTotal(validated);
  const payment = await processPayment(priced);
  return createConfirmation(payment);
}

// 2. 早期リターンパターン
// ❌ ネストが深い
function getDiscount(user: User) {
  if (user) {
    if (user.isPremium) {
      if (user.orders > 10) {
        return 0.2;
      }
      return 0.1;
    }
    return 0.05;
  }
  return 0;
}

// ✅ 早期リターン
function getDiscount(user: User) {
  if (!user) return 0;
  if (!user.isPremium) return 0.05;
  if (user.orders > 10) return 0.2;
  return 0.1;
}

// 3. マジックナンバーの排除
// ❌
if (status === 3) { /* ... */ }

// ✅
const ORDER_STATUS = { PENDING: 1, PROCESSING: 2, COMPLETED: 3 } as const;
if (status === ORDER_STATUS.COMPLETED) { /* ... */ }

错误处理チェック

// 错误处理の确认ポイント

// ❌ 错误の握りつぶし
try {
  await saveData(data);
} catch (e) {
  // 何如果ない
}

// ✅ 合适的错误処理
try {
  await saveData(data);
} catch (error) {
  logger.error('データ保存に失敗', { error, data: data.id });
  throw new AppError('SAVE_FAILED', 'データの保存に失敗しました', { cause: error });
}

レビュー自动化スクリプト

// scripts/review-check.ts
import { execSync } from 'child_process';

interface ReviewIssue {
  file: string;
  line: number;
  severity: 'error' | 'warning' | 'info';
  message: string;
}

function checkForIssues(): ReviewIssue[] {
  const issues: ReviewIssue[] = [];
  const diff = execSync('git diff --cached --name-only').toString().split('\n');

  for (const file of diff.filter(f => f.endsWith('.ts') || f.endsWith('.tsx'))) {
    const content = execSync(`git show :${file}`).toString();
    const lines = content.split('\n');

    lines.forEach((line, index) => {
      // console.logのチェック
      if (line.includes('console.log') && !file.includes('scripts/')) {
        issues.push({
          file, line: index + 1, severity: 'warning',
          message: 'console.logが残っています',
        });
      }

      // TODO/FIXMEのチェック
      if (/\/\/\s*(TODO|FIXME|HACK)/i.test(line)) {
        issues.push({
          file, line: index + 1, severity: 'info',
          message: 'TODO/FIXMEコメントがあります',
        });
      }

      // any类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类型のチェック
      if (/:\s*any\b/.test(line)) {
        issues.push({
          file, line: index + 1, severity: 'warning',
          message: 'any型が使用されています',
        });
      }
    });
  }

  return issues;
}

const issues = checkForIssues();
issues.forEach(i => console.log(`[${i.severity}] ${i.file}:${i.line} - ${i.message}`));

总结

コードレビューは测试戦略と密接に関連します。借助 Claude Code,安全・性能・可読性の観点から体系的なレビューを高效地実施可以。AIペアプ日志ラミングの手法と組み合わせれば、レビューの質と速度を両立可以。コードレビューの最佳实践はGoogle Engineering Practices

#Claude Code #code review #quality assurance #チェックリスト #automation