- Add validator_type field to scans and violations (architecture, security, performance) - Create security validator with SEC-xxx rules - Create performance validator with PERF-xxx rules - Add base validator class for shared functionality - Add validate_all.py script to run all validators - Update code quality service with validator type filtering - Add validator type tabs to dashboard UI - Add validator type filter to violations list - Update stats response with per-validator breakdown - Add security and performance rules documentation - Add chat-bubble icons to icon library 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
136 lines
4.0 KiB
YAML
136 lines
4.0 KiB
YAML
# API Performance Rules
|
|
# =====================
|
|
|
|
api_rules:
|
|
- id: "PERF-026"
|
|
name: "Pagination required for list endpoints"
|
|
severity: error
|
|
description: |
|
|
All list endpoints must support pagination.
|
|
Unbounded lists cause performance issues:
|
|
- Memory exhaustion
|
|
- Slow response times
|
|
- Database locks
|
|
file_pattern: "**/api/**/*.py"
|
|
anti_patterns:
|
|
- '@router\\.get\\([^)]*\\)\\s*\\n(?:(?!limit|skip|offset|page).)*def\\s+\\w+.*:\\s*\\n(?:(?!limit|skip|offset|page).)*return.*\\.all\\(\\)'
|
|
required_patterns:
|
|
- "limit|skip|offset|page"
|
|
example_bad: |
|
|
@router.get("/products")
|
|
def list_products(db: Session):
|
|
return db.query(Product).all()
|
|
example_good: |
|
|
@router.get("/products")
|
|
def list_products(
|
|
skip: int = 0,
|
|
limit: int = Query(default=20, le=100),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
return db.query(Product).offset(skip).limit(limit).all()
|
|
|
|
- id: "PERF-027"
|
|
name: "Reasonable default page sizes"
|
|
severity: warning
|
|
description: |
|
|
Default page sizes should be reasonable:
|
|
- Default: 20-50 items
|
|
- Maximum: 100-200 items
|
|
|
|
Very large page sizes negate pagination benefits.
|
|
file_pattern: "**/api/**/*.py"
|
|
anti_patterns:
|
|
- 'limit.*=.*Query\\([^)]*default\\s*=\\s*[5-9]\\d{2,}'
|
|
- 'limit.*=.*Query\\([^)]*le\\s*=\\s*[1-9]\\d{3,}'
|
|
example_bad: |
|
|
limit: int = Query(default=500, le=10000)
|
|
example_good: |
|
|
limit: int = Query(default=20, ge=1, le=100)
|
|
|
|
- id: "PERF-028"
|
|
name: "Response compression"
|
|
severity: info
|
|
description: |
|
|
Enable response compression for large responses:
|
|
- GZip or Brotli
|
|
- Significant bandwidth savings
|
|
- Faster load times
|
|
file_pattern: "**/main.py|**/app.py"
|
|
suggested_patterns:
|
|
- "GZipMiddleware|BrotliMiddleware|compress"
|
|
|
|
- id: "PERF-029"
|
|
name: "Efficient serialization"
|
|
severity: info
|
|
description: |
|
|
Use Pydantic's response_model for efficient serialization.
|
|
Avoid manual dict conversion.
|
|
file_pattern: "**/api/**/*.py"
|
|
anti_patterns:
|
|
- 'return\\s+\\{[^}]*for\\s+\\w+\\s+in'
|
|
- 'return\\s+\\[\\{.*for.*in.*\\]'
|
|
suggested_patterns:
|
|
- "response_model"
|
|
|
|
- id: "PERF-030"
|
|
name: "Avoid redundant queries in response"
|
|
severity: warning
|
|
description: |
|
|
Don't trigger lazy-loaded relationships during serialization.
|
|
Use eager loading or carefully control serialization.
|
|
file_pattern: "**/api/**/*.py"
|
|
|
|
- id: "PERF-031"
|
|
name: "Streaming for large responses"
|
|
severity: info
|
|
description: |
|
|
Use streaming responses for large data:
|
|
- File downloads
|
|
- Large exports (CSV, JSON)
|
|
- Real-time data feeds
|
|
file_pattern: "**/api/**/*.py"
|
|
suggested_patterns:
|
|
- "StreamingResponse|yield|generator"
|
|
|
|
- id: "PERF-032"
|
|
name: "Conditional requests support"
|
|
severity: info
|
|
description: |
|
|
Support conditional requests to reduce bandwidth:
|
|
- ETag validation
|
|
- If-None-Match handling
|
|
- 304 Not Modified responses
|
|
file_pattern: "**/api/**/*.py"
|
|
suggested_patterns:
|
|
- "ETag|If-None-Match|304"
|
|
|
|
- id: "PERF-033"
|
|
name: "Field selection support"
|
|
severity: info
|
|
description: |
|
|
Allow clients to request only needed fields.
|
|
Reduces response size and serialization cost.
|
|
file_pattern: "**/api/**/*.py"
|
|
suggested_patterns:
|
|
- "fields|include|exclude|sparse"
|
|
|
|
- id: "PERF-034"
|
|
name: "Avoid deep nesting in responses"
|
|
severity: info
|
|
description: |
|
|
Deeply nested responses are slow to serialize.
|
|
Consider flattening or using links instead.
|
|
file_pattern: "**/api/**/*.py"
|
|
|
|
- id: "PERF-035"
|
|
name: "Endpoint response time monitoring"
|
|
severity: info
|
|
description: |
|
|
Monitor API response times:
|
|
- Set SLA targets
|
|
- Alert on degradation
|
|
- Track percentiles (p50, p95, p99)
|
|
file_pattern: "**/main.py|**/middleware*.py"
|
|
suggested_patterns:
|
|
- "prometheus|metrics|timing|latency"
|