High Level Design (HLD) - Employee Revenue Microservice
1. Resumen Ejecutivo
Propósito del microservicio
El microservicio alpura-back-msa-transactions (identificado como módulo de Arquitectura Base ex en pom.xml) tiene como propósito principal la gestión y consulta de saldos y redención de productos para empleados. Actúa como el backend transaccional que permite visualizar el balance disponible de beneficios (productos) y ejecutar el canje de los mismos en tiendas.
Funcionalidad principal
- Consulta de Saldo: Permite obtener el balance detallado de productos disponibles para un empleado, buscando por su número de nómina.
- Redención de Productos: Procesa transacciones de canje, validando disponibilidad de saldo, descontando inventario virtual del empleado y registrando la transacción para auditoría.
- Sincronización de Eventos: Publica eventos de negocio (Tickets) hacia el ecosistema (Pub/Sub) para notificar creaciones de trabajos/procesos.
Tipo de consumidores
- Frontends: Aplicaciones Web o Móviles (App de Empleados) que consumen la API REST.
- Sistemas Internos: Otros microservicios o sistemas legacy que requieran verificar disponibilidad de beneficios.
Rol en la arquitectura
Pertenece al Dominio de Empleados / Beneficios. Es un servicio "Core" de negocio que orquesta la lógica transaccional de los beneficios de productos, aislando la complejidad del cálculo de saldos y manteniendo la integridad de las transacciones de canje.
2. Contexto Arquitectónico
Descripción del Ecosistema
El servicio reside en un entorno de microservicios Spring Boot, desplegado probablemente en contenedores (referencia a Dockerfile). Interactúa con una infraestructura de nube (Pub/Sub y Artifact Registry).
Relaciones
- Bases de Datos:
- Primaria (PostgreSQL): Almacena la información transaccional de ingresos de empleados (
EmployeeRevenue), transacciones de redención (RedemptionTransaction) y catálogos (Category).
- Primaria (PostgreSQL): Almacena la información transaccional de ingresos de empleados (
- Brokers / Mensajería:
- Google Cloud Pub/Sub: Publica eventos en el topic
uat.sienpro.sync.ticketsconfigurado vía properties.
- Google Cloud Pub/Sub: Publica eventos en el topic
- Librerías Internas:
- Depende fuertemente de librerías
com.alpurapara modelos (model-ex,model-sienpro), utilidades (common-utilities) y auditoría (common-telemetry).
- Depende fuertemente de librerías
Responsabilidades (Bounded Context)
El contexto delimitado de este servicio es "Gestión de Saldo de Beneficios de Empleados".
- IN: Gestión del saldo, reglas de redención, histórico de transacciones.
- OUT: Gestión de usuarios (Identity), Catálogo maestro de productos (solo lectura), Nómina general.
3. Arquitectura de Alto Nivel (HLD)
Diagrama de Arquitectura
Componentes Principales
- Controller:
EmployeeController(API REST). - Facade:
EmployeeRevenueImpl(Orquestación simple y delegación). - Service:
EmployeeRevenueServiceImpl(Lógica de negocio core: validación de saldos, transaccionalidad, lógica JSON). - Persistence: Repositorios JPA (
IEmployeeRevenueRepository, etc.) interactuando con entidades externas. - Listener:
JobEventListenerpara manejo de eventos transaccionales (JobCreatedEventVO).
Patrones
- Layered Architecture: Controller -> Facade -> Service -> Repository.
- Transactional Script: Lógica de negocio procedural dentro del Servicio.
- DTO/VO Pattern: Uso extensivo de VOs (
RedeemRequestVO,BalanceResponseVO) para desacoplar la API del modelo de dominio. - JSON Column: Uso de columnas JSON en BD para almacenar estructuras dinámicas de saldo (Flexibilidad vs Normalización).
4. Contrato de API y Endpoints
1. Consultar Saldo de Empleado
- Método:
GET - Path:
/api/v1/employees/{payrollNumber}/balance - Descripción: Obtiene el saldo disponible de productos para un empleado.
Response (202 Accepted): SingleResponseVO<BalanceResponseVO>
{
"success": true,
"data": {
"payrollNumber": 12345,
"employeeName": "Juan Perez",
"products": [
{
"code": "PROD01",
"productName": "Leche Entera",
"quantity": 5
}
],
"photo": "/9j/4AAQSk..."
},
"errors": []
}
2. Redimir Productos
- Método:
POST - Path:
/api/v1/employees/{payrollNumber}/redeem - Descripción: Ejecuta el canje de productos. Valida saldo y descuenta inventario.
Request Body: RedeemRequestVO
{
"storeId": "99",
"productsToRedeem": {
"PROD01": 2,
"PROD02": 1
}
}
Response (202 Accepted): SingleResponseVO<RedeemResponseVO>
{
"success": true,
"data": {
"message": "Redención exitosa",
"payrollNumber": 12345,
"newBalance": {
"PROD01": 3,
"PROD02": 5
}
}
}
5. Flujos Funcionales
Flujo: Redención de Productos
Este es el flujo crítico del negocio que garantiza la consistencia del saldo.
6. Integraciones Técnicas
Bases de Datos
- Motor: PostgreSQL (según
PrimaryDataConfigy dialect). - ORM: Hibernate / Spring Data JPA.
- Configuración:
hbm2ddl.auto = none(Esquema debe existir previamente).- Datos almacenados en columnas tipo JSON (manipulados via Jackson
JsonNode).
Mensajería (Pub/Sub)
- Provider: Google Cloud Pub/Sub.
- Topic:
projects/alpura-hub-uat/topics/uat.sienpro.sync.tickets(Hardcoded enJobEventListener, aunque existe código comentado para leer de properties). - Evento:
JobCreatedEventVO-> Se publica tras el commit de una transacción (TransactionPhase.AFTER_COMMIT).
7. Seguridad
- Mecanismos:
- El código analizado no contiene configuración explícita de Spring Security (filtros, roles, JWT decoder).
- Sin embargo,
ExApplicationrealiza un@ComponentScan({"com.alpura.security.*"}). Esto indica que la seguridad es provista por una librería compartida (alpura-libu similar) que autoconfigura la seguridad. - Suposición: Se asume seguridad vía Token OAuth2/JWT estándar en la organización, inyectada por la librería común.
8. Observabilidad
- Telemetría:
- Uso de anotación propia
@IAuditableen métodos de negocio (EmployeeRevenueServiceImpl), lo que sugiere un aspecto (AOP) que intercepta y registra auditoría. - Dependencia
back-java-lib-common-telemetry.
- Uso de anotación propia
- Métricas:
- Dependencia
micrometer-registry-prometheuspresente enpom.xml, habilitando endpoint para scraping de Prometheus. - Actuator presente (
spring-boot-starter-actuator).
- Dependencia
9. Modelo de Datos (ERD)
Diccionario de Datos
| Entidad | Tabla (est.) | Columna | Tipo Java | Tipo SQL (est.) | Descripción |
|---|---|---|---|---|---|
| EmployeeRevenueDO | employee_revenue | payroll_number | Long | BIGINT | Llave primaria. Número de nómina. |
total | JsonNode | JSONB | Objeto JSON con saldo: {"PROD1": 10, "PROD2": 5} | ||
| RedemptionTransactionDO | redemption_transaction | id | Long | BIGINT | ID autogenerado. |
payroll_number | Long | BIGINT | Referencia al empleado. | ||
balance_before | JsonNode | JSONB | Snapshot saldo antes. | ||
balance_after | JsonNode | JSONB | Snapshot saldo después. | ||
redeemed_amount | JsonNode | JSONB | Cantidad redimida. |
10. Consideraciones No Funcionales
- Concurrencia: El método
redeemProductsrecupera el registro, valida en memoria y guarda. Riesgo: Si no existe un bloqueo pesimista en base de datos (@Lock(LockModeType.PESSIMISTIC_WRITE)) o optimista (@Version), existe riesgo de condición de carrera (lost update) si dos redenciones ocurren simultáneamente. El repositorio tiene imports deLockModeType, pero no se observó la anotación@Locken el métodofindByPayrollNumberusado en el service (solo estaba definido en la interfaz sin anotación visible en el snippet mostrado, aunque se vió el import). - Performance:
- El uso de columnas JSON evita joins complejos para obtener el saldo completo.
- Data Sources: Configuración de
PrimaryySecondarydata sources sugiere separación de carga o conexión a múltiples esquemas.
- Mantenibilidad:
- Alta dependencia de librerías internas (
com.alpura.*). Esto estandariza pero acopla el ciclo de vida del servicio a las librerías base.
- Alta dependencia de librerías internas (
11. Estructura del Proyecto
src/main/java/com/alpura/java/arch
├── ExApplication.java # Main Entry Point
├── common
│ ├── listener # Event Listeners (Pub/Sub)
│ └── vo # Value Objects (DTOs)
├── config
│ └── database # Configuración de Datasources (Primary/Secondary)
├── facade # Capa intermedia (Interface + Impl)
├── persistence # Repositorios JPA
├── service # Lógica de Negocio (Interface + Impl)
└── web # Controllers REST