@chejende/clean-arch
v1.0.7
Published
Angular Clean Architecture schematics
Downloads
68
Maintainers
Readme
@chejende/clean-arch
Angular schematic para generar features con Clean Architecture (Hexagonal-inspired) de forma consistente, rapida y mantenible.
This package provides an Angular schematic to scaffold features using a Clean Architecture (Hexagonal-inspired) structure that is consistent, fast, and maintainable.
Tabla de Contenidos / Table of Contents
- 1. ¿Para que sirve? (ES)
- 2. Instalacion (ES)
- 3. Uso rapido (ES)
- 4. Arquitectura generada (ES)
- 5. Ejemplos detallados (ES)
- 6. Buenas practicas (ES)
- 7. Publicar en npm (ES)
- 8. What is this for? (EN)
- 9. Installation (EN)
- 10. Quick start (EN)
- 11. Generated architecture (EN)
- 12. Detailed examples (EN)
- 13. Best practices (EN)
- 14. Publish to npm (EN)
1. ¿Para que sirve? (ES)
@chejende/clean-arch crea automaticamente el esqueleto de una feature en Angular separando responsabilidades por capas:
domain: reglas y contratos del negocio.application: casos de uso, DTOs y providers.infrastructure: integraciones tecnicas (API, repositorios concretos, mappers).presentation: pagina/componente y store para estado UI.
Objetivo:
- Reducir tiempo de arranque de nuevas funcionalidades.
- Estandarizar estructura entre equipos.
- Evitar mezcla de logica de negocio con detalles de framework o transporte.
2. Instalacion (ES)
Como dependencia de desarrollo
npm install -D @chejende/clean-archUso sin instalar (one-shot)
npx -p @chejende/clean-arch ng g @chejende/clean-arch:feature usersRequisito recomendado: Angular CLI instalado en el proyecto.
3. Uso rapido (ES)
Comando principal
ng g @chejende/clean-arch:feature --name=usersTambien funciona con argumento posicional:
ng g @chejende/clean-arch:feature usersAlternativa con schematics
npx schematics @chejende/clean-arch:feature --name=users4. Arquitectura generada (ES)
Para users, se genera:
src/app/features/users/
domain/
models/users.model.ts
repositories/users.repository.ts
application/
dto/users.dto.ts
use-cases/get-users.use-case.ts
providers/users.providers.ts
infrastructure/
services/users-api.service.ts
repositories/users.repository.impl.ts
mappers/users.mapper.ts
presentation/
pages/users.page.ts
store/users.store.tsFlujo de dependencias recomendado
presentation -> application -> domaininfrastructure -> domain
Esto evita acoplar la logica de negocio con Angular, HTTP o detalles de infraestructura.
5. Ejemplos detallados (ES)
Ejemplo 1: Feature de autenticacion
ng g @chejende/clean-arch:feature authUso recomendado:
- Definir contratos en
domain/repositories/auth.repository.ts. - Implementar consumo HTTP en
infrastructure/services/auth-api.service.ts. - Orquestar flujo en
application/use-cases/get-auth.use-case.ts. - Exponer estado en
presentation/store/auth.store.ts.
Ejemplo 2: Feature de productos
ng g @chejende/clean-arch:feature productsBuenas decisiones comunes:
products.dto.ts: forma de datos de entrada/salida de backend.products.mapper.ts: conversion DTO -> Modelo de dominio.products.repository.impl.ts: delega en API service y devuelve dominio.
Ejemplo 3: Feature de ordenes
ng g @chejende/clean-arch:feature ordersCaso practico:
- Crear
GetOrdersUseCasepara lectura. - Agregar otros casos de uso (
CreateOrderUseCase,CancelOrderUseCase) dentro deapplication/use-cases.
Ejemplo 4: Registro de providers
En la feature users, el schematic crea USERS_PROVIDERS. Puedes registrarlo en config de app:
import { ApplicationConfig } from '@angular/core';
import { USERS_PROVIDERS } from './features/users/application/providers/users.providers';
export const appConfig: ApplicationConfig = {
providers: [...USERS_PROVIDERS],
};Ejemplo 5: Uso del caso de uso desde presentacion
import { Component, inject } from '@angular/core';
import { UsersRepository } from '../../domain/repositories/users.repository';
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case';
@Component({
standalone: true,
template: `<button (click)="load()">Load users</button>`,
})
export class UsersPage {
private repo = inject(UsersRepository);
async load() {
const useCase = new GetUsersUseCase(this.repo);
const users = await useCase.execute();
console.log(users);
}
}Ejemplo 6: Mapper explicito
import { UsersMapper } from './features/users/infrastructure/mappers/users.mapper';
const dto = { id: '123' };
const model = UsersMapper.toDomain(dto);
console.log(model.id);Ejemplo 7: Flujo de prueba unitaria por capa
domain: prueba reglas puras sin Angular.application: prueba casos de uso con mocks de repositorio.infrastructure: prueba adaptadores y mappers.presentation: prueba componentes/store con TestBed cuando aplique.
6. Buenas practicas (ES)
- Mantener el dominio libre de framework.
- Usar interfaces/abstract classes en
domainpara inversion de dependencias. - Mapear DTOs a modelos de dominio en
infrastructure/mappers. - Evitar llamadas HTTP directas desde
presentation. - Encapsular logica de negocio en casos de uso (
application/use-cases). - Registrar providers por feature para modularidad.
- Nombrar features en minuscula y en plural cuando representen colecciones (
users,products). - Agregar casos de uso pequenos y orientados a una accion.
- Mantener stores enfocados en estado de interfaz, no en reglas de negocio.
- Probar cada capa segun su responsabilidad.
Por que hacerlo asi:
- Mejora testabilidad.
- Reduce acoplamiento.
- Facilita cambios de backend/UI sin romper reglas del negocio.
- Escala mejor en equipos grandes y monorepos.
7. Publicar en npm (ES)
Build local
npm run buildPublicacion
npm publishNota: este paquete ya tiene prepublishOnly, por lo que npm publish ejecuta build antes de publicar.
Checklist previa:
- Incrementar version en
package.json. - Verificar que
dist/se genera correctamente. - Confirmar credenciales con
npm whoami. - Revisar README (este archivo) porque sera la documentacion en npm.
- Publicar con
npm publish --access publicsi aplica.
8. What is this for? (EN)
@chejende/clean-arch automatically scaffolds Angular features following Clean Architecture layers:
domain: business contracts and rules.application: use cases, DTOs, and providers.infrastructure: API services, concrete repositories, and mappers.presentation: UI page/component and feature store.
Main goals:
- Speed up feature bootstrap.
- Keep a consistent architecture across teams.
- Prevent business logic from being coupled to framework details.
9. Installation (EN)
As a dev dependency
npm install -D @chejende/clean-archOne-shot usage (without installing)
npx -p @chejende/clean-arch ng g @chejende/clean-arch:feature usersRecommended prerequisite: Angular CLI available in the target project.
10. Quick start (EN)
ng g @chejende/clean-arch:feature --name=usersPositional argument also works:
ng g @chejende/clean-arch:feature usersAlternative with schematics:
npx schematics @chejende/clean-arch:feature --name=users11. Generated architecture (EN)
For users, the schematic creates:
src/app/features/users/
domain/
models/users.model.ts
repositories/users.repository.ts
application/
dto/users.dto.ts
use-cases/get-users.use-case.ts
providers/users.providers.ts
infrastructure/
services/users-api.service.ts
repositories/users.repository.impl.ts
mappers/users.mapper.ts
presentation/
pages/users.page.ts
store/users.store.tsSuggested dependency direction:
presentation -> application -> domaininfrastructure -> domain
This keeps the core business model independent from transport and framework details.
12. Detailed examples (EN)
Example 1: Authentication feature
ng g @chejende/clean-arch:feature authSuggested usage:
- Keep repository contracts in
domain/repositories. - Implement HTTP calls in
infrastructure/services. - Orchestrate user flows in
application/use-cases. - Handle view state in
presentation/store.
Example 2: Products feature
ng g @chejende/clean-arch:feature productsTypical design choices:
- Keep backend shapes in
products.dto.ts. - Convert DTOs to domain models with
products.mapper.ts. - Keep external calls inside
products.repository.impl.ts.
Example 3: Orders feature
ng g @chejende/clean-arch:feature ordersPractical extension:
- Start with
GetOrdersUseCase. - Add dedicated use cases like
CreateOrderUseCase,CancelOrderUseCase.
Example 4: Provider registration
import { ApplicationConfig } from '@angular/core';
import { USERS_PROVIDERS } from './features/users/application/providers/users.providers';
export const appConfig: ApplicationConfig = {
providers: [...USERS_PROVIDERS],
};Example 5: Calling a use case from presentation
import { Component, inject } from '@angular/core';
import { UsersRepository } from '../../domain/repositories/users.repository';
import { GetUsersUseCase } from '../../application/use-cases/get-users.use-case';
@Component({
standalone: true,
template: `<button (click)="load()">Load users</button>`,
})
export class UsersPage {
private repo = inject(UsersRepository);
async load() {
const useCase = new GetUsersUseCase(this.repo);
const users = await useCase.execute();
console.log(users);
}
}Example 6: Explicit mapper usage
import { UsersMapper } from './features/users/infrastructure/mappers/users.mapper';
const dto = { id: '123' };
const model = UsersMapper.toDomain(dto);
console.log(model.id);Example 7: Layer-based test strategy
domain: pure business tests, no Angular runtime needed.application: use cases tested with repository mocks.infrastructure: adapter and mapper tests.presentation: UI/store tests with Angular testing tools when required.
13. Best practices (EN)
- Keep the domain layer framework-agnostic.
- Use interfaces/abstract classes in
domainfor dependency inversion. - Map DTOs to domain models in
infrastructure/mappers. - Avoid direct HTTP calls from the presentation layer.
- Put business behavior into
application/use-cases. - Register providers per feature to preserve modularity.
- Use lowercase, meaningful feature names.
- Prefer small, single-purpose use cases.
- Keep stores focused on UI state.
- Test each layer according to its responsibility.
Why this works:
- Better testability.
- Lower coupling.
- Easier evolution of backend and UI independently.
- Better long-term scalability for teams.
14. Publish to npm (EN)
Build
npm run buildPublish
npm publishNote: prepublishOnly already runs the build process before publishing.
Pre-publish checklist:
- Bump
versioninpackage.json. - Verify
dist/output and generatedcollection.json. - Confirm npm auth using
npm whoami. - Review this README since it is your npm landing documentation.
- Publish with
npm publish --access publicwhen needed.
