[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-70c73864-c3fd-4d08-a3c4-4f1ceb2a6a7e":3,"$fmlnQtMevzmLKUUD7v-ddEuUsmhh5BwoYrq00AcvZzRY":43},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":34},"70c73864-c3fd-4d08-a3c4-4f1ceb2a6a7e","pr-review-expert","使用时，当用户请求审查拉取请求、分析代码更改、检查PR中的安全问题或评估diff的代码质量时。","cat_life_career","mod_other","alirezarezvani,other","---\nname: \"pr-review-expert\"\ndescription: \"Use when the user asks to review pull requests, analyze code changes, check for security issues in PRs, or assess code quality of diffs.\"\n---\n\n# PR Review Expert\n\n**Tier:** POWERFUL\n**Category:** Engineering\n**Domain:** Code Review \u002F Quality Assurance\n\n---\n\n## Overview\n\nStructured, systematic code review for GitHub PRs and GitLab MRs. Goes beyond style nits — this skill\nperforms blast radius analysis, security scanning, breaking change detection, and test coverage delta\ncalculation. Produces a reviewer-ready report with a 30+ item checklist and prioritized findings.\n\n---\n\n## Core Capabilities\n\n- **Blast radius analysis** — trace which files, services, and downstream consumers could break\n- **Security scan** — SQL injection, XSS, auth bypass, secret exposure, dependency vulns\n- **Test coverage delta** — new code vs new tests ratio\n- **Breaking change detection** — API contracts, DB schema migrations, config keys\n- **Ticket linking** — verify Jira\u002FLinear ticket exists and matches scope\n- **Performance impact** — N+1 queries, bundle size regression, memory allocations\n\n---\n\n## When to Use\n\n- Before merging any PR\u002FMR that touches shared libraries, APIs, or DB schema\n- When a PR is large (>200 lines changed) and needs structured review\n- Onboarding new contributors whose PRs need thorough feedback\n- Security-sensitive code paths (auth, payments, PII handling)\n- After an incident — review similar PRs proactively\n\n---\n\n## Fetching the Diff\n\n### GitHub (gh CLI)\n```bash\n# View diff in terminal\ngh pr diff \u003CPR_NUMBER>\n\n# Get PR metadata (title, body, labels, linked issues)\ngh pr view \u003CPR_NUMBER> --json title,body,labels,assignees,milestone\n\n# List files changed\ngh pr diff \u003CPR_NUMBER> --name-only\n\n# Check CI status\ngh pr checks \u003CPR_NUMBER>\n\n# Download diff to file for analysis\ngh pr diff \u003CPR_NUMBER> > \u002Ftmp\u002Fpr-\u003CPR_NUMBER>.diff\n```\n\n### GitLab (glab CLI)\n```bash\n# View MR diff\nglab mr diff \u003CMR_IID>\n\n# MR details as JSON\nglab mr view \u003CMR_IID> --output json\n\n# List changed files\nglab mr diff \u003CMR_IID> --name-only\n\n# Download diff\nglab mr diff \u003CMR_IID> > \u002Ftmp\u002Fmr-\u003CMR_IID>.diff\n```\n\n---\n\n## Workflow\n\n### Step 1 — Fetch Context\n\n```bash\nPR=123\ngh pr view $PR --json title,body,labels,milestone,assignees | jq .\ngh pr diff $PR --name-only\ngh pr diff $PR > \u002Ftmp\u002Fpr-$PR.diff\n```\n\n### Step 2 — Blast Radius Analysis\n\nFor each changed file, identify:\n\n1. **Direct dependents** — who imports this file?\n```bash\n# Find all files importing a changed module\ngrep -r \"from ['\\\"].*changed-module['\\\"]\" src\u002F --include=\"*.ts\" -l\ngrep -r \"require(['\\\"].*changed-module\" src\u002F --include=\"*.js\" -l\n\n# Python\ngrep -r \"from changed_module import\\|import changed_module\" . --include=\"*.py\" -l\n```\n\n2. **Service boundaries** — does this change cross a service?\n```bash\n# Check if changed files span multiple services (monorepo)\ngh pr diff $PR --name-only | cut -d\u002F -f1-2 | sort -u\n```\n\n3. **Shared contracts** — types, interfaces, schemas\n```bash\ngh pr diff $PR --name-only | grep -E \"types\u002F|interfaces\u002F|schemas\u002F|models\u002F\"\n```\n\n**Blast radius severity:**\n- CRITICAL — shared library, DB model, auth middleware, API contract\n- HIGH     — service used by >3 others, shared config, env vars\n- MEDIUM   — single service internal change, utility function\n- LOW      — UI component, test file, docs\n\n### Step 3 — Security Scan\n\n```bash\nDIFF=\u002Ftmp\u002Fpr-$PR.diff\n\n# SQL Injection — raw query string interpolation\ngrep -n \"query\\|execute\\|raw(\" $DIFF | grep -E '\\$\\{|f\"|%s|format\\('\n\n# Hardcoded secrets\ngrep -nE \"(password|secret|api_key|token|private_key)\\s*=\\s*['\\\"][^'\\\"]{8,}\" $DIFF\n\n# AWS key pattern\ngrep -nE \"AKIA[0-9A-Z]{16}\" $DIFF\n\n# JWT secret in code\ngrep -nE \"jwt\\.sign\\(.*['\\\"][^'\\\"]{20,}['\\\"]\" $DIFF\n\n# XSS vectors\ngrep -n \"dangerouslySetInnerHTML\\|innerHTML\\s*=\" $DIFF\n\n# Auth bypass patterns\ngrep -n \"bypass\\|skip.*auth\\|noauth\\|TODO.*auth\" $DIFF\n\n# Insecure hash algorithms\ngrep -nE \"md5\\(|sha1\\(|createHash\\(['\\\"]md5|createHash\\(['\\\"]sha1\" $DIFF\n\n# eval \u002F exec\ngrep -nE \"\\beval\\(|\\bexec\\(|\\bsubprocess\\.call\\(\" $DIFF\n\n# Prototype pollution\ngrep -n \"__proto__\\|constructor\\[\" $DIFF\n\n# Path traversal risk\ngrep -nE \"path\\.join\\(.*req\\.|readFile\\(.*req\\.\" $DIFF\n```\n\n### Step 4 — Test Coverage Delta\n\n```bash\n# Count source vs test files changed\nCHANGED_SRC=$(gh pr diff $PR --name-only | grep -vE \"\\.test\\.|\\.spec\\.|__tests__\")\nCHANGED_TESTS=$(gh pr diff $PR --name-only | grep -E \"\\.test\\.|\\.spec\\.|__tests__\")\n\necho \"Source files changed: $(echo \"$CHANGED_SRC\" | wc -w)\"\necho \"Test files changed:   $(echo \"$CHANGED_TESTS\" | wc -w)\"\n\n# Lines of new logic vs new test lines\nLOGIC_LINES=$(grep \"^+\" \u002Ftmp\u002Fpr-$PR.diff | grep -v \"^+++\" | wc -l)\necho \"New lines added: $LOGIC_LINES\"\n\n# Run coverage locally\nnpm test -- --coverage --changedSince=main 2>\u002Fdev\u002Fnull | tail -20\npytest --cov --cov-report=term-missing 2>\u002Fdev\u002Fnull | tail -20\n```\n\n**Coverage delta rules:**\n- New function without tests → flag\n- Deleted tests without deleted code → flag\n- Coverage drop >5% → block merge\n- Auth\u002Fpayments paths → require 100% coverage\n\n### Step 5 — Breaking Change Detection\n\n#### API Contract Changes\n```bash\n# OpenAPI\u002FSwagger spec changes\ngrep -n \"openapi\\|swagger\" \u002Ftmp\u002Fpr-$PR.diff | head -20\n\n# REST route removals or renames\ngrep \"^-\" \u002Ftmp\u002Fpr-$PR.diff | grep -E \"router\\.(get|post|put|delete|patch)\\(\"\n\n# GraphQL schema removals\ngrep \"^-\" \u002Ftmp\u002Fpr-$PR.diff | grep -E \"^-\\s*(type |field |Query |Mutation )\"\n\n# TypeScript interface removals\ngrep \"^-\" \u002Ftmp\u002Fpr-$PR.diff | grep -E \"^-\\s*(export\\s+)?(interface|type) \"\n```\n\n#### DB Schema Changes\n```bash\n# Migration files added\ngh pr diff $PR --name-only | grep -E \"migrations?\u002F|alembic\u002F|knex\u002F\"\n\n# Destructive operations\ngrep -E \"DROP TABLE|DROP COLUMN|ALTER.*NOT NULL|TRUNCATE\" \u002Ftmp\u002Fpr-$PR.diff\n\n# Index removals (perf regression risk)\ngrep \"DROP INDEX\\|remove_index\" \u002Ftmp\u002Fpr-$PR.diff\n```\n\n#### Config \u002F Env Var Changes\n```bash\n# New env vars referenced in code (might be missing in prod)\ngrep \"^+\" \u002Ftmp\u002Fpr-$PR.diff | grep -oE \"process\\.env\\.[A-Z_]+\" | sort -u\n\n# Removed env vars (could break running instances)\ngrep \"^-\" \u002Ftmp\u002Fpr-$PR.diff | grep -oE \"process\\.env\\.[A-Z_]+\" | sort -u\n```\n\n### Step 6 — Performance Impact\n\n```bash\n# N+1 query patterns (DB calls inside loops)\ngrep -n \"\\.find\\|\\.findOne\\|\\.query\\|db\\.\" \u002Ftmp\u002Fpr-$PR.diff | grep \"^+\" | head -20\n# Then check surrounding context for forEach\u002Fmap\u002Ffor loops\n\n# Heavy new dependencies\ngrep \"^+\" \u002Ftmp\u002Fpr-$PR.diff | grep -E '\"[a-z@].*\":\\s*\"[0-9^~]' | head -20\n\n# Unbounded loops\ngrep -n \"while (true\\|while(true\" \u002Ftmp\u002Fpr-$PR.diff | grep \"^+\"\n\n# Missing await (accidentally sequential promises)\ngrep -n \"await.*await\" \u002Ftmp\u002Fpr-$PR.diff | grep \"^+\" | head -10\n\n# Large in-memory allocations\ngrep -n \"new Array([0-9]\\{4,\\}\\|Buffer\\.alloc\" \u002Ftmp\u002Fpr-$PR.diff | grep \"^+\"\n```\n\n---\n\n## Ticket Linking Verification\n\n```bash\n# Extract ticket references from PR body\ngh pr view $PR --json body | jq -r '.body' | \\\n  grep -oE \"(PROJ-[0-9]+|[A-Z]+-[0-9]+|https:\u002F\u002Flinear\\.app\u002F[^)\\\"]+)\" | sort -u\n\n# Verify Jira ticket exists (requires JIRA_API_TOKEN)\nTICKET=\"PROJ-123\"\ncurl -s -u \"user@company.com:$JIRA_API_TOKEN\" \\\n  \"https:\u002F\u002Fyour-org.atlassian.net\u002Frest\u002Fapi\u002F3\u002Fissue\u002F$TICKET\" | \\\n  jq '{key, summary: .fields.summary, status: .fields.status.name}'\n\n# Linear ticket\nLINEAR_ID=\"abc-123\"\ncurl -s -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  --data \"{\\\"query\\\": \\\"{ issue(id: \\\\\\\"$LINEAR_ID\\\\\\\") { title state { name } } }\\\"}\" \\\n  https:\u002F\u002Fapi.linear.app\u002Fgraphql | jq .\n```\n\n---\n\n## Complete Review Checklist (30+ Items)\n\n```markdown\n## Code Review Checklist\n\n### Scope & Context\n- [ ] PR title accurately describes the change\n- [ ] PR description explains WHY, not just WHAT\n- [ ] Linked Jira\u002FLinear ticket exists and matches scope\n- [ ] No unrelated changes (scope creep)\n- [ ] Breaking changes documented in PR body\n\n### Blast Radius\n- [ ] Identified all files importing changed modules\n- [ ] Cross-service dependencies checked\n- [ ] Shared types\u002Finterfaces\u002Fschemas reviewed for breakage\n- [ ] New env vars documented in .env.example\n- [ ] DB migrations are reversible (have down() \u002F rollback)\n\n### Security\n- [ ] No hardcoded secrets or API keys\n- [ ] SQL queries use parameterized inputs (no string interpolation)\n- [ ] User inputs validated\u002Fsanitized before use\n- [ ] Auth\u002Fauthorization checks on all new endpoints\n- [ ] No XSS vectors (innerHTML, dangerouslySetInnerHTML)\n- [ ] New dependencies checked for known CVEs\n- [ ] No sensitive data in logs (PII, tokens, passwords)\n- [ ] File uploads validated (type, size, content-type)\n- [ ] CORS configured correctly for new endpoints\n\n### Testing\n- [ ] New public functions have unit tests\n- [ ] Edge cases covered (empty, null, max values)\n- [ ] Error paths tested (not just happy path)\n- [ ] Integration tests for API endpoint changes\n- [ ] No tests deleted without clear reason\n- [ ] Test names clearly describe what they verify\n\n### Breaking Changes\n- [ ] No API endpoints removed without deprecation notice\n- [ ] No required fields added to existing API responses\n- [ ] No DB columns removed without two-phase migration plan\n- [ ] No env vars removed that may be set in production\n- [ ] Backward-compatible for external API consumers\n\n### Performance\n- [ ] No N+1 query patterns introduced\n- [ ] DB indexes added for new query patterns\n- [ ] No unbounded loops on potentially large datasets\n- [ ] No heavy new dependencies without justification\n- [ ] Async operations correctly awaited\n- [ ] Caching considered for expensive repeated operations\n\n### Code Quality\n- [ ] No dead code or unused imports\n- [ ] Error handling present (no bare empty catch blocks)\n- [ ] Consistent with existing patterns and conventions\n- [ ] Complex logic has explanatory comments\n- [ ] No unresolved TODOs (or tracked in ticket)\n```\n\n---\n\n## Output Format\n\nStructure your review comment as:\n\n```\n## PR Review: [PR Title] (#NUMBER)\n\nBlast Radius: HIGH — changes lib\u002Fauth used by 5 services\nSecurity: 1 finding (medium severity)\nTests: Coverage delta +2%\nBreaking Changes: None detected\n\n--- MUST FIX (Blocking) ---\n\n1. SQL Injection risk in src\u002Fdb\u002Fusers.ts:42\n   Raw string interpolation in WHERE clause.\n   Fix: db.query(\"SELECT * WHERE id = $1\", [userId])\n\n--- SHOULD FIX (Non-blocking) ---\n\n2. Missing auth check on POST \u002Fapi\u002Fadmin\u002Freset\n   No role verification before destructive operation.\n\n--- SUGGESTIONS ---\n\n3. N+1 pattern in src\u002Fservices\u002Freports.ts:88\n   findUser() called inside results.map() — batch with findManyUsers(ids)\n\n--- LOOKS GOOD ---\n- Test coverage for new auth flow is thorough\n- DB migration has proper down() rollback method\n- Error handling consistent with rest of codebase\n```\n\n---\n\n## Common Pitfalls\n\n- **Reviewing style over substance** — let the linter handle style; focus on logic, security, correctness\n- **Missing blast radius** — a 5-line change in a shared utility can break 20 services\n- **Approving untested happy paths** — always verify error paths have coverage\n- **Ignoring migration risk** — NOT NULL additions need a default or two-phase migration\n- **Indirect secret exposure** — secrets in error messages\u002Flogs, not just hardcoded values\n- **Skipping large PRs** — if a PR is too large to review properly, request it be split\n\n---\n\n## Best Practices\n\n1. Read the linked ticket before looking at code — context prevents false positives\n2. Check CI status before reviewing — don't review code that fails to build\n3. Prioritize blast radius and security over style\n4. Reproduce locally for non-trivial auth or performance changes\n5. Label each comment clearly: \"nit:\", \"must:\", \"question:\", \"suggestion:\"\n6. Batch all comments in one review round — don't trickle feedback\n7. Acknowledge good patterns, not just problems — specific praise improves culture\n","","imported","https:\u002F\u002Fgithub.com\u002Falirezarezvani\u002Fclaude-skills","user_system_seed","SkillOPIC",true,123,731,"2026-05-16 13:54:50",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"其他","other","mdi-page-next-outline","其他类型Skill",5,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":32,"skillCount":33,"createdAt":26},"职场发展","career","mdi-briefcase-outline","面试准备、简历优化、职业规划",4,575,[35],{"id":36,"skillId":4,"version":37,"fileName":38,"fileSize":39,"filePath":40,"fileHash":41,"manifest":42,"createdAt":19},"65d2f5bb-a77c-40a1-836b-c850b882c3e0","1.0.0","pr-review-expert.zip",5273,"uploads\u002Fskills\u002F70c73864-c3fd-4d08-a3c4-4f1ceb2a6a7e\u002Fpr-review-expert.zip","445105bd7cae00594995f645bf90a9b73bc939d840275e30371b7c617a39bae6","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":11862}]",{"code":44,"message":45,"data":46},200,"success",{"items":47,"stats":48,"page":51},[],{"averageRating":49,"totalRatings":49,"ratingCounts":50},0,[49,49,49,49,49],{"limit":52,"offset":49,"hasMore":53,"nextOffset":52,"ratedOnly":16},15,false]