# π PR Review Guide for Maintainers
**Language:** [English](PR_REVIEW_GUIDE.md) | [δΈζ](PR_REVIEW_GUIDE.zh-CN.md)
This guide is for NOFX maintainers reviewing pull requests.
---
## π Review Checklist
### 1. Initial Triage (Within 24 hours)
- [ ] **Check PR alignment with roadmap**
- Does it fit into our current priorities?
- Is it in the [roadmap](../roadmap/README.md)?
- If not, should we accept it anyway?
- [ ] **Verify PR completeness**
- All sections of PR template filled?
- Clear description of changes?
- Related issues linked?
- Screenshots/demo for UI changes?
- [ ] **Apply appropriate labels**
- Priority: critical/high/medium/low
- Type: bug/feature/enhancement/docs
- Area: frontend/backend/exchange/ai/security
- Status: needs review/needs changes
- [ ] **Assign reviewers**
- Assign based on area of expertise
- At least 1 maintainer review required
### 2. Code Review
#### A. Functionality Review
```markdown
β
**Questions to Ask:**
- Does it solve the stated problem?
- Are edge cases handled?
- Will this break existing functionality?
- Is the approach correct for our architecture?
- Are there better alternatives?
```
**Testing:**
- [ ] All CI checks passed?
- [ ] Manual testing performed by contributor?
- [ ] Test coverage adequate?
- [ ] Tests are meaningful (not just for coverage)?
#### B. Code Quality Review
**Go Backend Code:**
```go
// β Bad - Reject
func GetData(a, b string) interface{} {
d := doSomething(a, b)
return d
}
// β
Good - Approve
func GetAccountBalance(apiKey, secretKey string) (*Balance, error) {
if apiKey == "" || secretKey == "" {
return nil, fmt.Errorf("API credentials required")
}
balance, err := client.FetchBalance(apiKey, secretKey)
if err != nil {
return nil, fmt.Errorf("failed to fetch balance: %w", err)
}
return balance, nil
}
```
**Check for:**
- [ ] Meaningful variable/function names
- [ ] Proper error handling (no ignored errors)
- [ ] Comments for complex logic
- [ ] No hardcoded values (use constants/config)
- [ ] Follows Go idioms and conventions
- [ ] No unnecessary complexity
**TypeScript/React Frontend Code:**
```typescript
// β Bad - Reject
const getData = (data: any) => {
return data.map(d =>
{d.name}
)
}
// β
Good - Approve
interface Trader {
id: string;
name: string;
status: 'running' | 'stopped';
}
const TraderList: React.FC<{ traders: Trader[] }> = ({ traders }) => {
return (
{traders.map(trader => (
))}
);
};
```
**Check for:**
- [ ] Type safety (no `any` unless absolutely necessary)
- [ ] Proper React patterns (hooks, functional components)
- [ ] Component reusability
- [ ] Accessibility (a11y) considerations
- [ ] Performance optimizations (memoization where needed)
#### C. Security Review
**Critical Checks:**
```go
// π¨ REJECT - Security Issue
func Login(username, password string) {
query := "SELECT * FROM users WHERE username='" + username + "'" // SQL Injection!
db.Query(query)
}
// β
APPROVE - Secure
func Login(username, password string) error {
query := "SELECT * FROM users WHERE username = ?"
row := db.QueryRow(query, username) // Parameterized query
// ... proper password verification with bcrypt
}
```
- [ ] No SQL injection vulnerabilities
- [ ] No XSS vulnerabilities in frontend
- [ ] API keys/secrets not hardcoded
- [ ] User inputs properly validated
- [ ] Authentication/authorization properly handled
- [ ] No sensitive data in logs
- [ ] Dependencies have no known vulnerabilities
#### D. Performance Review
- [ ] No obvious performance issues
- [ ] Database queries optimized (indexes, no N+1 queries)
- [ ] No unnecessary API calls
- [ ] Proper caching where applicable
- [ ] No memory leaks
### 3. Documentation Review
- [ ] Code comments for complex logic
- [ ] README updated if needed
- [ ] API documentation updated (if API changes)
- [ ] Migration guide for breaking changes
- [ ] Changelog entry (for significant changes)
### 4. Testing Review
- [ ] Unit tests for new functions
- [ ] Integration tests for new features
- [ ] Tests actually test the functionality (not just coverage)
- [ ] Test names are descriptive
- [ ] Mock data is realistic
---
## π·οΈ Label Management
### Priority Assignment
Use these criteria to assign priority:
**Critical:**
- Security vulnerabilities
- Production-breaking bugs
- Data loss issues
**High:**
- Major bugs affecting many users
- High-priority roadmap features
- Performance issues
**Medium:**
- Regular bug fixes
- Standard feature requests
- Refactoring
**Low:**
- Minor improvements
- Code style changes
- Non-urgent documentation
### Status Workflow
```
needs review β in review β needs changes β needs review β approved β merged
β
on hold
```
**Status Labels:**
- `status: needs review` - Ready for initial review
- `status: in progress` - Being actively reviewed
- `status: needs changes` - Reviewer requested changes
- `status: on hold` - Waiting for discussion/decision
- `status: blocked` - Blocked by another PR/issue
---
## π¬ Providing Feedback
### Writing Good Review Comments
**β Bad Comments:**
```
This is wrong.
Change this.
Why did you do this?
```
**β
Good Comments:**
```
This approach might cause issues with concurrent requests.
Consider using a mutex or atomic operations here.
Suggestion: Extract this logic into a separate function for better testability:
```go
func validateTraderConfig(config *TraderConfig) error {
// validation logic
}
```
Question: Have you considered using the existing `ExchangeClient` interface
instead of creating a new one? This would maintain consistency with the rest
of the codebase.
```
### Comment Types
**π΄ Blocking (must be addressed):**
```markdown
**BLOCKING:** This introduces a SQL injection vulnerability.
Please use parameterized queries instead.
```
**π‘ Non-blocking (suggestions):**
```markdown
**Suggestion:** Consider using `strings.Builder` here for better performance
when concatenating many strings.
```
**π’ Praise (encourage good practices):**
```markdown
**Nice!** Great use of context for timeout handling. This is exactly what
we want to see.
```
### Questions vs Directives
**β Directive (can feel demanding):**
```
Change this to use the factory pattern.
Add tests for this function.
```
**β
Question (more collaborative):**
```
Would the factory pattern be a better fit here? It might make testing easier.
Could you add a test case for the error path? I want to make sure we handle
failures gracefully.
```
---
## β±οΈ Response Time Guidelines
| PR Type | Initial Review | Follow-up | Merge Decision |
|---------|---------------|-----------|----------------|
| **Critical Bug** | 4 hours | 2 hours | Same day |
| **Bounty PR** | 24 hours | 12 hours | 2-3 days |
| **Feature** | 2-3 days | 1-2 days | 3-5 days |
| **Documentation** | 2-3 days | 1-2 days | 3-5 days |
| **Large PR** | 3-5 days | 2-3 days | 5-7 days |
---
## β
Approval Criteria
A PR should be approved when:
1. **Functionality**
- β
Solves the stated problem
- β
No regression in existing features
- β
Edge cases handled
2. **Quality**
- β
Follows code standards
- β
Well-structured and readable
- β
Adequate test coverage
3. **Security**
- β
No security vulnerabilities
- β
Inputs validated
- β
Secrets properly managed
4. **Documentation**
- β
Code commented where needed
- β
Docs updated if applicable
5. **Process**
- β
All CI checks pass
- β
All review comments addressed
- β
Rebased on latest dev branch
---
## π« Rejection Criteria
Reject a PR if:
**Immediate Rejection:**
- π΄ Introduces security vulnerabilities
- π΄ Contains malicious code
- π΄ Violates Code of Conduct
- π΄ Contains plagiarized code
- π΄ Hardcoded API keys or secrets
**Request Changes:**
- π‘ Poor code quality (after feedback ignored)
- π‘ No tests for new features
- π‘ Breaking changes without migration path
- π‘ Doesn't align with roadmap (without prior discussion)
- π‘ Incomplete (missing critical parts)
**Close with Explanation:**
- π Duplicate functionality
- π Out of scope for project
- π Better alternative already exists
- π Contributor unresponsive for >2 weeks
---
## π― Special Case Reviews
### Bounty PRs
Extra care needed:
- [ ] All acceptance criteria met?
- [ ] Demo video/screenshots provided?
- [ ] Working as specified in bounty issue?
- [ ] Payment info discussed privately?
- [ ] Priority review (24h turnaround)
### Breaking Changes
- [ ] Migration guide provided?
- [ ] Deprecation warnings added?
- [ ] Version bump planned?
- [ ] Backward compatibility considered?
- [ ] RFC (Request for Comments) created for major changes?
### Security PRs
- [ ] Verified by security-focused reviewer?
- [ ] No public disclosure of vulnerability?
- [ ] Coordinated disclosure if needed?
- [ ] Security advisory prepared?
- [ ] Patch release planned?
---
## π Merge Guidelines
### When to Merge
Merge when:
- β
At least 1 approval from maintainer
- β
All CI checks passing
- β
All conversations resolved
- β
No requested changes pending
- β
Rebased on latest target branch
### Merge Strategy
**Squash Merge** (default for most PRs):
- Small bug fixes
- Single-feature PRs
- Documentation updates
- Keeps git history clean
**Merge Commit** (for complex PRs):
- Multi-commit features with logical commits
- Preserve commit history
- Large refactoring with atomic commits
**Rebase and Merge** (rarely):
- When linear history is important
- Commits are already well-structured
### Merge Commit Message
Format:
```
(): (#123)
Brief description of changes.
- Key change 1
- Key change 2
Co-authored-by: Contributor Name
```
---
## π Review Metrics to Track
Monitor these metrics monthly:
- Average time to first review
- Average time to merge
- PR acceptance rate
- Number of PRs by type (bug/feature/docs)
- Number of PRs by area (frontend/backend/exchange)
- Contributor retention rate
---
## π Questions?
If unsure about a PR:
1. **Ask other maintainers** in private channel
2. **Request more context** from contributor
3. **Mark as "on hold"** and add to next maintainer sync
4. **When in doubt, be conservative** - better to ask than approve something risky
---
## π Related Resources
- [Contributing Guide](../../CONTRIBUTING.md)
- [Code of Conduct](../../CODE_OF_CONDUCT.md)
- [Security Policy](../../SECURITY.md)
- [Project Roadmap](../roadmap/README.md)
---
**Remember:** Reviews should be **respectful**, **constructive**, and **educational**.
We're building a community, not just code. π