@chejende/clean-arch 1.0.0 → 1.0.1
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 +457 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,28 +1,474 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @chejende/clean-arch
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Angular schematic para generar features con Clean Architecture (Hexagonal-inspired) de forma consistente, rapida y mantenible.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package provides an Angular schematic to scaffold features using a Clean Architecture (Hexagonal-inspired) structure that is consistent, fast, and maintainable.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Tabla de Contenidos / Table of Contents
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- [1. ¿Para que sirve? (ES)](#1-para-que-sirve-es)
|
|
10
|
+
- [2. Instalacion (ES)](#2-instalacion-es)
|
|
11
|
+
- [3. Uso rapido (ES)](#3-uso-rapido-es)
|
|
12
|
+
- [4. Arquitectura generada (ES)](#4-arquitectura-generada-es)
|
|
13
|
+
- [5. Ejemplos detallados (ES)](#5-ejemplos-detallados-es)
|
|
14
|
+
- [6. Buenas practicas (ES)](#6-buenas-practicas-es)
|
|
15
|
+
- [7. Publicar en npm (ES)](#7-publicar-en-npm-es)
|
|
16
|
+
- [8. What is this for? (EN)](#8-what-is-this-for-en)
|
|
17
|
+
- [9. Installation (EN)](#9-installation-en)
|
|
18
|
+
- [10. Quick start (EN)](#10-quick-start-en)
|
|
19
|
+
- [11. Generated architecture (EN)](#11-generated-architecture-en)
|
|
20
|
+
- [12. Detailed examples (EN)](#12-detailed-examples-en)
|
|
21
|
+
- [13. Best practices (EN)](#13-best-practices-en)
|
|
22
|
+
- [14. Publish to npm (EN)](#14-publish-to-npm-en)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 1. ¿Para que sirve? (ES)
|
|
27
|
+
|
|
28
|
+
`@chejende/clean-arch` crea automaticamente el esqueleto de una feature en Angular separando responsabilidades por capas:
|
|
29
|
+
|
|
30
|
+
- `domain`: reglas y contratos del negocio.
|
|
31
|
+
- `application`: casos de uso, DTOs y providers.
|
|
32
|
+
- `infrastructure`: integraciones tecnicas (API, repositorios concretos, mappers).
|
|
33
|
+
- `presentation`: pagina/componente y store para estado UI.
|
|
34
|
+
|
|
35
|
+
Objetivo:
|
|
36
|
+
|
|
37
|
+
- Reducir tiempo de arranque de nuevas funcionalidades.
|
|
38
|
+
- Estandarizar estructura entre equipos.
|
|
39
|
+
- Evitar mezcla de logica de negocio con detalles de framework o transporte.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. Instalacion (ES)
|
|
44
|
+
|
|
45
|
+
### Como dependencia de desarrollo
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install -D @chejende/clean-arch
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Uso sin instalar (one-shot)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx -p @chejende/clean-arch ng g @chejende/clean-arch:feature users
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Requisito recomendado: Angular CLI instalado en el proyecto.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 3. Uso rapido (ES)
|
|
62
|
+
|
|
63
|
+
### Comando principal
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
ng g @chejende/clean-arch:feature --name=users
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Tambien funciona con argumento posicional:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ng g @chejende/clean-arch:feature users
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Alternativa con `schematics`
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx schematics @chejende/clean-arch:feature --name=users
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 4. Arquitectura generada (ES)
|
|
84
|
+
|
|
85
|
+
Para `users`, se genera:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
src/app/features/users/
|
|
89
|
+
domain/
|
|
90
|
+
models/users.model.ts
|
|
91
|
+
repositories/users.repository.ts
|
|
92
|
+
application/
|
|
93
|
+
dto/users.dto.ts
|
|
94
|
+
use-cases/get-users.use-case.ts
|
|
95
|
+
providers/users.providers.ts
|
|
96
|
+
infrastructure/
|
|
97
|
+
services/users-api.service.ts
|
|
98
|
+
repositories/users.repository.impl.ts
|
|
99
|
+
mappers/users.mapper.ts
|
|
100
|
+
presentation/
|
|
101
|
+
pages/users.page.ts
|
|
102
|
+
store/users.store.ts
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Flujo de dependencias recomendado
|
|
106
|
+
|
|
107
|
+
`presentation -> application -> domain`
|
|
108
|
+
`infrastructure -> domain`
|
|
109
|
+
|
|
110
|
+
Esto evita acoplar la logica de negocio con Angular, HTTP o detalles de infraestructura.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 5. Ejemplos detallados (ES)
|
|
115
|
+
|
|
116
|
+
### Ejemplo 1: Feature de autenticacion
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
ng g @chejende/clean-arch:feature auth
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Uso recomendado:
|
|
123
|
+
|
|
124
|
+
- Definir contratos en `domain/repositories/auth.repository.ts`.
|
|
125
|
+
- Implementar consumo HTTP en `infrastructure/services/auth-api.service.ts`.
|
|
126
|
+
- Orquestar flujo en `application/use-cases/get-auth.use-case.ts`.
|
|
127
|
+
- Exponer estado en `presentation/store/auth.store.ts`.
|
|
128
|
+
|
|
129
|
+
### Ejemplo 2: Feature de productos
|
|
10
130
|
|
|
11
131
|
```bash
|
|
12
|
-
|
|
132
|
+
ng g @chejende/clean-arch:feature products
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Buenas decisiones comunes:
|
|
136
|
+
|
|
137
|
+
- `products.dto.ts`: forma de datos de entrada/salida de backend.
|
|
138
|
+
- `products.mapper.ts`: conversion DTO -> Modelo de dominio.
|
|
139
|
+
- `products.repository.impl.ts`: delega en API service y devuelve dominio.
|
|
140
|
+
|
|
141
|
+
### Ejemplo 3: Feature de ordenes
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
ng g @chejende/clean-arch:feature orders
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Caso practico:
|
|
148
|
+
|
|
149
|
+
- Crear `GetOrdersUseCase` para lectura.
|
|
150
|
+
- Agregar otros casos de uso (`CreateOrderUseCase`, `CancelOrderUseCase`) dentro de `application/use-cases`.
|
|
151
|
+
|
|
152
|
+
### Ejemplo 4: Registro de providers
|
|
153
|
+
|
|
154
|
+
En la feature `users`, el schematic crea `USERS_PROVIDERS`. Puedes registrarlo en config de app:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { ApplicationConfig } from '@angular/core';
|
|
158
|
+
import { USERS_PROVIDERS } from './features/users/application/providers/users.providers';
|
|
159
|
+
|
|
160
|
+
export const appConfig: ApplicationConfig = {
|
|
161
|
+
providers: [...USERS_PROVIDERS],
|
|
162
|
+
};
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Ejemplo 5: Uso del caso de uso desde presentacion
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { Component, inject } from '@angular/core';
|
|
169
|
+
import { UsersRepository } from '../../domain/repositories/users.repository';
|
|
170
|
+
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case';
|
|
171
|
+
|
|
172
|
+
@Component({
|
|
173
|
+
standalone: true,
|
|
174
|
+
template: `<button (click)="load()">Load users</button>`,
|
|
175
|
+
})
|
|
176
|
+
export class UsersPage {
|
|
177
|
+
private repo = inject(UsersRepository);
|
|
178
|
+
|
|
179
|
+
async load() {
|
|
180
|
+
const useCase = new GetUsersUseCase(this.repo);
|
|
181
|
+
const users = await useCase.execute();
|
|
182
|
+
console.log(users);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
13
185
|
```
|
|
14
186
|
|
|
15
|
-
###
|
|
187
|
+
### Ejemplo 6: Mapper explicito
|
|
16
188
|
|
|
17
|
-
|
|
189
|
+
```ts
|
|
190
|
+
import { UsersMapper } from './features/users/infrastructure/mappers/users.mapper';
|
|
18
191
|
|
|
19
|
-
|
|
192
|
+
const dto = { id: '123' };
|
|
193
|
+
const model = UsersMapper.toDomain(dto);
|
|
194
|
+
console.log(model.id);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Ejemplo 7: Flujo de prueba unitaria por capa
|
|
198
|
+
|
|
199
|
+
- `domain`: prueba reglas puras sin Angular.
|
|
200
|
+
- `application`: prueba casos de uso con mocks de repositorio.
|
|
201
|
+
- `infrastructure`: prueba adaptadores y mappers.
|
|
202
|
+
- `presentation`: prueba componentes/store con TestBed cuando aplique.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## 6. Buenas practicas (ES)
|
|
207
|
+
|
|
208
|
+
1. Mantener el dominio libre de framework.
|
|
209
|
+
2. Usar interfaces/abstract classes en `domain` para inversion de dependencias.
|
|
210
|
+
3. Mapear DTOs a modelos de dominio en `infrastructure/mappers`.
|
|
211
|
+
4. Evitar llamadas HTTP directas desde `presentation`.
|
|
212
|
+
5. Encapsular logica de negocio en casos de uso (`application/use-cases`).
|
|
213
|
+
6. Registrar providers por feature para modularidad.
|
|
214
|
+
7. Nombrar features en minuscula y en plural cuando representen colecciones (`users`, `products`).
|
|
215
|
+
8. Agregar casos de uso pequenos y orientados a una accion.
|
|
216
|
+
9. Mantener stores enfocados en estado de interfaz, no en reglas de negocio.
|
|
217
|
+
10. Probar cada capa segun su responsabilidad.
|
|
20
218
|
|
|
21
|
-
|
|
219
|
+
Por que hacerlo asi:
|
|
220
|
+
|
|
221
|
+
- Mejora testabilidad.
|
|
222
|
+
- Reduce acoplamiento.
|
|
223
|
+
- Facilita cambios de backend/UI sin romper reglas del negocio.
|
|
224
|
+
- Escala mejor en equipos grandes y monorepos.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 7. Publicar en npm (ES)
|
|
229
|
+
|
|
230
|
+
### Build local
|
|
22
231
|
|
|
23
232
|
```bash
|
|
24
233
|
npm run build
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Publicacion
|
|
237
|
+
|
|
238
|
+
```bash
|
|
25
239
|
npm publish
|
|
26
240
|
```
|
|
27
241
|
|
|
28
|
-
|
|
242
|
+
Nota: este paquete ya tiene `prepublishOnly`, por lo que `npm publish` ejecuta build antes de publicar.
|
|
243
|
+
|
|
244
|
+
Checklist previa:
|
|
245
|
+
|
|
246
|
+
1. Incrementar version en `package.json`.
|
|
247
|
+
2. Verificar que `dist/` se genera correctamente.
|
|
248
|
+
3. Confirmar credenciales con `npm whoami`.
|
|
249
|
+
4. Revisar README (este archivo) porque sera la documentacion en npm.
|
|
250
|
+
5. Publicar con `npm publish --access public` si aplica.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 8. What is this for? (EN)
|
|
255
|
+
|
|
256
|
+
`@chejende/clean-arch` automatically scaffolds Angular features following Clean Architecture layers:
|
|
257
|
+
|
|
258
|
+
- `domain`: business contracts and rules.
|
|
259
|
+
- `application`: use cases, DTOs, and providers.
|
|
260
|
+
- `infrastructure`: API services, concrete repositories, and mappers.
|
|
261
|
+
- `presentation`: UI page/component and feature store.
|
|
262
|
+
|
|
263
|
+
Main goals:
|
|
264
|
+
|
|
265
|
+
- Speed up feature bootstrap.
|
|
266
|
+
- Keep a consistent architecture across teams.
|
|
267
|
+
- Prevent business logic from being coupled to framework details.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 9. Installation (EN)
|
|
272
|
+
|
|
273
|
+
### As a dev dependency
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
npm install -D @chejende/clean-arch
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### One-shot usage (without installing)
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
npx -p @chejende/clean-arch ng g @chejende/clean-arch:feature users
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Recommended prerequisite: Angular CLI available in the target project.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## 10. Quick start (EN)
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
ng g @chejende/clean-arch:feature --name=users
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Positional argument also works:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
ng g @chejende/clean-arch:feature users
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Alternative with `schematics`:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
npx schematics @chejende/clean-arch:feature --name=users
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 11. Generated architecture (EN)
|
|
310
|
+
|
|
311
|
+
For `users`, the schematic creates:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
src/app/features/users/
|
|
315
|
+
domain/
|
|
316
|
+
models/users.model.ts
|
|
317
|
+
repositories/users.repository.ts
|
|
318
|
+
application/
|
|
319
|
+
dto/users.dto.ts
|
|
320
|
+
use-cases/get-users.use-case.ts
|
|
321
|
+
providers/users.providers.ts
|
|
322
|
+
infrastructure/
|
|
323
|
+
services/users-api.service.ts
|
|
324
|
+
repositories/users.repository.impl.ts
|
|
325
|
+
mappers/users.mapper.ts
|
|
326
|
+
presentation/
|
|
327
|
+
pages/users.page.ts
|
|
328
|
+
store/users.store.ts
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Suggested dependency direction:
|
|
332
|
+
|
|
333
|
+
`presentation -> application -> domain`
|
|
334
|
+
`infrastructure -> domain`
|
|
335
|
+
|
|
336
|
+
This keeps the core business model independent from transport and framework details.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 12. Detailed examples (EN)
|
|
341
|
+
|
|
342
|
+
### Example 1: Authentication feature
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
ng g @chejende/clean-arch:feature auth
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Suggested usage:
|
|
349
|
+
|
|
350
|
+
- Keep repository contracts in `domain/repositories`.
|
|
351
|
+
- Implement HTTP calls in `infrastructure/services`.
|
|
352
|
+
- Orchestrate user flows in `application/use-cases`.
|
|
353
|
+
- Handle view state in `presentation/store`.
|
|
354
|
+
|
|
355
|
+
### Example 2: Products feature
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
ng g @chejende/clean-arch:feature products
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Typical design choices:
|
|
362
|
+
|
|
363
|
+
- Keep backend shapes in `products.dto.ts`.
|
|
364
|
+
- Convert DTOs to domain models with `products.mapper.ts`.
|
|
365
|
+
- Keep external calls inside `products.repository.impl.ts`.
|
|
366
|
+
|
|
367
|
+
### Example 3: Orders feature
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
ng g @chejende/clean-arch:feature orders
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Practical extension:
|
|
374
|
+
|
|
375
|
+
- Start with `GetOrdersUseCase`.
|
|
376
|
+
- Add dedicated use cases like `CreateOrderUseCase`, `CancelOrderUseCase`.
|
|
377
|
+
|
|
378
|
+
### Example 4: Provider registration
|
|
379
|
+
|
|
380
|
+
```ts
|
|
381
|
+
import { ApplicationConfig } from '@angular/core';
|
|
382
|
+
import { USERS_PROVIDERS } from './features/users/application/providers/users.providers';
|
|
383
|
+
|
|
384
|
+
export const appConfig: ApplicationConfig = {
|
|
385
|
+
providers: [...USERS_PROVIDERS],
|
|
386
|
+
};
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Example 5: Calling a use case from presentation
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
import { Component, inject } from '@angular/core';
|
|
393
|
+
import { UsersRepository } from '../../domain/repositories/users.repository';
|
|
394
|
+
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case';
|
|
395
|
+
|
|
396
|
+
@Component({
|
|
397
|
+
standalone: true,
|
|
398
|
+
template: `<button (click)="load()">Load users</button>`,
|
|
399
|
+
})
|
|
400
|
+
export class UsersPage {
|
|
401
|
+
private repo = inject(UsersRepository);
|
|
402
|
+
|
|
403
|
+
async load() {
|
|
404
|
+
const useCase = new GetUsersUseCase(this.repo);
|
|
405
|
+
const users = await useCase.execute();
|
|
406
|
+
console.log(users);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Example 6: Explicit mapper usage
|
|
412
|
+
|
|
413
|
+
```ts
|
|
414
|
+
import { UsersMapper } from './features/users/infrastructure/mappers/users.mapper';
|
|
415
|
+
|
|
416
|
+
const dto = { id: '123' };
|
|
417
|
+
const model = UsersMapper.toDomain(dto);
|
|
418
|
+
console.log(model.id);
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Example 7: Layer-based test strategy
|
|
422
|
+
|
|
423
|
+
- `domain`: pure business tests, no Angular runtime needed.
|
|
424
|
+
- `application`: use cases tested with repository mocks.
|
|
425
|
+
- `infrastructure`: adapter and mapper tests.
|
|
426
|
+
- `presentation`: UI/store tests with Angular testing tools when required.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 13. Best practices (EN)
|
|
431
|
+
|
|
432
|
+
1. Keep the domain layer framework-agnostic.
|
|
433
|
+
2. Use interfaces/abstract classes in `domain` for dependency inversion.
|
|
434
|
+
3. Map DTOs to domain models in `infrastructure/mappers`.
|
|
435
|
+
4. Avoid direct HTTP calls from the presentation layer.
|
|
436
|
+
5. Put business behavior into `application/use-cases`.
|
|
437
|
+
6. Register providers per feature to preserve modularity.
|
|
438
|
+
7. Use lowercase, meaningful feature names.
|
|
439
|
+
8. Prefer small, single-purpose use cases.
|
|
440
|
+
9. Keep stores focused on UI state.
|
|
441
|
+
10. Test each layer according to its responsibility.
|
|
442
|
+
|
|
443
|
+
Why this works:
|
|
444
|
+
|
|
445
|
+
- Better testability.
|
|
446
|
+
- Lower coupling.
|
|
447
|
+
- Easier evolution of backend and UI independently.
|
|
448
|
+
- Better long-term scalability for teams.
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## 14. Publish to npm (EN)
|
|
453
|
+
|
|
454
|
+
### Build
|
|
455
|
+
|
|
456
|
+
```bash
|
|
457
|
+
npm run build
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Publish
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
npm publish
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Note: `prepublishOnly` already runs the build process before publishing.
|
|
467
|
+
|
|
468
|
+
Pre-publish checklist:
|
|
469
|
+
|
|
470
|
+
1. Bump `version` in `package.json`.
|
|
471
|
+
2. Verify `dist/` output and generated `collection.json`.
|
|
472
|
+
3. Confirm npm auth using `npm whoami`.
|
|
473
|
+
4. Review this README since it is your npm landing documentation.
|
|
474
|
+
5. Publish with `npm publish --access public` when needed.
|