mcpField
P
pr-review-expert

pr-review-expert

github.com/alirezarezvaniテスト・品質28.9k681 回インストール2 日前に更新
リポジトリ

pr-review-expert について

GitHub PR と GitLab MR を確認するチーム向けの構造化コードレビュースキルです。影響範囲、セキュリティ、テスト、互換性、性能を調べ、優先度別に指摘をまとめます。

主な機能

  1. 01変更の影響範囲分析
  2. 02セキュリティ問題のスキャン
  3. 03テストカバレッジ差分の確認
  4. 04破壊的変更の検出
  5. 05チケットリンクの確認
  6. 06性能影響のレビュー

活用シーン

  1. 01共有ライブラリや API の変更レビュー
  2. 02大規模な PR や MR の体系的な確認
  3. 03セキュリティ上重要なコードの評価
  4. 04スキーマ移行の破壊リスク確認

インストール

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

$npx skills add https://github.com/alirezarezvani/claude-skills --skill pr-review-expert

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

詳細

PR Review Expert

Tier: 強力 Category: エンジニアリング Domain: コードレビュー/品質保証


概要

GitHub の PR と GitLab の MR を対象に、構造的かつ体系的なコードレビューを行います。スタイルに関する細かな指摘にとどまらず、影響範囲の分析、セキュリティスキャン、破壊的変更の検出、テストカバレッジの差分計算を実施します。30 項目以上のチェックリストと優先順位付けされた指摘事項を含む、レビュー担当者がすぐに使えるレポートを作成します。


主な機能

  • 影響範囲の分析 — どのファイル、サービス、下流の利用者に問題が生じる可能性があるかを追跡します
  • セキュリティスキャン — SQL インジェクション、XSS、認証のバイパス、シークレットの漏えい、依存関係の脆弱性
  • テストカバレッジの差分 — 新規コードと新規テストの比率
  • 破壊的変更の検出 — API 契約、DB スキーマのマイグレーション、設定キー
  • チケットの紐付け — Jira/Linear のチケットが存在し、スコープと一致しているかを確認します
  • パフォーマンスへの影響 — N+1 クエリ、バンドルサイズの回帰、メモリ割り当て

使用する場面

  • 共有ライブラリ、API、DB スキーマに関わる PR/MR をマージする前
  • PR が大きく(変更行数が 200 行を超え)、体系的なレビューが必要な場合
  • PR に対する十分なフィードバックが必要な、新しいコントリビューターのオンボーディング
  • セキュリティ上重要なコードパス(認証、決済、PII の取り扱い)
  • インシデント発生後 — 類似した PR を先回りしてレビューする場合

差分の取得

GitHub(gh CLI)
# View diff in terminal
gh pr diff <PR_NUMBER>

# Get PR metadata (title, body, labels, linked issues)
gh pr view <PR_NUMBER> --json title,body,labels,assignees,milestone

# List files changed
gh pr diff <PR_NUMBER> --name-only

# Check CI status
gh pr checks <PR_NUMBER>

# Download diff to file for analysis
gh pr diff <PR_NUMBER> > /tmp/pr-<PR_NUMBER>.diff
GitLab(glab CLI)
# View MR diff
glab mr diff <MR_IID>

# MR details as JSON
glab mr view <MR_IID> --output json

# List changed files
glab mr diff <MR_IID> --name-only

# Download diff
glab mr diff <MR_IID> > /tmp/mr-<MR_IID>.diff

ワークフロー

ステップ 1 — コンテキストの取得
PR=123
gh pr view $PR --json title,body,labels,milestone,assignees | jq .
gh pr diff $PR --name-only
gh pr diff $PR > /tmp/pr-$PR.diff
ステップ 2 — 影響範囲の分析

変更された各ファイルについて、以下を特定します。

  1. 直接の依存先 — このファイルをインポートしているのは何か?
# Find all files importing a changed module
grep -r "from ['\"].*changed-module['\"]" src/ --include="*.ts" -l
grep -r "require(['\"].*changed-module" src/ --include="*.js" -l

# Python
grep -r "from changed_module import\|import changed_module" . --include="*.py" -l
  1. サービス境界 — この変更はサービスをまたぐか?
# Check if changed files span multiple services (monorepo)
gh pr diff $PR --name-only | cut -d/ -f1-2 | sort -u
  1. 共有契約 — 型、インターフェース、スキーマ
gh pr diff $PR --name-only | grep -E "types/|interfaces/|schemas/|models/"

影響範囲の深刻度:

  • CRITICAL — 共有ライブラリ、DB モデル、認証ミドルウェア、API 契約
  • HIGH — 3 つを超えるサービスが使用するサービス、共有設定、環境変数
  • MEDIUM — 単一サービス内の変更、ユーティリティ関数
  • LOW — UI コンポーネント、テストファイル、ドキュメント
ステップ 3 — セキュリティスキャン
DIFF=/tmp/pr-$PR.diff

# SQL Injection — raw query string interpolation
grep -n "query\|execute\|raw(" $DIFF | grep -E '\$\{|f"|%s|format\('

# Hardcoded secrets
grep -nE "(password|secret|api_key|token|private_key)\s*=\s*['\"][^'\"]{8,}" $DIFF

# AWS key pattern
grep -nE "AKIA[0-9A-Z]{16}" $DIFF

# JWT secret in code
grep -nE "jwt\.sign\(.*['\"][^'\"]{20,}['\"]" $DIFF

# XSS vectors
grep -n "dangerouslySetInnerHTML\|innerHTML\s*=" $DIFF

# Auth bypass patterns
grep -n "bypass\|skip.*auth\|noauth\|TODO.*auth" $DIFF

# Insecure hash algorithms
grep -nE "md5\(|sha1\(|createHash\(['\"]md5|createHash\(['\"]sha1" $DIFF

# eval / exec
grep -nE "\beval\(|\bexec\(|\bsubprocess\.call\(" $DIFF

# Prototype pollution
grep -n "__proto__\|constructor\[" $DIFF

# Path traversal risk
grep -nE "path\.join\(.*req\.|readFile\(.*req\." $DIFF
ステップ 4 — テストカバレッジの差分
# Count source vs test files changed
CHANGED_SRC=$(gh pr diff $PR --name-only | grep -vE "\.test\.|\.spec\.|__tests__")
CHANGED_TESTS=$(gh pr diff $PR --name-only | grep -E "\.test\.|\.spec\.|__tests__")

echo "Source files changed: $(echo "$CHANGED_SRC" | wc -w)"
echo "Test files changed:   $(echo "$CHANGED_TESTS" | wc -w)"

# Lines of new logic vs new test lines
LOGIC_LINES=$(grep "^+" /tmp/pr-$PR.diff | grep -v "^+++" | wc -l)
echo "New lines added: $LOGIC_LINES"

# Run coverage locally
npm test -- --coverage --changedSince=main 2>/dev/null | tail -20
pytest --cov --cov-report=term-missing 2>/dev/null | tail -20

カバレッジ差分のルール:

  • テストのない新規関数 → 指摘する
  • コードを削除せずにテストを削除 → 指摘する
  • カバレッジが 5% を超えて低下 → マージをブロックする
  • 認証/決済のパス → 100% のカバレッジを必須とする
ステップ 5 — 破壊的変更の検出
API 契約の変更
# OpenAPI/Swagger spec changes
grep -n "openapi\|swagger" /tmp/pr-$PR.diff | head -20

# REST route removals or renames
grep "^-" /tmp/pr-$PR.diff | grep -E "router\.(get|post|put|delete|patch)\("

# GraphQL schema removals
grep "^-" /tmp/pr-$PR.diff | grep -E "^-\s*(type |field |Query |Mutation )"

# TypeScript interface removals
grep "^-" /tmp/pr-$PR.diff | grep -E "^-\s*(export\s+)?(interface|type) "
DB スキーマの変更
# Migration files added
gh pr diff $PR --name-only | grep -E "migrations?/|alembic/|knex/"

# Destructive operations
grep -E "DROP TABLE|DROP COLUMN|ALTER.*NOT NULL|TRUNCATE" /tmp/pr-$PR.diff

# Index removals (perf regression risk)
grep "DROP INDEX\|remove_index" /tmp/pr-$PR.diff
設定/環境変数の変更
# New env vars referenced in code (might be missing in prod)
grep "^+" /tmp/pr-$PR.diff | grep -oE "process\.env\.[A-Z_]+" | sort -u

# Removed env vars (could break running instances)
grep "^-" /tmp/pr-$PR.diff | grep -oE "process\.env\.[A-Z_]+" | sort -u
ステップ 6 — パフォーマンスへの影響
# N+1 query patterns (DB calls inside loops)
grep -n "\.find\|\.findOne\|\.query\|db\." /tmp/pr-$PR.diff | grep "^+" | head -20
# Then check surrounding context for forEach/map/for loops

# Heavy new dependencies
grep "^+" /tmp/pr-$PR.diff | grep -E '"[a-z@].*":\s*"[0-9^~]' | head -20

# Unbounded loops
grep -n "while (true\|while(true" /tmp/pr-$PR.diff | grep "^+"

# Missing await (accidentally sequential promises)
grep -n "await.*await" /tmp/pr-$PR.diff | grep "^+" | head -10

# Large in-memory allocations
grep -n "new Array([0-9]\{4,\}\|Buffer\.alloc" /tmp/pr-$PR.diff | grep "^+"

チケット紐付けの確認

# Extract ticket references from PR body
gh pr view $PR --json body | jq -r '.body' | \
  grep -oE "(PROJ-[0-9]+|[A-Z]+-[0-9]+|https://linear\.app/[^)\"]+)" | sort -u

# Verify Jira ticket exists (requires JIRA_API_TOKEN to be SET in the environment).
# Credentials are fed to curl via a config read from stdin (-K -) so the token
# never appears in argv — `ps aux` / /proc/*/cmdline can't see it, and nothing
# secret lands in shell history. Never paste the raw token on the command line.
TICKET="PROJ-123"
: "${JIRA_API_TOKEN:?JIRA_API_TOKEN must be set}"
curl -s -K - "https://your-org.atlassian.net/rest/api/3/issue/$TICKET" <<EOF | \
  jq '{key, summary: .fields.summary, status: .fields.status.name}'
user = "[email protected]:$JIRA_API_TOKEN"
EOF

# Linear ticket — same pattern: the Authorization header goes through the
# stdin config, not a -H flag, to keep the key out of the process list.
LINEAR_ID="abc-123"
: "${LINEAR_API_KEY:?LINEAR_API_KEY must be set}"
curl -s -K - -H "Content-Type: application/json" \
  --data "{\"query\": \"{ issue(id: \\\"$LINEAR_ID\\\") { title state { name } } }\"}" \
  https://api.linear.app/graphql <<EOF | jq .
header = "Authorization: $LINEAR_API_KEY"
EOF

セキュリティ上の注意: Jira を繰り返し使用する場合は、~/.netrc のエントリー (machine your-org.atlassian.net login [email protected] password <token>、 chmod 600 ~/.netrc)を使用し、curl -s --netrc … を呼び出してください。コマンド自体に シークレット情報を一切含めずに済みます。


レビューチェックリスト(30 項目以上)

## Code Review Checklist

### Scope & Context
- [ ] PR title accurately describes the change
- [ ] PR description explains WHY, not just WHAT
- [ ] Linked Jira/Linear ticket exists and matches scope
- [ ] No unrelated changes (scope creep)
- [ ] Breaking changes documented in PR body

### Blast Radius
- [ ] Identified all files importing changed modules
- [ ] Cross-service dependencies checked
- [ ] Shared types/interfaces/schemas reviewed for breakage
- [ ] New env vars documented in .env.example
- [ ] DB migrations are reversible (have down() / rollback)

### Security
- [ ] No hardcoded secrets or API keys
- [ ] SQL queries use parameterized inputs (no string interpolation)
- [ ] User inputs validated/sanitized before use
- [ ] Auth/authorization checks on all new endpoints
- [ ] No XSS vectors (innerHTML, dangerouslySetInnerHTML)
- [ ] New dependencies checked for known CVEs
- [ ] No sensitive data in logs (PII, tokens, passwords)
- [ ] File uploads validated (type, size, content-type)
- [ ] CORS configured correctly for new endpoints

### Testing
- [ ] New public functions have unit tests
- [ ] Edge cases covered (empty, null, max values)
- [ ] Error paths tested (not just happy path)
- [ ] Integration tests for API endpoint changes
- [ ] No tests deleted without clear reason
- [ ] Test names clearly describe what they verify

### Breaking Changes
- [ ] No API endpoints removed without deprecation notice
- [ ] No required fields added to existing API responses
- [ ] No DB columns removed without two-phase migration plan
- [ ] No env vars removed that may be set in production
- [ ] Backward-compatible for external API consumers

### Performance
- [ ] No N+1 query patterns introduced
- [ ] DB indexes added for new query patterns
- [ ] No unbounded loops on potentially large datasets
- [ ] No heavy new dependencies without justification
- [ ] Async operations correctly awaited
- [ ] Caching considered for expensive repeated operations

### Code Quality
- [ ] No dead code or unused imports
- [ ] Error handling present (no bare empty catch blocks)
- [ ] Consistent with existing patterns and conventions
- [ ] Complex logic has explanatory comments
- [ ] No unresolved TODOs (or tracked in ticket)

出力形式

レビューコメントは次の形式で構成します。

## PR Review: [PR Title] (#NUMBER)

Blast Radius: HIGH — changes lib/auth used by 5 services
Security: 1 finding (medium severity)
Tests: Coverage delta +2%
Breaking Changes: None detected

--- MUST FIX (Blocking) ---

1. SQL Injection risk in src/db/users.ts:42
   Raw string interpolation in WHERE clause.
   Fix: db.query("SELECT * WHERE id = $1", [userId])

--- SHOULD FIX (Non-blocking) ---

2. Missing auth check on POST /api/admin/reset
   No role verification before destructive operation.

--- SUGGESTIONS ---

3. N+1 pattern in src/services/reports.ts:88
   findUser() called inside results.map() — batch with findManyUsers(ids)

--- LOOKS GOOD ---
- Test coverage for new auth flow is thorough
- DB migration has proper down() rollback method
- Error handling consistent with rest of codebase

よくある落とし穴

  • 内容よりスタイルを優先してレビューする — スタイルはリンターに任せ、ロジック、セキュリティ、正確性に注力します
  • 影響範囲を見落とす — 共有ユーティリティの 5 行の変更が、20 のサービスを壊すことがあります
  • テストされていない正常系を承認する — エラーパスにテストカバレッジがあることを必ず確認します
  • マイグレーションのリスクを無視する — NOT NULL の追加にはデフォルト値か二段階のマイグレーションが必要です
  • 間接的なシークレットの漏えい — ハードコードされた値だけでなく、エラーメッセージやログ内のシークレットにも注意します
  • 大きな PR のレビューを省略する — PR が大きすぎて適切にレビューできない場合は、分割を依頼します

ベストプラクティス

  1. コードを見る前に、リンクされたチケットを読む — コンテキストを把握すれば誤検出を防げます
  2. レビュー前に CI のステータスを確認する — ビルドに失敗するコードはレビューしません
  3. スタイルよりも影響範囲とセキュリティを優先する
  4. 認証やパフォーマンスに関する重要な変更は、ローカルで再現する
  5. 各コメントに「nit:」「must:」「question:」「suggestion:」などのラベルを明確に付ける
  6. すべてのコメントを 1 回のレビューにまとめる — フィードバックを小出しにしない
  7. 問題だけでなく、良いパターンも認める — 具体的に称賛することが、より良い文化につながります

コメント