| name | reviewing-code-changes |
| description | Use when reviewing code changes, identifying potential bugs, or suggesting improvements for pull requests. Covers correctness, maintainability, performance, security, and project-specific rule compliance (Symfony 8, PHP 8.4, Doctrine multi-EM, RabbitMQ message flow, Redis cache, API key handling). |
| allowed-tools | Read, Grep, Glob |
Code Review
Review Scope
Before starting, determine what changed:
git diff main...HEAD --name-only
git diff main...HEAD
Group changed files by layer — Entity, Repository, Service, Handler, Controller, Config — and apply the relevant checklist sections for each layer.
Review Checklist
Correctness
PHP 8.4 Conventions
Symfony 8 Conventions
Doctrine / Database (@see .claude/rules/database/postgresql-rule.md)
External API Integration (@see .claude/rules/api/rest-rule.md)
Redis / Cache (@see .claude/rules/cache/redis-rule.md)
Security
Maintainability
Performance
Severity Levels
Apply one of three severities to each finding:
| Severity | Label | When to use |
|---|
| Must fix | [MUST] | Bug, security vulnerability, rule violation, data corruption risk |
| Should fix | [SHOULD] | Performance issue, maintainability problem, project convention deviation |
| Consider | [CONSIDER] | Optional improvement, style preference, future-proofing |
Only [MUST] items block merge.
Review Output Format
Structure the review response in this exact order:
Summary
One or two sentences: overall code quality assessment and merge readiness.
[MUST] Required Changes
Items that must be resolved before merging. Reference the specific file and line:
app/src/Entity/Foo.php:42 — Missing #[ORM\HasLifecycleCallbacks]; #[ORM\PrePersist] will be silently ignored without it.
app/src/Service/Bar.php:17 — Decrypted API key passed to logger; use masked prefix only.
[SHOULD] Recommended Changes
Items that improve quality but do not block merge:
app/src/Repository/BazRepository.php — findByStatus() has no companion findByStatusQueryBuilder(); callers cannot paginate without duplicating the query.
[CONSIDER] Optional Suggestions
Low-priority ideas for future improvement:
- Consider extracting the timezone constant
new \DateTimeZone('Asia/Seoul') to a shared constant to avoid scattered string literals.
Positive Feedback
Acknowledge what is done well — this is not optional. Identify at least one concrete strength:
app/src/MessageHandler/FooHandler.php — Correctly separates fetch and transform; the raw JSON is persisted first and transformation is deferred to a downstream MessageEvent.
Rule File Quick Reference
When a finding relates to a project rule, cite the rule file directly:
| Area | Rule file |
|---|
| Database / Doctrine | .claude/rules/database/postgresql-rule.md |
| External API | .claude/rules/api/rest-rule.md |
| Redis / Cache | .claude/rules/cache/redis-rule.md |
| Nginx | .claude/rules/server/nginx-rule.md |
| General conventions | CLAUDE.md |