@qazuor/claude-code-config 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1248 -0
- package/dist/bin.cjs +11886 -0
- package/dist/bin.cjs.map +1 -0
- package/dist/bin.d.cts +1 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +11869 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.cjs +3887 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1325 -0
- package/dist/index.d.ts +1325 -0
- package/dist/index.js +3835 -0
- package/dist/index.js.map +1 -0
- package/package.json +86 -0
- package/templates/.log/notifications.log +1775 -0
- package/templates/agents/README.md +164 -0
- package/templates/agents/_registry.json +443 -0
- package/templates/agents/design/content-writer.md +353 -0
- package/templates/agents/design/ux-ui-designer.md +382 -0
- package/templates/agents/engineering/astro-engineer.md +293 -0
- package/templates/agents/engineering/db-drizzle-engineer.md +360 -0
- package/templates/agents/engineering/express-engineer.md +316 -0
- package/templates/agents/engineering/fastify-engineer.md +399 -0
- package/templates/agents/engineering/hono-engineer.md +263 -0
- package/templates/agents/engineering/mongoose-engineer.md +473 -0
- package/templates/agents/engineering/nestjs-engineer.md +429 -0
- package/templates/agents/engineering/nextjs-engineer.md +451 -0
- package/templates/agents/engineering/node-typescript-engineer.md +347 -0
- package/templates/agents/engineering/prisma-engineer.md +432 -0
- package/templates/agents/engineering/react-senior-dev.md +394 -0
- package/templates/agents/engineering/tanstack-start-engineer.md +447 -0
- package/templates/agents/engineering/tech-lead.md +269 -0
- package/templates/agents/product/product-functional.md +329 -0
- package/templates/agents/product/product-technical.md +578 -0
- package/templates/agents/quality/debugger.md +514 -0
- package/templates/agents/quality/qa-engineer.md +390 -0
- package/templates/agents/specialized/enrichment-agent.md +277 -0
- package/templates/agents/specialized/i18n-specialist.md +322 -0
- package/templates/agents/specialized/seo-ai-specialist.md +387 -0
- package/templates/agents/specialized/tech-writer.md +300 -0
- package/templates/code-style/.editorconfig +27 -0
- package/templates/code-style/.prettierignore +25 -0
- package/templates/code-style/.prettierrc +12 -0
- package/templates/code-style/biome.json +78 -0
- package/templates/code-style/commitlint.config.js +44 -0
- package/templates/commands/README.md +175 -0
- package/templates/commands/_registry.json +420 -0
- package/templates/commands/add-new-entity.md +211 -0
- package/templates/commands/audit/accessibility-audit.md +360 -0
- package/templates/commands/audit/performance-audit.md +290 -0
- package/templates/commands/audit/security-audit.md +231 -0
- package/templates/commands/code-check.md +127 -0
- package/templates/commands/five-why.md +225 -0
- package/templates/commands/formatting/format-markdown.md +197 -0
- package/templates/commands/git/commit.md +247 -0
- package/templates/commands/meta/create-agent.md +257 -0
- package/templates/commands/meta/create-command.md +312 -0
- package/templates/commands/meta/create-skill.md +321 -0
- package/templates/commands/meta/help.md +318 -0
- package/templates/commands/planning/check-completed-tasks.md +224 -0
- package/templates/commands/planning/cleanup-issues.md +248 -0
- package/templates/commands/planning/planning-cleanup.md +251 -0
- package/templates/commands/planning/sync-planning-github.md +133 -0
- package/templates/commands/planning/sync-todos-github.md +203 -0
- package/templates/commands/quality-check.md +211 -0
- package/templates/commands/run-tests.md +159 -0
- package/templates/commands/start-feature-plan.md +232 -0
- package/templates/commands/start-refactor-plan.md +244 -0
- package/templates/commands/sync-planning.md +176 -0
- package/templates/commands/update-docs.md +242 -0
- package/templates/docs/CHECKPOINT-SYSTEM.md +504 -0
- package/templates/docs/INDEX.md +677 -0
- package/templates/docs/RECOMMENDED-HOOKS.md +415 -0
- package/templates/docs/_registry.json +329 -0
- package/templates/docs/diagrams/README.md +220 -0
- package/templates/docs/diagrams/agent-hierarchy.mmd +55 -0
- package/templates/docs/diagrams/documentation-map.mmd +61 -0
- package/templates/docs/diagrams/tools-relationship.mmd +55 -0
- package/templates/docs/diagrams/workflow-decision-tree.mmd +38 -0
- package/templates/docs/doc-sync.md +533 -0
- package/templates/docs/examples/end-to-end-workflow.md +1505 -0
- package/templates/docs/glossary.md +495 -0
- package/templates/docs/guides/mockup-prompt-engineering.md +644 -0
- package/templates/docs/guides/mockup-setup.md +737 -0
- package/templates/docs/learnings/README.md +250 -0
- package/templates/docs/learnings/common-architectural-patterns.md +123 -0
- package/templates/docs/learnings/common-mistakes-to-avoid.md +149 -0
- package/templates/docs/learnings/markdown-formatting-standards.md +104 -0
- package/templates/docs/learnings/monorepo-command-execution.md +64 -0
- package/templates/docs/learnings/optimization-tips.md +146 -0
- package/templates/docs/learnings/planning-linear-sync-workflow.md +70 -0
- package/templates/docs/learnings/shell-compatibility-fish.md +46 -0
- package/templates/docs/learnings/test-organization-structure.md +68 -0
- package/templates/docs/mcp-installation.md +613 -0
- package/templates/docs/mcp-servers.md +989 -0
- package/templates/docs/notification-installation.md +570 -0
- package/templates/docs/quick-start.md +354 -0
- package/templates/docs/standards/architecture-patterns.md +1064 -0
- package/templates/docs/standards/atomic-commits.md +513 -0
- package/templates/docs/standards/code-standards.md +993 -0
- package/templates/docs/standards/design-standards.md +656 -0
- package/templates/docs/standards/documentation-standards.md +1160 -0
- package/templates/docs/standards/testing-standards.md +969 -0
- package/templates/docs/system-maintenance.md +604 -0
- package/templates/docs/templates/PDR-template.md +561 -0
- package/templates/docs/templates/TODOs-template.md +534 -0
- package/templates/docs/templates/tech-analysis-template.md +800 -0
- package/templates/docs/workflows/README.md +519 -0
- package/templates/docs/workflows/atomic-task-protocol.md +955 -0
- package/templates/docs/workflows/decision-tree.md +482 -0
- package/templates/docs/workflows/edge-cases.md +856 -0
- package/templates/docs/workflows/phase-1-planning.md +957 -0
- package/templates/docs/workflows/phase-2-implementation.md +896 -0
- package/templates/docs/workflows/phase-3-validation.md +792 -0
- package/templates/docs/workflows/phase-4-finalization.md +927 -0
- package/templates/docs/workflows/quick-fix-protocol.md +505 -0
- package/templates/docs/workflows/task-atomization.md +537 -0
- package/templates/docs/workflows/task-completion-protocol.md +448 -0
- package/templates/hooks/on-notification.sh +28 -0
- package/templates/schemas/checkpoint.schema.json +97 -0
- package/templates/schemas/code-registry.schema.json +84 -0
- package/templates/schemas/pdr.schema.json +314 -0
- package/templates/schemas/problems.schema.json +55 -0
- package/templates/schemas/tech-analysis.schema.json +404 -0
- package/templates/schemas/telemetry.schema.json +298 -0
- package/templates/schemas/todos.schema.json +234 -0
- package/templates/schemas/workflows.schema.json +69 -0
- package/templates/scripts/add-changelogs.sh +105 -0
- package/templates/scripts/generate-code-registry.ts +270 -0
- package/templates/scripts/health-check.sh +343 -0
- package/templates/scripts/sync-registry.sh +40 -0
- package/templates/scripts/telemetry-report.ts +36 -0
- package/templates/scripts/validate-docs.sh +224 -0
- package/templates/scripts/validate-registry.sh +225 -0
- package/templates/scripts/validate-schemas.ts +283 -0
- package/templates/scripts/validate-structure.sh +165 -0
- package/templates/scripts/worktree-cleanup.sh +81 -0
- package/templates/scripts/worktree-create.sh +63 -0
- package/templates/sessions/planning/.gitkeep +0 -0
- package/templates/sessions/planning/archived/.gitkeep +0 -0
- package/templates/settings.json +202 -0
- package/templates/settings.local.json +138 -0
- package/templates/skills/README.md +197 -0
- package/templates/skills/_registry.json +473 -0
- package/templates/skills/audit/accessibility-audit.md +309 -0
- package/templates/skills/audit/performance-audit.md +257 -0
- package/templates/skills/audit/security-audit.md +217 -0
- package/templates/skills/auth/nextauth-patterns.md +308 -0
- package/templates/skills/brand-guidelines.md +240 -0
- package/templates/skills/documentation/markdown-formatter.md +302 -0
- package/templates/skills/git/git-commit-helper.md +321 -0
- package/templates/skills/i18n/i18n-patterns.md +251 -0
- package/templates/skills/patterns/error-handling-patterns.md +242 -0
- package/templates/skills/patterns/tdd-methodology.md +342 -0
- package/templates/skills/qa/qa-criteria-validator.md +383 -0
- package/templates/skills/qa/web-app-testing.md +398 -0
- package/templates/skills/react/react-hook-form-patterns.md +359 -0
- package/templates/skills/state/redux-toolkit-patterns.md +272 -0
- package/templates/skills/state/tanstack-query-patterns.md +299 -0
- package/templates/skills/state/zustand-patterns.md +301 -0
- package/templates/skills/tech/mermaid-diagram-specialist.md +195 -0
- package/templates/skills/tech/shadcn-specialist.md +252 -0
- package/templates/skills/tech/vercel-specialist.md +297 -0
- package/templates/skills/testing/api-app-testing.md +254 -0
- package/templates/skills/testing/performance-testing.md +275 -0
- package/templates/skills/testing/security-testing.md +348 -0
- package/templates/skills/utils/add-memory.md +295 -0
- package/templates/skills/utils/json-data-auditor.md +283 -0
- package/templates/skills/utils/pdf-creator-editor.md +342 -0
- package/templates/tools/format-markdown.sh +185 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: error-handling-patterns
|
|
3
|
+
category: patterns
|
|
4
|
+
description: Standardized error handling patterns for database, API, and frontend layers
|
|
5
|
+
usage: Use when implementing error handling across application layers
|
|
6
|
+
input: Error scenarios, application context, error types
|
|
7
|
+
output: Error handling code, custom error classes
|
|
8
|
+
config_required:
|
|
9
|
+
database_error_codes: "Database-specific error codes mapping (e.g., PostgreSQL, MySQL)"
|
|
10
|
+
http_status_codes: "HTTP status codes used in API responses"
|
|
11
|
+
error_logging_service: "Error logging service (e.g., Sentry, LogRocket, console)"
|
|
12
|
+
frontend_framework: "Frontend framework (React, Vue, Angular, etc.)"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Error Handling Patterns
|
|
16
|
+
|
|
17
|
+
## ⚙️ Configuration
|
|
18
|
+
|
|
19
|
+
| Setting | Description | Example |
|
|
20
|
+
|---------|-------------|---------|
|
|
21
|
+
| `database_error_codes` | Database-specific error codes for constraint violations | PostgreSQL: `23505` (unique), `23503` (foreign key) |
|
|
22
|
+
| `http_status_codes` | HTTP status codes for different error types | `400` (validation), `404` (not found), `500` (server) |
|
|
23
|
+
| `error_logging_service` | Service for logging unexpected errors | Sentry, LogRocket, console |
|
|
24
|
+
| `frontend_framework` | Framework for UI error boundaries | React, Vue, Angular |
|
|
25
|
+
|
|
26
|
+
## Purpose
|
|
27
|
+
|
|
28
|
+
Provide consistent, type-safe error handling across database, service, API, and frontend layers with:
|
|
29
|
+
- Custom error class hierarchy
|
|
30
|
+
- Secure error messages (no internal leaks)
|
|
31
|
+
- Operational vs programming error distinction
|
|
32
|
+
- Proper error propagation
|
|
33
|
+
|
|
34
|
+
## Error Class Hierarchy
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Base application error
|
|
38
|
+
export class AppError extends Error {
|
|
39
|
+
constructor(
|
|
40
|
+
message: string,
|
|
41
|
+
public statusCode: number,
|
|
42
|
+
public code: string,
|
|
43
|
+
public isOperational = true
|
|
44
|
+
) {
|
|
45
|
+
super(message);
|
|
46
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
47
|
+
Error.captureStackTrace(this);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Domain-specific errors
|
|
52
|
+
export class ValidationError extends AppError {
|
|
53
|
+
constructor(message: string, public fields?: Record<string, string>) {
|
|
54
|
+
super(message, 400, 'VALIDATION_ERROR');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export class NotFoundError extends AppError {
|
|
59
|
+
constructor(resource: string, id?: string) {
|
|
60
|
+
super(`${resource}${id ? ` with id ${id}` : ''} not found`, 404, 'NOT_FOUND');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class UnauthorizedError extends AppError {
|
|
65
|
+
constructor(message = 'Unauthorized') {
|
|
66
|
+
super(message, 401, 'UNAUTHORIZED');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class ConflictError extends AppError {
|
|
71
|
+
constructor(message: string) {
|
|
72
|
+
super(message, 409, 'CONFLICT');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Layer-Specific Patterns
|
|
78
|
+
|
|
79
|
+
### Database Layer
|
|
80
|
+
|
|
81
|
+
| Pattern | When to Use | Example |
|
|
82
|
+
|---------|-------------|---------|
|
|
83
|
+
| Resource Not Found | Record doesn't exist | Throw `NotFoundError` |
|
|
84
|
+
| Constraint Violation | Unique, FK violations | Map DB codes to `ConflictError`/`ValidationError` |
|
|
85
|
+
| Unexpected Error | Unknown DB errors | Throw `AppError` with `isOperational: false` |
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
try {
|
|
89
|
+
const record = await db.table.findFirst({ where: eq(table.id, id) });
|
|
90
|
+
if (!record) throw new NotFoundError('Resource', id);
|
|
91
|
+
return record;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (error instanceof AppError) throw error;
|
|
94
|
+
|
|
95
|
+
// Map database-specific codes
|
|
96
|
+
if (error.code === '23505') {
|
|
97
|
+
throw new ConflictError('Resource already exists');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
throw new AppError('Database operation failed', 500, 'DATABASE_ERROR', false);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Service Layer
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async create(data: Input): Promise<Output> {
|
|
108
|
+
// Validate business rules
|
|
109
|
+
if (data.startDate >= data.endDate) {
|
|
110
|
+
throw new ValidationError('End date must be after start date', {
|
|
111
|
+
startDate: 'Must be before end date',
|
|
112
|
+
endDate: 'Must be after start date'
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Check availability
|
|
117
|
+
const isAvailable = await this.checkAvailability(data);
|
|
118
|
+
if (!isAvailable) {
|
|
119
|
+
throw new ConflictError('Resource not available');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
return await this.repository.create(data);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error instanceof AppError) throw error;
|
|
126
|
+
throw new AppError('Create failed', 500, 'CREATE_FAILED', false);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### API Layer
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Global error handler
|
|
135
|
+
export const errorHandler = async (err: Error, context: Context) => {
|
|
136
|
+
// Log non-operational errors
|
|
137
|
+
if (err instanceof AppError && !err.isOperational) {
|
|
138
|
+
console.error('Non-operational error:', err);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Handle operational errors
|
|
142
|
+
if (err instanceof AppError) {
|
|
143
|
+
return context.json({
|
|
144
|
+
error: {
|
|
145
|
+
code: err.code,
|
|
146
|
+
message: err.message,
|
|
147
|
+
...(err instanceof ValidationError && { fields: err.fields })
|
|
148
|
+
}
|
|
149
|
+
}, err.statusCode);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Schema validation errors
|
|
153
|
+
if (err instanceof ZodError) {
|
|
154
|
+
return context.json({
|
|
155
|
+
error: {
|
|
156
|
+
code: 'VALIDATION_ERROR',
|
|
157
|
+
message: 'Invalid request data',
|
|
158
|
+
fields: err.flatten().fieldErrors
|
|
159
|
+
}
|
|
160
|
+
}, 400);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Unknown errors (sanitized)
|
|
164
|
+
console.error('Unexpected error:', err);
|
|
165
|
+
return context.json({
|
|
166
|
+
error: {
|
|
167
|
+
code: 'INTERNAL_ERROR',
|
|
168
|
+
message: 'An unexpected error occurred'
|
|
169
|
+
}
|
|
170
|
+
}, 500);
|
|
171
|
+
};
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Frontend Layer
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Error Boundary (React)
|
|
178
|
+
export class ErrorBoundary extends React.Component<Props, State> {
|
|
179
|
+
state = { hasError: false, error: null };
|
|
180
|
+
|
|
181
|
+
static getDerivedStateFromError(error: Error) {
|
|
182
|
+
return { hasError: true, error };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
186
|
+
console.error('Error boundary caught:', error, errorInfo);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
render() {
|
|
190
|
+
if (this.state.hasError) {
|
|
191
|
+
return <ErrorFallback error={this.state.error} />;
|
|
192
|
+
}
|
|
193
|
+
return this.props.children;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Query error handling
|
|
198
|
+
const { data, error } = useQuery({
|
|
199
|
+
queryFn: async () => {
|
|
200
|
+
const response = await fetch('/api/resource');
|
|
201
|
+
if (!response.ok) {
|
|
202
|
+
const error = await response.json();
|
|
203
|
+
throw new Error(error.error.message);
|
|
204
|
+
}
|
|
205
|
+
return response.json();
|
|
206
|
+
},
|
|
207
|
+
retry: (failureCount, error) => {
|
|
208
|
+
// Don't retry client errors
|
|
209
|
+
if (error.message.includes('400') || error.message.includes('404')) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
// Retry server errors up to 3 times
|
|
213
|
+
return failureCount < 3;
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Best Practices
|
|
219
|
+
|
|
220
|
+
| Practice | Description |
|
|
221
|
+
|----------|-------------|
|
|
222
|
+
| **Custom Error Classes** | Use domain-specific errors for clarity |
|
|
223
|
+
| **Fail Fast** | Validate early, throw errors immediately |
|
|
224
|
+
| **Preserve Stack Traces** | Use `Error.captureStackTrace` |
|
|
225
|
+
| **Don't Leak Internals** | Sanitize error messages in production |
|
|
226
|
+
| **Log Unexpected Errors** | Always log non-operational errors |
|
|
227
|
+
| **Type-Safe Errors** | Use TypeScript for error types |
|
|
228
|
+
| **Operational vs Programming** | Distinguish between expected and unexpected errors |
|
|
229
|
+
| **Error Boundaries** | Catch UI errors with error boundaries |
|
|
230
|
+
|
|
231
|
+
## Anti-Patterns to Avoid
|
|
232
|
+
|
|
233
|
+
- ❌ Catching all errors without handling them
|
|
234
|
+
- ❌ Exposing stack traces in production
|
|
235
|
+
- ❌ Generic error messages without context
|
|
236
|
+
- ❌ Silently swallowing errors
|
|
237
|
+
- ❌ Using error codes inconsistently
|
|
238
|
+
|
|
239
|
+
## Related Skills
|
|
240
|
+
|
|
241
|
+
- `tdd-methodology` - Test error scenarios
|
|
242
|
+
- `api-app-testing` - Test error responses
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd-methodology
|
|
3
|
+
category: patterns
|
|
4
|
+
description: Test-Driven Development workflow (RED-GREEN-REFACTOR) ensuring quality and coverage
|
|
5
|
+
usage: Use when implementing features to ensure testability and design quality
|
|
6
|
+
input: Feature requirements, acceptance criteria, technical specifications
|
|
7
|
+
output: Tests written before implementation, well-designed code with high coverage
|
|
8
|
+
config_required:
|
|
9
|
+
- TEST_FRAMEWORK: "Test framework to use (e.g., Vitest, Jest)"
|
|
10
|
+
- COVERAGE_TARGET: "Minimum coverage percentage (e.g., 90%)"
|
|
11
|
+
- TEST_COMMAND: "Command to run tests (e.g., pnpm test)"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# TDD Methodology
|
|
15
|
+
|
|
16
|
+
## ⚙️ Configuration
|
|
17
|
+
|
|
18
|
+
| Setting | Description | Example |
|
|
19
|
+
|---------|-------------|---------|
|
|
20
|
+
| TEST_FRAMEWORK | Test framework | `Vitest`, `Jest`, `Mocha` |
|
|
21
|
+
| COVERAGE_TARGET | Minimum coverage | `90%` |
|
|
22
|
+
| TEST_COMMAND | Run tests command | `pnpm test`, `npm test` |
|
|
23
|
+
| WATCH_COMMAND | Watch mode command | `pnpm test:watch` |
|
|
24
|
+
| COVERAGE_COMMAND | Coverage command | `pnpm test:coverage` |
|
|
25
|
+
|
|
26
|
+
## Purpose
|
|
27
|
+
|
|
28
|
+
Test-Driven Development approach ensuring testable, well-designed code with comprehensive coverage.
|
|
29
|
+
|
|
30
|
+
## The TDD Cycle
|
|
31
|
+
|
|
32
|
+
### RED → GREEN → REFACTOR
|
|
33
|
+
|
|
34
|
+
- **RED**: Write a failing test
|
|
35
|
+
- **GREEN**: Write minimum code to pass
|
|
36
|
+
- **REFACTOR**: Improve code while keeping tests green
|
|
37
|
+
|
|
38
|
+
**Cycle time**: 2-10 minutes per iteration
|
|
39
|
+
|
|
40
|
+
## Workflow
|
|
41
|
+
|
|
42
|
+
### 1. RED - Write Failing Test
|
|
43
|
+
|
|
44
|
+
**Objective**: Define expected behavior through failing test
|
|
45
|
+
|
|
46
|
+
**Actions:**
|
|
47
|
+
1. Identify single behavior to test
|
|
48
|
+
2. Write test describing expected behavior
|
|
49
|
+
3. Run test - it MUST fail
|
|
50
|
+
4. Verify failure message is clear
|
|
51
|
+
|
|
52
|
+
**Example:**
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// Step 1: RED - Write failing test
|
|
56
|
+
describe('OrderService', () => {
|
|
57
|
+
it('should create order with valid data', async () => {
|
|
58
|
+
const service = new OrderService();
|
|
59
|
+
|
|
60
|
+
const order = await service.create({
|
|
61
|
+
itemId: 'item-1',
|
|
62
|
+
quantity: 2,
|
|
63
|
+
customerId: 'customer-1'
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(order).toHaveProperty('id');
|
|
67
|
+
expect(order.status).toBe('pending');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Run: {{TEST_COMMAND}}
|
|
72
|
+
// Result: FAIL - OrderService is not defined
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. GREEN - Make Test Pass
|
|
76
|
+
|
|
77
|
+
**Objective**: Write minimum code to make test pass
|
|
78
|
+
|
|
79
|
+
**Actions:**
|
|
80
|
+
1. Write simplest code that passes
|
|
81
|
+
2. Don't add extra features
|
|
82
|
+
3. Don't optimize yet
|
|
83
|
+
4. Run test - it MUST pass
|
|
84
|
+
|
|
85
|
+
**Example:**
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Step 2: GREEN - Minimum implementation
|
|
89
|
+
export class OrderService {
|
|
90
|
+
async create(data) {
|
|
91
|
+
return {
|
|
92
|
+
id: 'order-1',
|
|
93
|
+
status: 'pending',
|
|
94
|
+
...data
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Run: {{TEST_COMMAND}}
|
|
100
|
+
// Result: PASS ✓
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 3. REFACTOR - Improve Code
|
|
104
|
+
|
|
105
|
+
**Objective**: Improve design while keeping tests green
|
|
106
|
+
|
|
107
|
+
**Actions:**
|
|
108
|
+
1. Remove duplication
|
|
109
|
+
2. Improve names
|
|
110
|
+
3. Extract methods/classes
|
|
111
|
+
4. Apply design patterns
|
|
112
|
+
5. Run tests after each change
|
|
113
|
+
6. Tests MUST stay green
|
|
114
|
+
|
|
115
|
+
**Example:**
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// Step 3: REFACTOR - Add proper implementation
|
|
119
|
+
export class OrderService extends BaseCrudService<Order> {
|
|
120
|
+
constructor(
|
|
121
|
+
private orderModel: OrderModel,
|
|
122
|
+
private validator: OrderValidator
|
|
123
|
+
) {
|
|
124
|
+
super(orderModel);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async create(data: CreateOrderInput): Promise<Order> {
|
|
128
|
+
await this.validator.validate(data);
|
|
129
|
+
|
|
130
|
+
const order = await this.orderModel.create({
|
|
131
|
+
...data,
|
|
132
|
+
status: 'pending'
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return order;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Run: {{TEST_COMMAND}}
|
|
140
|
+
// Result: PASS ✓ (still passing)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 4. Repeat
|
|
144
|
+
|
|
145
|
+
**Continue cycle for next behavior:**
|
|
146
|
+
1. Pick next behavior
|
|
147
|
+
2. Write failing test (RED)
|
|
148
|
+
3. Make it pass (GREEN)
|
|
149
|
+
4. Refactor (REFACTOR)
|
|
150
|
+
5. Commit when tests green
|
|
151
|
+
|
|
152
|
+
## TDD Rules
|
|
153
|
+
|
|
154
|
+
### Three Laws of TDD
|
|
155
|
+
|
|
156
|
+
1. **Don't write production code** until you have a failing test
|
|
157
|
+
2. **Don't write more test** than needed to fail
|
|
158
|
+
3. **Don't write more production code** than needed to pass
|
|
159
|
+
|
|
160
|
+
### Additional Guidelines
|
|
161
|
+
|
|
162
|
+
- **One test at a time**: Focus on single behavior
|
|
163
|
+
- **Test names describe behavior**: Clear, descriptive names
|
|
164
|
+
- **AAA pattern**: Arrange, Act, Assert
|
|
165
|
+
- **Fast tests**: Tests should run in seconds
|
|
166
|
+
- **Independent tests**: No test dependencies
|
|
167
|
+
- **Repeatable**: Same results every time
|
|
168
|
+
|
|
169
|
+
## Benefits
|
|
170
|
+
|
|
171
|
+
1. **Design Quality**: Forces modular, testable design
|
|
172
|
+
2. **Coverage**: High coverage naturally achieved
|
|
173
|
+
3. **Documentation**: Tests document behavior
|
|
174
|
+
4. **Confidence**: Safe refactoring
|
|
175
|
+
5. **Bug Prevention**: Catches issues early
|
|
176
|
+
6. **Focus**: One thing at a time
|
|
177
|
+
|
|
178
|
+
## Common Mistakes
|
|
179
|
+
|
|
180
|
+
### ❌ Writing Tests After Code
|
|
181
|
+
|
|
182
|
+
**Why bad**: Code already designed, tests fit code instead of driving design
|
|
183
|
+
|
|
184
|
+
**Fix**: Always write test first
|
|
185
|
+
|
|
186
|
+
### ❌ Writing Too Much Test
|
|
187
|
+
|
|
188
|
+
**Why bad**: Wastes time, test becomes complex
|
|
189
|
+
|
|
190
|
+
**Fix**: Write minimal test that fails
|
|
191
|
+
|
|
192
|
+
### ❌ Writing Too Much Code
|
|
193
|
+
|
|
194
|
+
**Why bad**: Adds unnecessary complexity
|
|
195
|
+
|
|
196
|
+
**Fix**: Write just enough to pass
|
|
197
|
+
|
|
198
|
+
### ❌ Skipping Refactor
|
|
199
|
+
|
|
200
|
+
**Why bad**: Code becomes messy over time
|
|
201
|
+
|
|
202
|
+
**Fix**: Refactor after each GREEN
|
|
203
|
+
|
|
204
|
+
### ❌ Not Running Tests Frequently
|
|
205
|
+
|
|
206
|
+
**Why bad**: Miss immediate feedback
|
|
207
|
+
|
|
208
|
+
**Fix**: Run tests after each step
|
|
209
|
+
|
|
210
|
+
## TDD with Different Layers
|
|
211
|
+
|
|
212
|
+
### Database Layer
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// RED: Write failing test
|
|
216
|
+
it('should find item by ID', async () => {
|
|
217
|
+
const model = new ItemModel(db);
|
|
218
|
+
const item = await model.findById('item-1');
|
|
219
|
+
expect(item).toBeDefined();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// GREEN: Implement
|
|
223
|
+
class ItemModel extends BaseModel<Item> {
|
|
224
|
+
async findById(id: string) {
|
|
225
|
+
return await db.items.findFirst({
|
|
226
|
+
where: eq(items.id, id)
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// REFACTOR: Add error handling
|
|
232
|
+
async findById(id: string) {
|
|
233
|
+
const item = await db.items.findFirst({
|
|
234
|
+
where: eq(items.id, id)
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
if (!item) {
|
|
238
|
+
throw new NotFoundError('Item not found');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return item;
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Service Layer
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// RED: Business logic test
|
|
249
|
+
it('should not allow negative quantity', async () => {
|
|
250
|
+
await expect(
|
|
251
|
+
service.create({
|
|
252
|
+
quantity: -1
|
|
253
|
+
})
|
|
254
|
+
).rejects.toThrow('Quantity must be positive');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// GREEN: Implement validation
|
|
258
|
+
async create(data) {
|
|
259
|
+
if (data.quantity < 0) {
|
|
260
|
+
throw new Error('Quantity must be positive');
|
|
261
|
+
}
|
|
262
|
+
return await this.model.create(data);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// REFACTOR: Extract validator
|
|
266
|
+
class QuantityValidator {
|
|
267
|
+
validatePositive(quantity: number) {
|
|
268
|
+
if (quantity < 0) {
|
|
269
|
+
throw new ValidationError('Quantity must be positive');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### API Layer
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
// RED: API test
|
|
279
|
+
it('POST /api/orders should return 201', async () => {
|
|
280
|
+
const response = await app.request('/api/orders', {
|
|
281
|
+
method: 'POST',
|
|
282
|
+
body: JSON.stringify(validOrder)
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
expect(response.status).toBe(201);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// GREEN: Implement route
|
|
289
|
+
app.post('/api/orders', async (c) => {
|
|
290
|
+
const data = await c.req.json();
|
|
291
|
+
const order = await service.create(data);
|
|
292
|
+
return c.json(order, 201);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// REFACTOR: Add validation
|
|
296
|
+
app.post('/api/orders',
|
|
297
|
+
validator('json', createOrderSchema),
|
|
298
|
+
async (c) => {
|
|
299
|
+
const data = c.req.valid('json');
|
|
300
|
+
const order = await service.create(data);
|
|
301
|
+
return c.json(order, 201);
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Coverage Goals
|
|
307
|
+
|
|
308
|
+
- **Unit Tests**: >= {{COVERAGE_TARGET}}
|
|
309
|
+
- **Integration Tests**: All critical paths
|
|
310
|
+
- **E2E Tests**: Happy paths
|
|
311
|
+
|
|
312
|
+
## Best Practices
|
|
313
|
+
|
|
314
|
+
1. **Start Simple**: Test simplest case first
|
|
315
|
+
2. **One Assert**: One logical assertion per test
|
|
316
|
+
3. **Clear Names**: Test name explains behavior
|
|
317
|
+
4. **Fast Feedback**: Keep tests fast
|
|
318
|
+
5. **Isolated**: Tests don't depend on each other
|
|
319
|
+
6. **Deterministic**: Always same result
|
|
320
|
+
7. **Readable**: Tests as documentation
|
|
321
|
+
8. **Maintainable**: Refactor tests too
|
|
322
|
+
|
|
323
|
+
## Output
|
|
324
|
+
|
|
325
|
+
**Produces:**
|
|
326
|
+
- Test files written before implementation
|
|
327
|
+
- Well-designed, modular code
|
|
328
|
+
- Coverage >= {{COVERAGE_TARGET}}
|
|
329
|
+
- Living documentation through tests
|
|
330
|
+
|
|
331
|
+
**Success Criteria:**
|
|
332
|
+
- All tests passing
|
|
333
|
+
- Coverage meets target
|
|
334
|
+
- Code well-designed and maintainable
|
|
335
|
+
- Tests serve as documentation
|
|
336
|
+
|
|
337
|
+
## Related Skills
|
|
338
|
+
|
|
339
|
+
- `api-app-testing` - API-specific testing
|
|
340
|
+
- `web-app-testing` - Frontend testing
|
|
341
|
+
- `security-testing` - Security testing
|
|
342
|
+
- `performance-testing` - Performance testing
|