claude/dev-tools/skills/code-quality/SKILL.md
Provides code quality principles including SOLID, DRY, testing strategies, and best practices for implementation review. Use when reviewing code or applying quality standards.
npx skillsauth add sequenzia/agent-alchemy code-qualityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides code quality principles and best practices for reviewing and improving implementations.
A class/function should have one reason to change.
Bad:
class UserService {
createUser(data) { /* creates user */ }
sendEmail(user) { /* sends email */ }
generateReport(users) { /* generates report */ }
}
Good:
class UserService {
createUser(data) { /* creates user */ }
}
class EmailService {
sendEmail(user) { /* sends email */ }
}
class ReportService {
generateReport(users) { /* generates report */ }
}
Open for extension, closed for modification.
Bad: Adding new payment types requires modifying existing code
function processPayment(type, amount) {
if (type === 'credit') { /* ... */ }
else if (type === 'debit') { /* ... */ }
// Must modify to add new types
}
Good: New payment types can be added without modification
interface PaymentProcessor {
process(amount: number): Promise<void>;
}
class CreditProcessor implements PaymentProcessor { /* ... */ }
class DebitProcessor implements PaymentProcessor { /* ... */ }
Subtypes must be substitutable for their base types.
Bad:
class Bird {
fly() { /* ... */ }
}
class Penguin extends Bird {
fly() { throw new Error("Can't fly!"); } // Violates LSP
}
Good:
class Bird { /* ... */ }
class FlyingBird extends Bird {
fly() { /* ... */ }
}
class Penguin extends Bird { /* no fly method */ }
Clients shouldn't depend on interfaces they don't use.
Bad:
interface Worker {
work(): void;
eat(): void;
sleep(): void;
}
Good:
interface Workable { work(): void; }
interface Eatable { eat(): void; }
interface Sleepable { sleep(): void; }
Depend on abstractions, not concretions.
Bad:
class UserService {
private db = new PostgresDatabase();
}
Good:
class UserService {
constructor(private db: Database) {}
}
Every piece of knowledge should have a single representation.
Apply when:
Don't over-apply:
Prefer simple solutions over clever ones.
Simple code:
Don't add functionality until it's needed.
Avoid:
// Bad
const d = new Date();
const arr = users.filter(u => u.a > 18);
// Good
const currentDate = new Date();
const adultUsers = users.filter(user => user.age > 18);
// Bad: side effect hidden in getter
getUser() {
this.lastAccess = Date.now(); // Side effect!
return this.user;
}
// Good: explicit about what it does
getUser() {
return this.user;
}
recordAccess() {
this.lastAccess = Date.now();
}
// Be specific about errors
class ValidationError extends Error {}
class NotFoundError extends Error {}
class AuthorizationError extends Error {}
// Handle at appropriate level
try {
await processOrder(order);
} catch (error) {
if (error instanceof ValidationError) {
return res.status(400).json({ error: error.message });
}
if (error instanceof NotFoundError) {
return res.status(404).json({ error: error.message });
}
throw error; // Re-throw unexpected errors
}
/\
/ \ E2E Tests (few)
/────\
/ \ Integration Tests (some)
/────────\
/ \ Unit Tests (many)
/────────────\
describe('calculateTotal', () => {
it('sums item prices', () => {
const items = [{ price: 10 }, { price: 20 }];
expect(calculateTotal(items)).toBe(30);
});
it('applies discount', () => {
const items = [{ price: 100 }];
expect(calculateTotal(items, { discount: 0.1 })).toBe(90);
});
it('handles empty cart', () => {
expect(calculateTotal([])).toBe(0);
});
});
// Bad: tests implementation details
it('calls _internalMethod', () => {
const spy = jest.spyOn(service, '_internalMethod');
service.doThing();
expect(spy).toHaveBeenCalled();
});
// Good: tests behavior
it('sends welcome email on registration', async () => {
await service.registerUser({ email: '[email protected]' });
expect(emailSent).toContainEqual({
to: '[email protected]',
template: 'welcome'
});
});
| Smell | Description | Solution | |-------|-------------|----------| | Long Method | Function > 20-30 lines | Extract methods | | Large Class | Class with too many responsibilities | Split into focused classes | | Long Parameter List | > 3-4 parameters | Use parameter object | | Duplicate Code | Same code in multiple places | Extract function | | Dead Code | Unused code | Delete it | | Magic Numbers | Unexplained numeric literals | Use named constants | | Nested Conditionals | Deep if/else nesting | Early returns, extract methods | | Feature Envy | Method uses another class's data heavily | Move method to that class |
When a code block can be grouped and named
When the function body is as clear as the name
When an expression is complex
When the name doesn't communicate intent
When you have repeated switch/if statements on type
When several parameters travel together
development
Systematic, hypothesis-driven debugging workflow with triage-based track routing. Use when asked to "fix this bug", "debug this", "why is this failing", "this is broken", "investigate this error", "track down this issue", or any debugging situation. Supports --deep flag to force full investigation.
development
Executes diagnostic investigation tasks to test debugging hypotheses. Runs tests, traces execution, checks git history, and reports evidence. (converted from agent)
content-media
Provides architectural pattern knowledge for designing feature implementations including MVC, event-driven, microservices, and CQRS patterns. Use when designing system architecture or choosing implementation patterns.
documentation
Provides Mermaid diagram syntax, best practices, and styling rules for technical visualizations. Use when creating diagrams, flowcharts, sequence diagrams, class diagrams, state diagrams, ER diagrams, architecture diagrams, C4 diagrams, or any visual documentation in markdown.