Esta PoC implementa un flujo simplificado de Payment Processing usando Angular con Standalone Components y Native Federation.
La solución está compuesta por un Shell que orquesta la navegación, la autenticación compartida, la carga remota de Microfrontends y la comunicación entre componentes mediante un Event Bus frontend.
Los dominios funcionales principales son:
- Accounts MFE: consulta cuentas, consulta tarjetas y registra beneficiarios.
- Payments MFE: inicia pagos, confirma pagos, consulta historial y publica eventos.
- Notifications MFE: consulta notificaciones, marca notificaciones como leídas y refleja eventos de pagos.
Cada dominio backend es un servicio REST independiente:
authentication-apiaccounts-apipayments-apinotifications-api
Toda la solución corre localmente, usa datasets JSON como fuente mock.
Esta versión demuestra dos niveles de Microfrontends:
| Patrón | Dónde se ve | Descripción |
|---|---|---|
| Route-level Microfrontends | /accounts, /payments, /notifications |
El Shell carga una aplicación remota completa por ruta. |
| Section-level Microfrontends | Home / |
El Shell carga secciones/cards federadas expuestas por cada MFE. |
En el Home del Shell, las secciones marcadas como:
- Accounts MFE / Cuentas y tarjetas
- Payments MFE / Últimos pagos
- Notifications MFE / Bandeja y alertas
No son cards locales del Shell. Son componentes remotos expuestos por cada Microfrontend mediante Native Federation.
La única sección local del Shell en el Home es:
SHELL-OWNED EVENT BUS MONITOR
Esa sección pertenece al Shell porque representa el monitoreo global de eventos emitidos por los MFEs.
La PoC está alineada a Angular 21.x:
| Elemento | Versión usada |
|---|---|
| Angular framework | 21.2.17 |
| Angular CLI | 21.2.18 |
| Native Federation | @angular-architects/native-federation@21.2.5 |
| TypeScript | 5.9.3 |
| Node.js recomendado | 22.16.0 |
| Backend runtime | Node.js 22 + Express 5 |
| Capa | Tecnología |
|---|---|
| Frontend | Angular 21.2.x, Standalone Components, Angular Router |
| Microfrontends | @angular-architects/native-federation |
| Comunicación frontend | Event Bus basado en window.CustomEvent + RxJS |
| Sesión compartida mock | localStorage, cookie local y sincronización periódica |
| HTTP frontend | HttpClient, withFetch, interceptor funcional |
| Backend | Node.js 22, Express 5, TypeScript 5.9 |
| Validación de comandos | Zod |
| Datasets | JSON local |
| Infraestructura local | Docker Compose + Nginx |
| Requests | REST Client .http |
| Testing backend | Node Test Runner |
flowchart TB
Browser[Browser]
Shell[Shell Angular App<br/>localhost:4200]
AccountsMFE[Accounts MFE<br/>localhost:4201]
PaymentsMFE[Payments MFE<br/>localhost:4202]
NotificationsMFE[Notifications MFE<br/>localhost:4203]
AuthAPI[Authentication API<br/>localhost:3000]
AccountsAPI[Accounts API<br/>localhost:3001]
PaymentsAPI[Payments API<br/>localhost:3002]
NotificationsAPI[Notifications API<br/>localhost:3003]
Datasets[(datasets/json)]
EventBus[[Shared Event Bus]]
Browser --> Shell
Shell -->|Route federation<br/>./Component| AccountsMFE
Shell -->|Route federation<br/>./Component| PaymentsMFE
Shell -->|Route federation<br/>./Component| NotificationsMFE
Shell -->|Home section federation<br/>./HomeSection| AccountsMFE
Shell -->|Home section federation<br/>./HomeSection| PaymentsMFE
Shell -->|Home section federation<br/>./HomeSection| NotificationsMFE
Shell --> AuthAPI
AccountsMFE --> AccountsAPI
PaymentsMFE --> PaymentsAPI
PaymentsMFE --> NotificationsAPI
NotificationsMFE --> NotificationsAPI
PaymentsMFE --> EventBus
NotificationsMFE --> EventBus
Shell --> EventBus
AuthAPI --> Datasets
AccountsAPI --> Datasets
PaymentsAPI --> Datasets
NotificationsAPI --> Datasets
payment-processing-poc/
├── angular.json
├── package.json
├── README.md
├── VALIDATION.md
├── tsconfig.json
├── projects/
│ ├── shell/
│ │ ├── public/
│ │ │ └── federation.manifest.json
│ │ └── src/app/
│ │ ├── app.routes.ts
│ │ ├── home.component.ts
│ │ ├── home.component.html
│ │ ├── login.component.ts
│ │ └── app.ts
│ ├── accounts/
│ │ ├── federation.config.js
│ │ └── src/app/
│ │ ├── app.ts
│ │ └── accounts-home-section.component.ts
│ ├── payments/
│ │ ├── federation.config.js
│ │ └── src/app/
│ │ ├── app.ts
│ │ └── payments-home-section.component.ts
│ ├── notifications/
│ │ ├── federation.config.js
│ │ └── src/app/
│ │ ├── app.ts
│ │ └── notifications-home-section.component.ts
│ └── shared/
│ └── src/lib/
│ ├── api-config.ts
│ ├── auth-api.service.ts
│ ├── auth-session.service.ts
│ ├── auth-token.interceptor.ts
│ ├── auth.guard.ts
│ ├── event-bus.service.ts
│ ├── login-panel.component.ts
│ └── models.ts
├── backends/
│ ├── authentication/
│ ├── accounts/
│ ├── payments/
│ └── notifications/
├── datasets/
│ ├── json/
│ └── scripts/
├── requests/
│ ├── payment-processing-poc.http
│ └── responses/
└── infrastructure/
├── docker-compose.yml
├── frontend.Dockerfile
├── nginx/
├── manifests/
├── mock-services/
├── requests/
├── responses/
└── scripts/
El Shell es la aplicación principal.
Responsabilidades:
- Cargar
federation.manifest.json. - Resolver rutas remotas hacia Accounts, Payments y Notifications.
- Cargar secciones federadas de Home expuestas por cada MFE.
- Gestionar login/logout demo.
- Proteger rutas remotas usando
authGuard. - Mantener navegación principal.
- Escuchar eventos globales del Event Bus.
- Mostrar el monitor local
Shell-owned Event Bus Monitor.
Rutas principales:
| Ruta | Origen | Protección | Descripción |
|---|---|---|---|
/ |
Shell + secciones federadas | Requiere sesión para mostrar secciones remotas | Home con secciones remotas de cada MFE |
/login |
Shell | Pública | Login mock compartido |
/accounts |
Accounts MFE | authGuard |
Gestión de cuentas, tarjetas y beneficiarios |
/payments |
Payments MFE | authGuard |
Inicio y confirmación de pagos |
/notifications |
Notifications MFE | authGuard |
Bandeja de notificaciones |
Responsabilidades:
- Consultar cuentas.
- Consultar tarjetas asociadas a una cuenta.
- Consultar beneficiarios.
- Registrar beneficiarios mock.
- Exponer una sección federada para el Home del Shell.
- Bloquear contenido cuando se abre standalone sin sesión.
Backend asociado: accounts-api.
Exposes principales:
exposes: {
'./Component': './projects/accounts/src/app/app.ts',
'./HomeSection': './projects/accounts/src/app/accounts-home-section.component.ts',
}Responsabilidades:
- Iniciar pago.
- Recibir código mock de autorización.
- Confirmar pago.
- Consultar historial.
- Refrescar historial automáticamente después de iniciar o confirmar pagos.
- Publicar eventos
PAYMENT_INITIATEDyPAYMENT_CONFIRMED. - Registrar notificaciones mock en
notifications-apimediante/notifications/payment-events. - Exponer una sección federada para el Home del Shell.
- Bloquear contenido cuando se abre standalone sin sesión.
Backend asociado: payments-api.
Exposes principales:
exposes: {
'./Component': './projects/payments/src/app/app.ts',
'./HomeSection': './projects/payments/src/app/payments-home-section.component.ts',
}Responsabilidades:
- Consultar notificaciones.
- Refrescar bandeja automáticamente.
- Marcar notificaciones como leídas.
- Escuchar eventos vivos del Event Bus.
- Exponer una sección federada para el Home del Shell.
- Bloquear contenido cuando se abre standalone sin sesión.
Backend asociado: notifications-api.
Exposes principales:
exposes: {
'./Component': './projects/notifications/src/app/app.ts',
'./HomeSection': './projects/notifications/src/app/notifications-home-section.component.ts',
}El Home del Shell carga dinámicamente componentes remotos usando Native Federation:
loadRemoteModule('accounts', './HomeSection')
loadRemoteModule('payments', './HomeSection')
loadRemoteModule('notifications', './HomeSection')Cada remoto devuelve un componente standalone:
| Remote name | Expose | Componente remoto |
|---|---|---|
accounts |
./HomeSection |
AccountsHomeSectionComponent |
payments |
./HomeSection |
PaymentsHomeSectionComponent |
notifications |
./HomeSection |
NotificationsHomeSectionComponent |
El Shell renderiza esos componentes mediante NgComponentOutlet.
flowchart LR
ShellHome[Shell Home]
AccountsSection[AccountsHomeSectionComponent]
PaymentsSection[PaymentsHomeSectionComponent]
NotificationsSection[NotificationsHomeSectionComponent]
EventBusMonitor[Shell-owned Event Bus Monitor]
ShellHome -->|loadRemoteModule accounts ./HomeSection| AccountsSection
ShellHome -->|loadRemoteModule payments ./HomeSection| PaymentsSection
ShellHome -->|loadRemoteModule notifications ./HomeSection| NotificationsSection
ShellHome --> EventBusMonitor
AccountsSection --> AccountsAPI[Accounts API]
PaymentsSection --> PaymentsAPI[Payments API]
NotificationsSection --> NotificationsAPI[Notifications API]
La librería projects/shared contiene elementos reutilizables:
| Elemento | Responsabilidad |
|---|---|
AuthSessionService |
Administra sesión compartida mock con localStorage, cookie local y sincronización. |
AuthApiService |
Consume authentication-api para login/logout. |
authTokenInterceptor |
Agrega Authorization: Bearer <accessToken> a las llamadas HTTP. |
authGuard |
Protege rutas remotas del Shell. |
LoginPanelComponent |
Componente standalone de login reutilizado por Shell y MFEs. |
EventBusService |
Publica y escucha eventos mediante window.CustomEvent. |
PAYMENT_PROCESSING_API_CONFIG |
Configuración de URLs locales de APIs. |
models.ts |
Contratos compartidos. |
Exports esperados en projects/shared/src/public-api.ts:
export * from './lib/api-config';
export * from './lib/auth-api.service';
export * from './lib/auth-session.service';
export * from './lib/auth-token.interceptor';
export * from './lib/auth.guard';
export * from './lib/event-bus.service';
export * from './lib/login-panel.component';
export * from './lib/models';Importante: cuando se modifica projects/shared, se debe recompilar la librería antes de levantar Shell/MFEs:
npm run build:sharedEl script start:all ya ejecuta npm run build:shared automáticamente.
La autenticación es mock y local. No se usa proveedor real de identidad ni OAuth/OIDC real.
Credenciales demo:
username: edgar
password: demo
La sesión se comparte entre:
- Shell:
http://localhost:4200 - Accounts MFE:
http://localhost:4201 - Payments MFE:
http://localhost:4202 - Notifications MFE:
http://localhost:4203
Mecanismos usados:
localStoragecon la clavepayment-processing.session.- Cookie local
payment_processing_sessionconPath=/ySameSite=Lax. - Evento browser
payment-processing.session.changed. - Sincronización periódica cada 1 segundo para apps abiertas en puertos distintos.
- Interceptor HTTP que envía el token mock en cada llamada.
Flujo de autenticación:
sequenceDiagram
participant User as Usuario
participant Login as LoginPanelComponent
participant Auth as Authentication API
participant Session as AuthSessionService
participant Shell as Shell / MFE
User->>Login: Ingresa edgar/demo
Login->>Auth: POST /auth/login
Auth-->>Login: accessToken + user
Login->>Session: login(session)
Session->>Session: Guarda localStorage + cookie
Session->>Shell: Actualiza signal session
Shell-->>User: Renderiza contenido protegido
sequenceDiagram
participant Browser
participant Shell
participant Manifest as federation.manifest.json
participant Remote as Remote MFE
Browser->>Shell: GET /
Shell->>Manifest: Carga manifiesto
Browser->>Shell: Navega a /payments
Shell->>Shell: authGuard valida sesión
Shell->>Remote: GET http://localhost:4202/remoteEntry.json
Remote-->>Shell: Exposes ./Component
Shell-->>Browser: Renderiza Payments MFE
sequenceDiagram
participant Payments as Payments MFE
participant Bus as EventBusService
participant Shell as Shell Home
participant Notifications as Notifications MFE
Payments->>Bus: publish PAYMENT_INITIATED
Bus-->>Shell: Evento recibido
Bus-->>Notifications: Evento recibido
Payments->>Bus: publish PAYMENT_CONFIRMED
Bus-->>Shell: Actualiza Shell-owned Event Bus Monitor
Bus-->>Notifications: Actualiza eventos vivos
El Event Bus es frontend-only y usa window.CustomEvent.
Sirve para demostrar comunicación entre MFEs cargados dentro de la misma ventana/shell.
Si se abren MFEs en pestañas separadas, el Event Bus no cruza pestañas. Para cubrir ese caso, Payments MFE registra eventos de pago en notifications-api, y Notifications MFE refresca su bandeja contra el backend mock.
Cuando se inicia o confirma un pago, el flujo actual es:
sequenceDiagram
participant User as Usuario
participant PaymentsMFE as Payments MFE
participant PaymentsAPI as Payments API
participant NotificationsAPI as Notifications API
participant EventBus as Event Bus
participant NotificationsMFE as Notifications MFE
User->>PaymentsMFE: Iniciar pago
PaymentsMFE->>PaymentsAPI: POST /payments/initiate
PaymentsAPI-->>PaymentsMFE: paymentId + authorizationCode
PaymentsMFE->>NotificationsAPI: POST /notifications/payment-events
NotificationsAPI-->>PaymentsMFE: Notificación creada
PaymentsMFE->>EventBus: PAYMENT_INITIATED
PaymentsMFE->>PaymentsMFE: Refresca historial
User->>PaymentsMFE: Confirmar pago
PaymentsMFE->>PaymentsAPI: POST /payments/{id}/confirm
PaymentsAPI-->>PaymentsMFE: Pago CONFIRMED
PaymentsMFE->>NotificationsAPI: POST /notifications/payment-events
NotificationsAPI-->>PaymentsMFE: Notificación creada
PaymentsMFE->>EventBus: PAYMENT_CONFIRMED
NotificationsMFE->>NotificationsAPI: GET /notifications
NotificationsAPI-->>NotificationsMFE: Bandeja actualizada
Esto simula una integración asincrónica sin usar brokers ni infraestructura adicional.
Archivo:
projects/shell/public/federation.manifest.json
Contenido:
{
"accounts": "http://localhost:4201/remoteEntry.json",
"payments": "http://localhost:4202/remoteEntry.json",
"notifications": "http://localhost:4203/remoteEntry.json"
}El Shell resuelve dinámicamente cada remoto con:
loadRemoteModule('payments', './Component')
loadRemoteModule('payments', './HomeSection')Cada MFE expone su componente principal y su sección de Home en su federation.config.js:
exposes: {
'./Component': './projects/payments/src/app/app.ts',
'./HomeSection': './projects/payments/src/app/payments-home-section.component.ts',
}flowchart LR
Browser[Browser] --> Shell[Shell :4200]
Shell --> Manifest[federation.manifest.json]
Manifest --> AccountsEntry[accounts remoteEntry.json :4201]
Manifest --> PaymentsEntry[payments remoteEntry.json :4202]
Manifest --> NotificationsEntry[notifications remoteEntry.json :4203]
AccountsEntry --> AccountsComponent[Accounts Remote Component]
PaymentsEntry --> PaymentsComponent[Payments Remote Component]
NotificationsEntry --> NotificationsComponent[Notifications Remote Component]
Shell --> AccountsComponent
Shell --> PaymentsComponent
Shell --> NotificationsComponent
Cada frontend se puede construir y servir de forma independiente:
| Aplicación | Puerto local | Artefacto |
|---|---|---|
| Shell | 4200 | dist/shell/browser |
| Accounts MFE | 4201 | dist/accounts/browser |
| Payments MFE | 4202 | dist/payments/browser |
| Notifications MFE | 4203 | dist/notifications/browser |
En Docker Compose cada aplicación se sirve con Nginx en su propio contenedor.
También se pueden abrir los MFEs directamente:
Accounts MFE http://localhost:4201
Payments MFE http://localhost:4202
Notifications MFE http://localhost:4203
Shell http://localhost:4200
Si no existe sesión compartida, los MFEs standalone muestran el login y no renderizan el contenido funcional.
Cada backend es independiente y mantiene esta estructura mínima:
src/
├── domain/
│ ├── entities/
│ └── repositories/
├── application/
│ ├── ports/
│ └── use-cases/
├── infrastructure/
│ └── persistence/
└── presentation/
├── http/
├── routes/
└── server.ts
flowchart LR
Presentation[Presentation<br/>REST Controllers / Routes]
Application[Application<br/>Use Cases]
Domain[Domain<br/>Entities + Repository Contracts]
Infrastructure[Infrastructure<br/>JSON Dataset Adapters]
Presentation --> Application
Application --> Domain
Infrastructure --> Domain
Presentation --> Infrastructure
| Orden | Dominio | Método | URL | Descripción funcional | Descripción técnica |
|---|---|---|---|---|---|
| 1 | Authentication | GET | http://localhost:3000/health |
Verifica disponibilidad | Health check del servicio |
| 2 | Authentication | POST | http://localhost:3000/auth/login |
Login demo | Valida usuario desde users.json y devuelve token mock |
| 3 | Authentication | GET | http://localhost:3000/auth/me |
Consulta perfil | Devuelve usuario mock autenticado |
| 4 | Authentication | POST | http://localhost:3000/auth/logout |
Logout demo | Devuelve confirmación de logout |
| 5 | Accounts | GET | http://localhost:3001/health |
Verifica disponibilidad | Health check del servicio |
| 6 | Accounts | GET | http://localhost:3001/accounts/summary |
Sección federada de Home | Agrega saldos y número de tarjetas |
| 7 | Accounts | GET | http://localhost:3001/accounts |
Consulta cuentas | Lee accounts.json |
| 8 | Accounts | GET | http://localhost:3001/accounts/{id}/cards |
Consulta tarjetas | Filtra cards.json por cuenta |
| 9 | Accounts | GET | http://localhost:3001/beneficiaries |
Consulta beneficiarios | Lee beneficiaries.json |
| 10 | Accounts | POST | http://localhost:3001/beneficiaries |
Registro de beneficiario | Valida comando con Zod y guarda en memoria |
| 11 | Payments | GET | http://localhost:3002/health |
Verifica disponibilidad | Health check del servicio |
| 12 | Payments | GET | http://localhost:3002/payments/history?limit=3 |
Sección federada de Home / historial | Ordena pagos por fecha y aplica límite |
| 13 | Payments | GET | http://localhost:3002/payments |
Lista pagos | Lee pagos iniciales y pagos creados en memoria |
| 14 | Payments | POST | http://localhost:3002/payments/initiate |
Inicia pago | Crea pago INITIATED y código mock |
| 15 | Payments | POST | http://localhost:3002/payments/{id}/confirm |
Confirma pago | Valida código mock y cambia estado a CONFIRMED |
| 16 | Payments | GET | http://localhost:3002/payments/{id} |
Consulta pago | Busca pago por identificador |
| 17 | Notifications | GET | http://localhost:3003/health |
Verifica disponibilidad | Health check del servicio |
| 18 | Notifications | GET | http://localhost:3003/notifications?limit=5 |
Consulta notificaciones | Lee notifications.json y aplica límite |
| 19 | Notifications | POST | http://localhost:3003/notifications/{id}/read |
Marca notificación | Cambia estado read en memoria |
| 20 | Notifications | POST | http://localhost:3003/notifications/payment-events |
Registra evento de pago | Crea notificación mock desde evento de pago |
Los datasets están en:
datasets/json/
├── accounts.json
├── beneficiaries.json
├── cards.json
├── movements.json
├── notifications.json
├── payments.json
└── users.json
Los backends cargan estos archivos al iniciar mediante la variable:
DATASET_PATH=$PWD/datasets/json
Para revisar o resetear los datasets locales:
./datasets/scripts/reset-local-datasets.shNo hay base de datos. Los cambios realizados por POST se guardan en memoria mientras el backend correspondiente esté ejecutándose.
Archivo principal REST Client:
requests/payment-processing-poc.http
También hay respuestas de ejemplo en:
requests/responses/
infrastructure/responses/
Desde la raíz del proyecto:
npm run docker:upEsto ejecuta:
- Shell:
http://localhost:4200 - Accounts MFE:
http://localhost:4201 - Payments MFE:
http://localhost:4202 - Notifications MFE:
http://localhost:4203 - Authentication API:
http://localhost:3000 - Accounts API:
http://localhost:3001 - Payments API:
http://localhost:3002 - Notifications API:
http://localhost:3003
Health check:
./infrastructure/scripts/health-check.shApagar:
npm run docker:downDesde la raíz:
cd ~/Workspace/payment-processing-poc
npm run install:allEl script install:all instala:
- Dependencias del workspace Angular raíz.
- Dependencias de
backends/authentication. - Dependencias de
backends/accounts. - Dependencias de
backends/payments. - Dependencias de
backends/notifications.
Instalar dependencias frontend:
npm install --no-audit --no-fund --registry=https://registry.npmjs.org/Instalar dependencias backend:
npm --prefix backends/authentication install --no-audit --no-fund --registry=https://registry.npmjs.org/
npm --prefix backends/accounts install --no-audit --no-fund --registry=https://registry.npmjs.org/
npm --prefix backends/payments install --no-audit --no-fund --registry=https://registry.npmjs.org/
npm --prefix backends/notifications install --no-audit --no-fund --registry=https://registry.npmjs.org/Si vienes de un ZIP anterior o un lock generado en otro entorno, puedes limpiar antes:
rm -rf node_modules package-lock.json
rm -rf backends/authentication/node_modules backends/authentication/package-lock.json
rm -rf backends/accounts/node_modules backends/accounts/package-lock.json
rm -rf backends/payments/node_modules backends/payments/package-lock.json
rm -rf backends/notifications/node_modules backends/notifications/package-lock.jsonLuego reinstala con los comandos anteriores.
npm run build:allCompilación por partes:
npm run build:shared
npm run build:frontends
npm run build:apisnpm run start:api:authentication
npm run start:api:accounts
npm run start:api:payments
npm run start:api:notificationsnpm run start:accounts-mfe
npm run start:payments-mfe
npm run start:notifications-mfe
npm run start:shellOpción recomendada:
npm run start:allEste script ejecuta primero:
npm run build:sharedy luego levanta APIs, MFEs y Shell con concurrently.
Comando manual equivalente:
npm install --no-audit --no-fund --registry=https://registry.npmjs.org/ --verbose
npm --prefix backends/authentication install --no-audit --no-fund --registry=https://registry.npmjs.org/ --verbose
npm --prefix backends/accounts install --no-audit --no-fund --registry=https://registry.npmjs.org/ --verbose
npm --prefix backends/payments install --no-audit --no-fund --registry=https://registry.npmjs.org/ --verbose
npm --prefix backends/notifications install --no-audit --no-fund --registry=https://registry.npmjs.org/ --verbose
export DATASET_PATH="$(pwd)/datasets/json"
npx concurrently -k \
-n auth-api,accounts-api,payments-api,notifications-api,accounts-mfe,payments-mfe,notifications-mfe,shell \
"PORT=3000 DATASET_PATH=$DATASET_PATH npm --prefix backends/authentication run dev" \
"PORT=3001 DATASET_PATH=$DATASET_PATH npm --prefix backends/accounts run dev" \
"PORT=3002 DATASET_PATH=$DATASET_PATH npm --prefix backends/payments run dev" \
"PORT=3003 DATASET_PATH=$DATASET_PATH npm --prefix backends/notifications run dev" \
"npm run start:accounts-mfe" \
"npm run start:payments-mfe" \
"npm run start:notifications-mfe" \
"npm run start:shell"Abrir:
Shell http://localhost:4200
Accounts MFE http://localhost:4201
Payments MFE http://localhost:4202
Notifications MFE http://localhost:4203
| Script | Descripción |
|---|---|
npm run install:all |
Instala dependencias del workspace y de todos los backends. |
npm run build:shared |
Compila la librería compartida. |
npm run build:frontends |
Compila Shell y MFEs. |
npm run build:apis |
Compila los cuatro backends. |
npm run build:all |
Compila frontends y APIs. |
npm run start:apis |
Levanta las cuatro APIs. |
npm run start:frontends |
Compila shared y levanta Shell + MFEs. |
npm run start:all |
Compila shared y levanta APIs + Shell + MFEs. |
npm run test:apis |
Ejecuta pruebas unitarias de backends. |
npm run docker:up |
Levanta la solución con Docker Compose. |
npm run docker:down |
Apaga Docker Compose y elimina volúmenes. |
- Crear la aplicación Angular:
npx ng generate application new-domain --standalone --routing --style=scss --ssr=false- Inicializar Native Federation:
npx ng g @angular-architects/native-federation:init --project new-domain --port 4204 --type remote- Exponer el componente principal en
projects/new-domain/federation.config.js:
exposes: {
'./Component': './projects/new-domain/src/app/app.ts',
}- Agregar el remoto al manifest del Shell:
{
"new-domain": "http://localhost:4204/remoteEntry.json"
}- Agregar ruta en
projects/shell/src/app/app.routes.ts:
{
path: 'new-domain',
canActivate: [authGuard],
loadComponent: () => loadRemoteModule('new-domain', './Component').then((m) => m.App),
}- Agregar servicio Docker Compose si se requiere despliegue local independiente.
Este es el patrón recomendado para evitar cards locales en el Shell.
- Crear un componente standalone en el MFE:
projects/new-domain/src/app/new-domain-home-section.component.ts
- Exponerlo en
federation.config.js:
exposes: {
'./Component': './projects/new-domain/src/app/app.ts',
'./HomeSection': './projects/new-domain/src/app/new-domain-home-section.component.ts',
}- Cargarlo desde el Home del Shell:
readonly newDomainHomeSection = loadRemoteModule('new-domain', './HomeSection')
.then((m) => m.NewDomainHomeSectionComponent);- Renderizarlo con
NgComponentOutlet:
@if (newDomainHomeSection | async; as section) {
<ng-container *ngComponentOutlet="section"></ng-container>
}- Mantener la navegación de detalle con
routerLinkhacia la ruta remota:
<a routerLink="/new-domain">Ver detalle</a>Este patrón se mantiene como opción cuando el widget pertenece realmente al Shell, como el monitor de Event Bus.
- Crear o extender el endpoint backend que entregue el agregado necesario.
- Consumir el endpoint desde el componente del Shell.
- Agregar la tarjeta visual en el HTML del Shell.
- Si el widget depende de eventos, suscribirse a
EventBusService.events$.
Regla recomendada:
- Si el widget representa una capacidad de un dominio, exponerlo desde el MFE dueño del dominio.
- Si el widget representa una capacidad transversal del Shell, implementarlo localmente en el Shell.
- Crear carpeta bajo
backends/new-domain. - Mantener estructura:
src/domain
src/application
src/infrastructure
src/presentation
- Definir entidades y contratos en
domain. - Crear casos de uso en
application/use-cases. - Implementar adaptadores mock en
infrastructure/persistence. - Exponer endpoints en
presentation/routes. - Agregar
Dockerfiley servicio eninfrastructure/docker-compose.yml. - Agregar ejemplos al archivo
requests/payment-processing-poc.http. - Agregar el nuevo backend al script
install:all,build:apis,start:apisystart:all.
Ejecutar todas:
npm run test:apisPruebas incluidas:
| Backend | Prueba funcional | Prueba técnica |
|---|---|---|
| Authentication | Usuario demo puede autenticarse | LoginUseCase genera token mock |
| Accounts | Se agregan saldos y tarjetas | GetAccountSummaryUseCase usa contrato de repositorio |
| Payments | Pago puede iniciarse y confirmarse | InitiatePaymentUseCase + ConfirmPaymentUseCase |
| Notifications | Notificación puede marcarse como leída | MarkNotificationReadUseCase cambia estado |
Ejecutar:
npm testRequiere Chrome/Chromium disponible y variable CHROME_BIN configurada si el binario no está en el PATH.
- Instalar dependencias con
npm run install:all. - Levantar la solución con
npm run start:all. - Abrir
http://localhost:4200. - Verificar que el Home solicite login si no hay sesión.
- Iniciar sesión con
edgar / demo. - Verificar que el Home muestre las secciones federadas de Accounts, Payments y Notifications.
- Navegar a
Accountsy verificar cuentas, tarjetas y beneficiarios. - Registrar un beneficiario y verificar que la lista se refresque.
- Navegar a
Payments. - Iniciar pago y verificar que el historial se refresque con estado
INITIATED. - Confirmar pago y verificar que el historial se refresque con estado
CONFIRMED. - Verificar que el monitor Event Bus del Shell recibe eventos.
- Navegar a
Notificationsy verificar que se crearon notificaciones por eventos de pago. - Marcar una notificación como leída y verificar que la bandeja se refresque.
- Abrir
http://localhost:4201,http://localhost:4202yhttp://localhost:4203sin sesión y verificar que cada MFE muestre login. - Consumir endpoints desde
requests/payment-processing-poc.http.
Verificar registry público:
npm config get registryDebe responder:
https://registry.npmjs.org/
Buscar referencias a registry interno:
grep -R "applied-caas-gateway" package-lock.json backends/*/package-lock.json 2>/dev/nullVerificar Angular CLI local:
ls -la node_modules/.bin/ng
npx ng versionVerificar tsx en backends:
ls -la backends/authentication/node_modules/.bin/tsx
ls -la backends/accounts/node_modules/.bin/tsx
ls -la backends/payments/node_modules/.bin/tsx
ls -la backends/notifications/node_modules/.bin/tsxVerificar datasets:
ls -la datasets/jsonVerificar health checks:
curl http://localhost:3000/health
curl http://localhost:3001/health
curl http://localhost:3002/health
curl http://localhost:3003/healthVerificar remotes:
curl http://localhost:4201/remoteEntry.json
curl http://localhost:4202/remoteEntry.json
curl http://localhost:4203/remoteEntry.json