Saltar a contenido

Backend AutoCompraMod

Referencia técnica del backend: stack, layout, build, datos y seguridad. Para el porqué del diseño, mirá El monolito modular; acá están los datos exactos.

Stack

Pieza Versión / valor
Lenguaje Java 21 (enforcer fuerza [21,22))
Framework Spring Boot 3.4.0
Modularidad Spring Modulith 1.3.0
Persistencia Spring Data JPA / Hibernate, SQL Server (mssql-jdbc)
Auditoría Hibernate Envers (entidad Vale)
Cache Caffeine (catálogo ~100k)
Async externo Spring WebFlux WebClient + Reactor Netty (gateways de pago)
Seguridad OAuth2 Resource Server (JWT / Keycloak)
QR ZXing
Voucher / impresión escpos-coffee (ESC/POS) + OpenPDF (reemplazó iText 5 AGPL)
Frontend Cockpit React 18 + Vite + TypeScript (build vía frontend-maven-plugin)
Context-path /autocompras/v1

Layout de paquetes

com.tipre.autocompras
├── tickets/        orquestador (API del POS)
├── catalogo/       artículos por EAN/sucursal
├── pagos/          intent/pay/check/cancel (stateless)
├── promos/         cálculo de promociones
├── envases/        vales y depósitos retornables
├── shared/         kernel OPEN (ResponseMessage, enums, NucleoImpositivoDto)
├── security/       SecurityConfig + JwtAuthConverter (app-wide)
└── monitoring/     Cockpit (observabilidad)

Cada módulo se declara con un package-info.java anotado @ApplicationModule (shared es type = OPEN). El detalle de roles y reglas está en Los módulos.

Datos: schema-por-módulo

No hay una base única: cada módulo con persistencia define su propio DataSource (hbm2ddl.auto=none — el schema no lo maneja la app). Cero foreign keys cruzadas entre módulos.

Módulo Config Base Notas
tickets TicketsDataSourceConfig (@Primary) TsAutoCompra (SQL Server) Entidades Trx, PaymentAttempt, PosConfig, DeviceConfig.
catalogo CatalogoDataSourceConfig TipreRetail Read-only, cache Caffeine ~100k.
promos PromosDataSourceConfig TsPromos Promos + auditoría de cálculos.
envases EnvasesDataSourceConfig TsEnvases Vale (@Audited, Envers → tablas _AUD), Envase.
pagos Stateless: no persiste, usa WebClient a gateways.
monitoring MonitoringDataSourceConfig DB de observabilidad separada ErrorEvent, retención 30 días.

Entidades principales

  • Trx (tickets) — el ticket persistido. Estados: OPEN, PAGADO, VOUCHERPENDING, CLOSE, CANCELED_USER, CANCELED_INACTIVITY, ERROR.
  • Articulo (catalogo) — @Table(name = "dm_Artic"). Campos: cEan, cDescripcion, fPrecio, iTax, bPeso, bEnvase, iNroSuc, etc.
  • Vale (envases) — @Entity @Audited. Campos: nroVale, codVale, nroSucursal, fechaCreacion, fechaVto, terminalOrigen, estado. Genera Vales_AUD.
  • Envase (envases) — ean, plu, descripcion, nroSucursal, imagen (@Lob), habilitado, orden.

Seguridad

App-wide: un único SecurityFilterChain y JwtAuthConverter en el paquete security (SecurityConfig.java).

Propiedad Default Efecto
app.security.enabled false falseanyRequest().permitAll(). true → política de roles (resource server JWT/Keycloak).
app.security.admin-role ADMIN Rol exigido en mutaciones admin (espera authority ROLE_<admin-role>).

Con seguridad activa:

  • permitAll: /actuator/health, /actuator/info, /*/dummy, swagger.
  • hasRole(adminRole): POST /promociones/update, POST /cache/refresh, POST /catalogo/cache/refresh.
  • authenticated(): el resto (incluido el runtime del POS, para no romper el checkout).

Toggle en false = todo abierto

Con app.security.enabled=false todos los endpoints quedan permitAll, incluidas las mutaciones admin. Es sólo para dev / parallel-run; se loguea un WARN al armar el filter chain. En producción con Keycloak: enabled=true y admin-role al rol real del realm.

Build y guardrail

# Build + verificación de boundaries de módulos. Requiere JDK 21.
mvn test

# Levantar (con los DataSource configurados)
mvn spring-boot:run
  • ModularityTests corre ApplicationModules.of(...).verify() y rompe el build si se viola una frontera o aparece un ciclo. Ver El monolito modular.
  • CI: GitHub Actions corre mvn test con JDK 21 en cada push/PR (~411 tests; 22 deshabilitados por requerir infra de DB).
  • Cockpit: el profile frontend de Maven instala Node local (frontend-maven-plugin), corre npm ci && npm run build y copia dist/ a src/main/resources/static/cockpit, servido por Spring como SPA.

Por dónde seguir

  • Los módulos — qué hace cada uno y su API pública.
  • API REST — endpoints concretos.
  • Cockpit — el panel de operación y /monitoring/*.