| name | Code Quality Engineer |
| description | Ensures code quality through reviews, refactoring, technical debt management, and clean code practices |
| when_to_use | when reviewing code, refactoring, managing technical debt, or enforcing coding standards |
| version | 1.0.0 |
| swecom_area | 3. Software Construction |
Code Quality Engineer
Overview
The Code Quality Engineer ensures code is maintainable, readable, and follows best practices. This skill provides systematic approaches to code review, refactoring, and technical debt management.
When to Use This Skill
- Conducting code reviews
- Refactoring existing code
- Managing technical debt
- Enforcing coding standards
- Improving code maintainability
- Before merging pull requests
Critical Rules
- Readability over cleverness - Simple code is better than clever code
- Test before refactoring - Never refactor without tests
- Small incremental changes - Refactor in small, safe steps
- Track technical debt - Make it visible, prioritize it
Core Principles
Clean Code Fundamentals
Meaningful Names
- Variables: Reveal intent (e.g.,
elapsedTimeInDays not d)
- Functions: Verb phrases (e.g.,
calculateTotal() not total())
- Classes: Noun phrases (e.g.,
UserRepository not Data)
- Avoid disinformation: Don't call something
accountList if it's not a List
Functions
- Small: 5-20 lines ideal, rarely >50 lines
- Single responsibility: Do one thing well
- Few parameters: 0-2 ideal, max 3 (use objects for more)
- No side effects: Function name should describe everything it does
- Command-Query Separation: Either do something OR answer something, not both
Comments
- Code should explain itself: Good names > comments
- Use comments for WHY, not WHAT: Explain intent, not mechanics
- No commented-out code: Use version control
- Update or remove outdated comments: Lies are worse than no comments
SOLID Principles
S - Single Responsibility Principle
Definition: A class should have one, and only one, reason to change.
Bad:
class User {
save() { }
sendEmail() { }
generateReport() { }
}
Good:
class User {
}
class UserRepository {
save(user: User) { }
}
class EmailService {
sendWelcomeEmail(user: User) { }
}
O - Open/Closed Principle
Definition: Open for extension, closed for modification.
Bad:
class PaymentProcessor {
process(type: string) {
if (type === 'credit') { }
else if (type === 'paypal') { }
}
}
Good:
interface PaymentMethod {
process(amount: Money): void;
}
class CreditCardPayment implements PaymentMethod {
process(amount: Money) { }
}
class PayPalPayment implements PaymentMethod {
process(amount: Money) { }
}
class PaymentProcessor {
process(method: PaymentMethod, amount: Money) {
method.process(amount);
}
}
L - Liskov Substitution Principle
Definition: Subtypes must be substitutable for their base types.
Violation:
class Rectangle {
setWidth(w: number) { this.width = w; }
setHeight(h: number) { this.height = h; }
}
class Square extends Rectangle {
setWidth(w: number) {
this.width = w;
this.height = w;
}
}
I - Interface Segregation Principle
Definition: Many specific interfaces are better than one general interface.
Bad:
interface Worker {
work(): void;
eat(): void;
sleep(): void;
}
class Robot implements Worker {
work() { }
eat() { }
sleep() { }
}
Good:
interface Workable {
work(): void;
}
interface Eatable {
eat(): void;
}
class Human implements Workable, Eatable {
work() { }
eat() { }
}
class Robot implements Workable {
work() { }
}
D - Dependency Inversion Principle
Definition: Depend on abstractions, not concretions.
Bad:
class OrderService {
private db = new MySQLDatabase();
saveOrder(order: Order) {
this.db.save(order);
}
}
Good:
interface Database {
save(entity: any): void;
}
class OrderService {
constructor(private db: Database) {}
saveOrder(order: Order) {
this.db.save(order);
}
}
Code Review Process
Pre-Review Checklist (Author)
Before requesting review:
Review Checklist (Reviewer)
Functionality
Design
Readability
Testing
Security
Performance
Review Feedback Guidelines
Good Feedback:
- Be specific: "Extract this 50-line function into smaller functions"
- Explain why: "This violates SRP because it handles validation AND persistence"
- Suggest alternatives: "Consider using Strategy pattern here"
- Reference standards: "This doesn't follow our error handling convention"
Poor Feedback:
- Vague: "This is wrong"
- Personal: "I don't like this"
- No context: "Refactor this"
Refactoring Strategies
When to Refactor
Refactor when you see:
- Duplicate code (DRY violation)
- Long functions (>50 lines)
- Large classes (>300 lines)
- Long parameter lists (>3 params)
- Divergent change (one class changes for multiple reasons)
- Shotgun surgery (one change requires editing many classes)
- Feature envy (method uses another class more than its own)
- Data clumps (same group of data appears together)
Refactoring Process
- Ensure tests exist - Never refactor without test coverage
- Make one change at a time - Small, incremental steps
- Run tests after each change - Verify nothing breaks
- Commit frequently - Easy rollback if needed
Common Refactorings
Extract Method
Before:
function printInvoice(invoice: Invoice) {
console.log("Invoice Details:");
console.log(`Customer: ${invoice.customer.name}`);
console.log(`Total: $${invoice.total}`);
let tax = 0;
for (const item of invoice.items) {
tax += item.price * 0.1;
}
console.log(`Tax: $${tax}`);
}
After:
function printInvoice(invoice: Invoice) {
printHeader(invoice);
printTax(invoice);
}
function printHeader(invoice: Invoice) {
console.log("Invoice Details:");
console.log(`Customer: ${invoice.customer.name}`);
console.log(`Total: $${invoice.total}`);
}
function printTax(invoice: Invoice) {
const tax = calculateTax(invoice);
console.log(`Tax: $${tax}`);
}
function calculateTax(invoice: Invoice): number {
return invoice.items.reduce((sum, item) => sum + item.price * 0.1, 0);
}
Replace Conditional with Polymorphism
Before:
function getSpeed(vehicle: Vehicle): number {
switch (vehicle.type) {
case 'car': return vehicle.enginePower * 2;
case 'bike': return vehicle.pedalPower * 3;
case 'boat': return vehicle.motorPower * 1.5;
}
}
After:
abstract class Vehicle {
abstract getSpeed(): number;
}
class Car extends Vehicle {
getSpeed() { return this.enginePower * 2; }
}
class Bike extends Vehicle {
getSpeed() { return this.pedalPower * 3; }
}
class Boat extends Vehicle {
getSpeed() { return this.motorPower * 1.5; }
}
Introduce Parameter Object
Before:
function createOrder(
customerId: string,
customerName: string,
customerEmail: string,
shippingAddress: string,
shippingCity: string,
shippingZip: string
) {
}
After:
interface OrderParams {
customer: Customer;
shipping: Address;
}
function createOrder(params: OrderParams) {
}
Technical Debt Management
What is Technical Debt?
Definition: The implied cost of additional rework caused by choosing an easy (limited) solution now instead of a better approach that would take longer.
Types:
- Deliberate Debt: Conscious shortcuts for deadlines
- Accidental Debt: Unknowingly poor decisions
- Bit Rot: Code quality degrades over time
Tracking Technical Debt
In Code:
class UserController {
}
In Issues/Tickets:
## Technical Debt: Extract Authentication Logic
**Location**: `controllers/UserController.ts`
**Impact**: Medium (makes testing difficult, violates SRP)
**Effort**: 2 days
**Priority**: High
**Related to**: Feature XYZ (created this debt for deadline)
### Proposed Solution
Extract authentication to AuthService, inject via DI
Prioritizing Technical Debt
Matrix:
| Impact | Effort | Priority |
|---|
| High | Low | CRITICAL - Do now |
| High | High | Important - Schedule |
| Low | Low | Quick win - Do when free |
| Low | High | Defer - Reconsider later |
Debt Reduction Strategies
- Boy Scout Rule: Leave code better than you found it
- Dedicated refactoring sprints: 20% time for debt
- Debt budget: Max X debt items per quarter
- No new features until critical debt paid: For severe cases
Code Metrics
Key Metrics to Track
Cyclomatic Complexity
Definition: Number of linearly independent paths through code
Threshold:
- 1-10: Simple, low risk
- 11-20: Moderate complexity
- 21-50: High complexity, hard to test
- 50+: Untestable, refactor immediately
Code Coverage
Definition: Percentage of code executed by tests
Thresholds:
- <60%: Insufficient
- 60-80%: Adequate
- 80-90%: Good
- >90%: Excellent (but beware of diminishing returns)
Note: Coverage is necessary but not sufficient - must test the right things
Code Duplication
Definition: Percentage of duplicated code
Threshold: <3% duplication (stricter than general standards)
Maintainability Index
Definition: Composite metric (0-100) based on complexity, lines of code, and Halstead volume
Thresholds:
- 0-9: Unmaintainable
- 10-19: Difficult to maintain
- 20-100: Maintainable
Tools Integration
Static Analysis Tools
TypeScript/JavaScript:
- ESLint (linting)
- Prettier (formatting)
- SonarQube (quality analysis)
- TypeScript compiler (type checking)
Python:
- Pylint, Flake8 (linting)
- Black (formatting)
- mypy (type checking)
- Bandit (security)
Configuration Example (ESLint):
{
"rules": {
"complexity": ["error", 10],
"max-lines-per-function": ["warn", 50],
"max-params": ["error", 3],
"no-console": "error"
}
}
Output Format
After code review or refactoring session:
# Code Quality Review: [Feature/File Name]
## Summary
- Files reviewed: 5
- Issues found: 12 (3 critical, 5 moderate, 4 minor)
- Refactoring opportunities: 3
## Critical Issues
### 1. Authentication logic in UserController (SRP violation)
**File**: `controllers/UserController.ts:45-89`
**Issue**: Controller handles both HTTP and authentication logic
**Impact**: High - makes unit testing impossible, tight coupling
**Solution**: Extract to AuthService, inject via DI
**Effort**: 2 days
**Priority**: Critical
## Moderate Issues
### 2. Duplicate validation logic
**Files**: `UserService.ts:23`, `OrderService.ts:67`, `ProductService.ts:34`
**Issue**: Same email validation in 3 places
**Impact**: Medium - inconsistent behavior, hard to change
**Solution**: Extract to `EmailValidator` utility
**Effort**: 2 hours
**Priority**: Medium
## Minor Issues
### 3. Magic numbers
**File**: `PaymentService.ts:56`
**Issue**: Hardcoded `0.1` for tax rate
**Solution**: Extract to `TAX_RATE` constant
**Effort**: 5 minutes
**Priority**: Low
## Refactoring Recommendations
### 1. Extract Method - `calculateOrderTotal()`
**File**: `OrderService.ts:123-178`
**Reason**: 55-line function doing 3 things (validation, calculation, tax)
**Suggestion**: Extract `validateOrder()`, `calculateSubtotal()`, `calculateTax()`
## Code Metrics
| Metric | Before | After | Target |
|--------|--------|-------|--------|
| Cyclomatic Complexity | 23 | 12 | <10 |
| Code Coverage | 67% | 85% | >80% |
| Duplication | 8% | 2% | <3% |
| Maintainability Index | 45 | 72 | >60 |
## Technical Debt Tracking
New debt items added to backlog:
- DEBT-123: Extract authentication logic (Priority: Critical)
- DEBT-124: Centralize validation (Priority: Medium)
## Next Steps
- [ ] Author addresses critical issues
- [ ] Re-review after changes
- [ ] Merge if all critical issues resolved
Boundaries
This skill does NOT:
- Write new features (that's implementation)
- Make architectural decisions (that's System Architect)
- Test code (that's QAS Agent)
This skill DOES:
- Review code for quality
- Identify refactoring opportunities
- Track and prioritize technical debt
- Enforce clean code principles
- Measure code quality metrics
Related Skills
- TDD (
/Users/brooke/.config/superpowers/skills/skills/testing/test-driven-development/SKILL.md) - Write tests before refactoring
- Systematic Debugging (
/Users/brooke/.config/superpowers/skills/skills/debugging/systematic-debugging/SKILL.md) - Debug code quality issues
- System Architect (
~/.claude/skills/lifecycle/design/architecture/SKILL.md) - Provides architectural guidance
Resources
Books
- Clean Code - Robert C. Martin
- Refactoring - Martin Fowler
- Working Effectively with Legacy Code - Michael Feathers
Tools
- SonarQube - Quality analysis
- CodeClimate - Technical debt tracking
- Codecov - Coverage tracking
Version History
- 1.0.0 (2025-10-17): Initial skill creation (SWECOM gap fill)