@qazuor/claude-code-config 0.4.0 → 0.6.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/README.md +395 -50
- package/dist/bin.cjs +3207 -165
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +3207 -165
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +75 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +284 -1
- package/dist/index.d.ts +284 -1
- package/dist/index.js +75 -58
- package/dist/index.js.map +1 -1
- package/package.json +24 -24
- package/templates/CLAUDE.md.template +60 -5
- package/templates/agents/README.md +58 -39
- package/templates/agents/_registry.json +43 -202
- package/templates/agents/engineering/{hono-engineer.md → api-engineer.md} +61 -70
- package/templates/agents/engineering/database-engineer.md +253 -0
- package/templates/agents/engineering/frontend-engineer.md +302 -0
- package/templates/docs/_registry.json +54 -0
- package/templates/docs/standards/code-standards.md +20 -0
- package/templates/docs/standards/design-standards.md +13 -0
- package/templates/docs/standards/documentation-standards.md +13 -0
- package/templates/docs/standards/performance-standards.md +524 -0
- package/templates/docs/standards/security-standards.md +496 -0
- package/templates/docs/standards/testing-standards.md +15 -0
- package/templates/hooks/on-notification.sh +0 -0
- package/templates/scripts/add-changelogs.sh +0 -0
- package/templates/scripts/generate-code-registry.ts +0 -0
- package/templates/scripts/health-check.sh +0 -0
- package/templates/scripts/sync-registry.sh +0 -0
- package/templates/scripts/telemetry-report.ts +0 -0
- package/templates/scripts/validate-docs.sh +0 -0
- package/templates/scripts/validate-registry.sh +0 -0
- package/templates/scripts/validate-structure.sh +0 -0
- package/templates/scripts/worktree-cleanup.sh +0 -0
- package/templates/scripts/worktree-create.sh +0 -0
- package/templates/skills/README.md +99 -90
- package/templates/skills/_registry.json +323 -16
- package/templates/skills/api-frameworks/express-patterns.md +411 -0
- package/templates/skills/api-frameworks/fastify-patterns.md +419 -0
- package/templates/skills/api-frameworks/hono-patterns.md +388 -0
- package/templates/skills/api-frameworks/nestjs-patterns.md +497 -0
- package/templates/skills/database/drizzle-patterns.md +449 -0
- package/templates/skills/database/mongoose-patterns.md +503 -0
- package/templates/skills/database/prisma-patterns.md +487 -0
- package/templates/skills/frontend-frameworks/astro-patterns.md +415 -0
- package/templates/skills/frontend-frameworks/nextjs-patterns.md +470 -0
- package/templates/skills/frontend-frameworks/react-patterns.md +516 -0
- package/templates/skills/frontend-frameworks/tanstack-start-patterns.md +469 -0
- package/templates/skills/patterns/atdd-methodology.md +364 -0
- package/templates/skills/patterns/bdd-methodology.md +281 -0
- package/templates/skills/patterns/clean-architecture.md +444 -0
- package/templates/skills/patterns/hexagonal-architecture.md +567 -0
- package/templates/skills/patterns/vertical-slice-architecture.md +502 -0
- package/templates/agents/engineering/astro-engineer.md +0 -293
- package/templates/agents/engineering/db-drizzle-engineer.md +0 -360
- package/templates/agents/engineering/express-engineer.md +0 -316
- package/templates/agents/engineering/fastify-engineer.md +0 -399
- package/templates/agents/engineering/mongoose-engineer.md +0 -473
- package/templates/agents/engineering/nestjs-engineer.md +0 -429
- package/templates/agents/engineering/nextjs-engineer.md +0 -451
- package/templates/agents/engineering/prisma-engineer.md +0 -432
- package/templates/agents/engineering/react-senior-dev.md +0 -394
- package/templates/agents/engineering/tanstack-start-engineer.md +0 -447
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clean-architecture
|
|
3
|
+
category: patterns
|
|
4
|
+
description: Clean Architecture with concentric layers and dependency inversion for maintainable codebases
|
|
5
|
+
usage: Use when building applications that need clear separation of concerns and testability
|
|
6
|
+
input: Application requirements, domain models, use cases
|
|
7
|
+
output: Layered architecture with entities, use cases, interfaces, and frameworks
|
|
8
|
+
config_required:
|
|
9
|
+
- DOMAIN_DIR: "Directory for domain entities (e.g., src/domain/)"
|
|
10
|
+
- USE_CASES_DIR: "Directory for use cases/application layer (e.g., src/application/)"
|
|
11
|
+
- INTERFACES_DIR: "Directory for interfaces/adapters (e.g., src/interfaces/)"
|
|
12
|
+
- INFRASTRUCTURE_DIR: "Directory for frameworks/infrastructure (e.g., src/infrastructure/)"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Clean Architecture
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
Clean Architecture, introduced by Robert C. Martin (Uncle Bob), organizes code in concentric layers where dependencies point inward. The core business logic remains independent of external concerns like databases, UI, or frameworks.
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
| Setting | Description | Example |
|
|
24
|
+
|---------|-------------|---------|
|
|
25
|
+
| DOMAIN_DIR | Domain entities | `src/domain/`, `core/entities/` |
|
|
26
|
+
| USE_CASES_DIR | Application/Use cases | `src/application/`, `core/use-cases/` |
|
|
27
|
+
| INTERFACES_DIR | Interface adapters | `src/interfaces/`, `adapters/` |
|
|
28
|
+
| INFRASTRUCTURE_DIR | External frameworks | `src/infrastructure/`, `external/` |
|
|
29
|
+
|
|
30
|
+
## The Dependency Rule
|
|
31
|
+
|
|
32
|
+
**Dependencies ALWAYS point inward.** Inner layers know nothing about outer layers.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
┌─────────────────────────────────────────────────┐
|
|
36
|
+
│ Frameworks & Drivers │ ← External (DB, Web, UI)
|
|
37
|
+
│ ┌─────────────────────────────────────────┐ │
|
|
38
|
+
│ │ Interface Adapters │ │ ← Controllers, Gateways
|
|
39
|
+
│ │ ┌─────────────────────────────────┐ │ │
|
|
40
|
+
│ │ │ Application Layer │ │ │ ← Use Cases
|
|
41
|
+
│ │ │ ┌─────────────────────────┐ │ │ │
|
|
42
|
+
│ │ │ │ Enterprise Layer │ │ │ │ ← Entities
|
|
43
|
+
│ │ │ └─────────────────────────┘ │ │ │
|
|
44
|
+
│ │ └─────────────────────────────────┘ │ │
|
|
45
|
+
│ └─────────────────────────────────────────┘ │
|
|
46
|
+
└─────────────────────────────────────────────────┘
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Layer Details
|
|
50
|
+
|
|
51
|
+
### 1. Enterprise Layer (Entities)
|
|
52
|
+
|
|
53
|
+
**Purpose:** Core business rules and domain objects.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// domain/entities/User.ts
|
|
57
|
+
export interface User {
|
|
58
|
+
id: string;
|
|
59
|
+
email: string;
|
|
60
|
+
name: string;
|
|
61
|
+
createdAt: Date;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// domain/entities/Order.ts
|
|
65
|
+
export interface Order {
|
|
66
|
+
id: string;
|
|
67
|
+
userId: string;
|
|
68
|
+
items: OrderItem[];
|
|
69
|
+
total: number;
|
|
70
|
+
status: OrderStatus;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered';
|
|
74
|
+
|
|
75
|
+
// domain/value-objects/Email.ts
|
|
76
|
+
export class Email {
|
|
77
|
+
private constructor(private readonly value: string) {}
|
|
78
|
+
|
|
79
|
+
static create(email: string): Email {
|
|
80
|
+
if (!this.isValid(email)) {
|
|
81
|
+
throw new Error('Invalid email format');
|
|
82
|
+
}
|
|
83
|
+
return new Email(email);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static isValid(email: string): boolean {
|
|
87
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getValue(): string {
|
|
91
|
+
return this.value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Application Layer (Use Cases)
|
|
97
|
+
|
|
98
|
+
**Purpose:** Application-specific business rules.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// application/use-cases/CreateOrder.ts
|
|
102
|
+
import type { Order } from '../../domain/entities/Order';
|
|
103
|
+
import type { OrderRepository } from '../ports/OrderRepository';
|
|
104
|
+
import type { UserRepository } from '../ports/UserRepository';
|
|
105
|
+
import type { NotificationService } from '../ports/NotificationService';
|
|
106
|
+
|
|
107
|
+
interface CreateOrderInput {
|
|
108
|
+
userId: string;
|
|
109
|
+
items: Array<{ productId: string; quantity: number }>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface CreateOrderOutput {
|
|
113
|
+
order: Order;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export class CreateOrderUseCase {
|
|
117
|
+
constructor(
|
|
118
|
+
private orderRepository: OrderRepository,
|
|
119
|
+
private userRepository: UserRepository,
|
|
120
|
+
private notificationService: NotificationService
|
|
121
|
+
) {}
|
|
122
|
+
|
|
123
|
+
async execute(input: CreateOrderInput): Promise<CreateOrderOutput> {
|
|
124
|
+
// Validate user exists
|
|
125
|
+
const user = await this.userRepository.findById(input.userId);
|
|
126
|
+
if (!user) {
|
|
127
|
+
throw new Error('User not found');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Calculate total
|
|
131
|
+
const total = await this.calculateTotal(input.items);
|
|
132
|
+
|
|
133
|
+
// Create order
|
|
134
|
+
const order = await this.orderRepository.create({
|
|
135
|
+
userId: input.userId,
|
|
136
|
+
items: input.items,
|
|
137
|
+
total,
|
|
138
|
+
status: 'pending',
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Send notification
|
|
142
|
+
await this.notificationService.sendOrderConfirmation(user.email, order);
|
|
143
|
+
|
|
144
|
+
return { order };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private async calculateTotal(items: CreateOrderInput['items']): Promise<number> {
|
|
148
|
+
// Business logic for calculating total
|
|
149
|
+
return items.reduce((sum, item) => sum + item.quantity * 10, 0);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 3. Interface Adapters
|
|
155
|
+
|
|
156
|
+
**Purpose:** Convert data between use cases and external agencies.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// interfaces/controllers/OrderController.ts
|
|
160
|
+
import type { Request, Response } from 'express';
|
|
161
|
+
import type { CreateOrderUseCase } from '../../application/use-cases/CreateOrder';
|
|
162
|
+
|
|
163
|
+
export class OrderController {
|
|
164
|
+
constructor(private createOrderUseCase: CreateOrderUseCase) {}
|
|
165
|
+
|
|
166
|
+
async create(req: Request, res: Response): Promise<void> {
|
|
167
|
+
try {
|
|
168
|
+
const result = await this.createOrderUseCase.execute({
|
|
169
|
+
userId: req.body.userId,
|
|
170
|
+
items: req.body.items,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
res.status(201).json({
|
|
174
|
+
success: true,
|
|
175
|
+
data: this.toPresentation(result.order),
|
|
176
|
+
});
|
|
177
|
+
} catch (error) {
|
|
178
|
+
res.status(400).json({
|
|
179
|
+
success: false,
|
|
180
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private toPresentation(order: Order) {
|
|
186
|
+
return {
|
|
187
|
+
id: order.id,
|
|
188
|
+
items: order.items,
|
|
189
|
+
total: order.total,
|
|
190
|
+
status: order.status,
|
|
191
|
+
createdAt: order.createdAt.toISOString(),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// interfaces/presenters/OrderPresenter.ts
|
|
197
|
+
export class OrderPresenter {
|
|
198
|
+
static toJSON(order: Order) {
|
|
199
|
+
return {
|
|
200
|
+
id: order.id,
|
|
201
|
+
total: `$${order.total.toFixed(2)}`,
|
|
202
|
+
itemCount: order.items.length,
|
|
203
|
+
status: order.status,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 4. Frameworks & Drivers
|
|
210
|
+
|
|
211
|
+
**Purpose:** External frameworks, tools, and infrastructure.
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// infrastructure/repositories/PostgresOrderRepository.ts
|
|
215
|
+
import type { Order } from '../../domain/entities/Order';
|
|
216
|
+
import type { OrderRepository } from '../../application/ports/OrderRepository';
|
|
217
|
+
import { db } from '../database/connection';
|
|
218
|
+
|
|
219
|
+
export class PostgresOrderRepository implements OrderRepository {
|
|
220
|
+
async findById(id: string): Promise<Order | null> {
|
|
221
|
+
const result = await db.query('SELECT * FROM orders WHERE id = $1', [id]);
|
|
222
|
+
return result.rows[0] ? this.toDomain(result.rows[0]) : null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async create(data: Omit<Order, 'id' | 'createdAt'>): Promise<Order> {
|
|
226
|
+
const result = await db.query(
|
|
227
|
+
'INSERT INTO orders (user_id, items, total, status) VALUES ($1, $2, $3, $4) RETURNING *',
|
|
228
|
+
[data.userId, JSON.stringify(data.items), data.total, data.status]
|
|
229
|
+
);
|
|
230
|
+
return this.toDomain(result.rows[0]);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
private toDomain(row: any): Order {
|
|
234
|
+
return {
|
|
235
|
+
id: row.id,
|
|
236
|
+
userId: row.user_id,
|
|
237
|
+
items: row.items,
|
|
238
|
+
total: parseFloat(row.total),
|
|
239
|
+
status: row.status,
|
|
240
|
+
createdAt: row.created_at,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// infrastructure/services/EmailNotificationService.ts
|
|
246
|
+
import type { NotificationService } from '../../application/ports/NotificationService';
|
|
247
|
+
|
|
248
|
+
export class EmailNotificationService implements NotificationService {
|
|
249
|
+
async sendOrderConfirmation(email: string, order: Order): Promise<void> {
|
|
250
|
+
// Implementation using email provider
|
|
251
|
+
console.log(`Sending confirmation to ${email} for order ${order.id}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Ports (Interfaces)
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// application/ports/OrderRepository.ts
|
|
260
|
+
import type { Order } from '../../domain/entities/Order';
|
|
261
|
+
|
|
262
|
+
export interface OrderRepository {
|
|
263
|
+
findById(id: string): Promise<Order | null>;
|
|
264
|
+
findByUserId(userId: string): Promise<Order[]>;
|
|
265
|
+
create(data: Omit<Order, 'id' | 'createdAt'>): Promise<Order>;
|
|
266
|
+
update(id: string, data: Partial<Order>): Promise<Order>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// application/ports/NotificationService.ts
|
|
270
|
+
export interface NotificationService {
|
|
271
|
+
sendOrderConfirmation(email: string, order: Order): Promise<void>;
|
|
272
|
+
sendShippingUpdate(email: string, order: Order): Promise<void>;
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Project Structure
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
src/
|
|
280
|
+
├── domain/ # Enterprise Business Rules
|
|
281
|
+
│ ├── entities/
|
|
282
|
+
│ │ ├── User.ts
|
|
283
|
+
│ │ └── Order.ts
|
|
284
|
+
│ └── value-objects/
|
|
285
|
+
│ ├── Email.ts
|
|
286
|
+
│ └── Money.ts
|
|
287
|
+
├── application/ # Application Business Rules
|
|
288
|
+
│ ├── use-cases/
|
|
289
|
+
│ │ ├── CreateOrder.ts
|
|
290
|
+
│ │ ├── GetUserOrders.ts
|
|
291
|
+
│ │ └── UpdateOrderStatus.ts
|
|
292
|
+
│ └── ports/ # Interfaces for external services
|
|
293
|
+
│ ├── OrderRepository.ts
|
|
294
|
+
│ ├── UserRepository.ts
|
|
295
|
+
│ └── NotificationService.ts
|
|
296
|
+
├── interfaces/ # Interface Adapters
|
|
297
|
+
│ ├── controllers/
|
|
298
|
+
│ │ ├── OrderController.ts
|
|
299
|
+
│ │ └── UserController.ts
|
|
300
|
+
│ ├── presenters/
|
|
301
|
+
│ │ └── OrderPresenter.ts
|
|
302
|
+
│ └── gateways/
|
|
303
|
+
│ └── PaymentGateway.ts
|
|
304
|
+
└── infrastructure/ # Frameworks & Drivers
|
|
305
|
+
├── database/
|
|
306
|
+
│ ├── connection.ts
|
|
307
|
+
│ └── migrations/
|
|
308
|
+
├── repositories/
|
|
309
|
+
│ ├── PostgresOrderRepository.ts
|
|
310
|
+
│ └── PostgresUserRepository.ts
|
|
311
|
+
├── services/
|
|
312
|
+
│ └── EmailNotificationService.ts
|
|
313
|
+
└── web/
|
|
314
|
+
├── routes.ts
|
|
315
|
+
└── middleware/
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Dependency Injection
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// infrastructure/container.ts
|
|
322
|
+
import { CreateOrderUseCase } from '../application/use-cases/CreateOrder';
|
|
323
|
+
import { PostgresOrderRepository } from './repositories/PostgresOrderRepository';
|
|
324
|
+
import { PostgresUserRepository } from './repositories/PostgresUserRepository';
|
|
325
|
+
import { EmailNotificationService } from './services/EmailNotificationService';
|
|
326
|
+
import { OrderController } from '../interfaces/controllers/OrderController';
|
|
327
|
+
|
|
328
|
+
// Create implementations
|
|
329
|
+
const orderRepository = new PostgresOrderRepository();
|
|
330
|
+
const userRepository = new PostgresUserRepository();
|
|
331
|
+
const notificationService = new EmailNotificationService();
|
|
332
|
+
|
|
333
|
+
// Create use cases with injected dependencies
|
|
334
|
+
const createOrderUseCase = new CreateOrderUseCase(
|
|
335
|
+
orderRepository,
|
|
336
|
+
userRepository,
|
|
337
|
+
notificationService
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
// Create controllers
|
|
341
|
+
export const orderController = new OrderController(createOrderUseCase);
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Testing Strategy
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
// tests/application/use-cases/CreateOrder.test.ts
|
|
348
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
349
|
+
import { CreateOrderUseCase } from '../../../src/application/use-cases/CreateOrder';
|
|
350
|
+
|
|
351
|
+
describe('CreateOrderUseCase', () => {
|
|
352
|
+
it('should create order for valid user', async () => {
|
|
353
|
+
// Arrange - Use mock implementations
|
|
354
|
+
const mockOrderRepo = {
|
|
355
|
+
create: vi.fn().mockResolvedValue({
|
|
356
|
+
id: 'order-1',
|
|
357
|
+
userId: 'user-1',
|
|
358
|
+
items: [{ productId: 'prod-1', quantity: 2 }],
|
|
359
|
+
total: 20,
|
|
360
|
+
status: 'pending',
|
|
361
|
+
}),
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const mockUserRepo = {
|
|
365
|
+
findById: vi.fn().mockResolvedValue({
|
|
366
|
+
id: 'user-1',
|
|
367
|
+
email: 'test@example.com',
|
|
368
|
+
name: 'Test User',
|
|
369
|
+
}),
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const mockNotification = {
|
|
373
|
+
sendOrderConfirmation: vi.fn().mockResolvedValue(undefined),
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const useCase = new CreateOrderUseCase(
|
|
377
|
+
mockOrderRepo as any,
|
|
378
|
+
mockUserRepo as any,
|
|
379
|
+
mockNotification as any
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
// Act
|
|
383
|
+
const result = await useCase.execute({
|
|
384
|
+
userId: 'user-1',
|
|
385
|
+
items: [{ productId: 'prod-1', quantity: 2 }],
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
// Assert
|
|
389
|
+
expect(result.order.id).toBe('order-1');
|
|
390
|
+
expect(mockNotification.sendOrderConfirmation).toHaveBeenCalled();
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Best Practices
|
|
396
|
+
|
|
397
|
+
### Do's
|
|
398
|
+
|
|
399
|
+
- Keep entities pure (no framework dependencies)
|
|
400
|
+
- Use dependency injection for all external services
|
|
401
|
+
- Define ports (interfaces) in the application layer
|
|
402
|
+
- Test use cases independently of infrastructure
|
|
403
|
+
- Cross boundaries with simple data structures
|
|
404
|
+
|
|
405
|
+
### Don'ts
|
|
406
|
+
|
|
407
|
+
- Don't import from outer layers into inner layers
|
|
408
|
+
- Don't put business logic in controllers
|
|
409
|
+
- Don't let entities depend on databases
|
|
410
|
+
- Don't skip the use case layer for "simple" operations
|
|
411
|
+
- Don't create circular dependencies between layers
|
|
412
|
+
|
|
413
|
+
## When to Use Clean Architecture
|
|
414
|
+
|
|
415
|
+
**Good for:**
|
|
416
|
+
|
|
417
|
+
- Large applications with complex business logic
|
|
418
|
+
- Applications requiring high testability
|
|
419
|
+
- Teams following domain-driven design
|
|
420
|
+
- Long-term maintainable codebases
|
|
421
|
+
- Applications needing framework independence
|
|
422
|
+
|
|
423
|
+
**Less suitable for:**
|
|
424
|
+
|
|
425
|
+
- Simple CRUD applications
|
|
426
|
+
- Prototypes or MVPs
|
|
427
|
+
- Small teams with tight deadlines
|
|
428
|
+
- Applications with minimal business logic
|
|
429
|
+
|
|
430
|
+
## Output
|
|
431
|
+
|
|
432
|
+
**Produces:**
|
|
433
|
+
|
|
434
|
+
- Layered project structure
|
|
435
|
+
- Framework-independent business logic
|
|
436
|
+
- Testable use cases
|
|
437
|
+
- Clear separation of concerns
|
|
438
|
+
|
|
439
|
+
**Success Criteria:**
|
|
440
|
+
|
|
441
|
+
- Inner layers have no outer layer imports
|
|
442
|
+
- Use cases are fully unit testable
|
|
443
|
+
- Entities contain only business logic
|
|
444
|
+
- Infrastructure is easily swappable
|