🍗 PCK ZRA Middleware Wiki

System Architecture

The middleware is a Spring Boot 3.5.4 application on Java 21, packaged as a WAR and running on embedded Tomcat. This page covers the runtime stack, the code layout and the request pipeline.

Runtime environment

ComponentVersionPurpose
Java21 (LTS)Runtime platform
Spring Boot3.5.4Application framework
Maven3.xBuild tool
MariaDB10.6+Relational database
Flyway(via Spring Boot)Schema migrations (auto-run on startup)

Key dependencies

DependencyPurpose
spring-boot-starter-web / -data-jpa / -validation / -security / -actuator / -thymeleafREST API, ORM, bean validation, auth, monitoring, portal templating
mariadb-java-client, flyway-core, flyway-mysql, HikariCPJDBC, migrations, connection pool (max 20, min idle 5)
Apache httpclient5Outbound HTTP to Chrilan and Oracle STS
jjwt-api/impl/jackson 0.12.6JWT parsing and validation
springdoc-openapi-starter-webmvc-ui 2.6.0Swagger UI and OpenAPI 3 spec

Server configuration

PropertyValue
server.port8181
server.servlet.context-path/pckzra
server.address0.0.0.0
server.forward-headers-strategynative (Nginx reverse proxy support)

Package structure

src/main/java/com/micros/taxintchrilan/
├── TaxintChrilanMiddlewareApplication.java   # Spring Boot entry point
├── config/
│   ├── SecurityConfig.java          # Dual filter chain (API stateless + Web session)
│   ├── AsyncConfig.java             # Thread pool for async operations
│   └── DataInitializer.java         # Seed data on startup
├── controller/
│   ├── TaxintController.java        # Core POS API (/api/taxint/*)
│   ├── StoreController.java         # Store CRUD API (/api/stores/*)
│   ├── ReportsController.java       # Reports API (/api/reports/*)
│   └── WebController.java           # Thymeleaf portal (/, /dashboard, /stores, /reports)
├── service/
│   ├── ConversionService.java       # Taxint ↔ Chrilan transformation
│   ├── ChrilanApiClient.java        # HTTP client for Chrilan Smart API
│   ├── OracleStsApiClient.java      # HTTP client for Oracle STS (menu + PKCE)
│   ├── LoggingService.java          # Database logging for all API calls
│   ├── StoreRegistrationService.java# Store business logic
│   ├── MenuSyncService.java         # Oracle → Chrilan menu sync
│   ├── MenuSyncScheduler.java       # 60-second scheduled sync
│   ├── AuthenticationService.java   # Portal login + OTP
│   └── WhapiService.java            # WhatsApp messaging
├── dto/
│   ├── taxint/                      # 15 DTOs (Taxint format)
│   ├── chrilan/                     # 6 DTOs (Chrilan format)
│   └── oracle/                      # 8 DTOs (Oracle STS format)
├── entity/                          # ApiTransaction, ConversionLog, FiscalInvoice,
│                                    #   StoreRegistration, User
├── repository/                      # Spring Data JPA repositories (5)
├── security/
│   ├── JwtAuthenticationFilter.java
│   ├── OracleIdmJwtValidator.java   # JWKS signature verification
│   └── RequestResponseLoggingFilter.java
└── exception/
    ├── GlobalExceptionHandler.java
    └── ChrilanApiException.java

Request pipeline

HTTP request
  → RequestResponseLoggingFilter   (transaction ID + raw logging, before security)
  → Security filter chain
       API chain:  JwtAuthenticationFilter (stateless, Bearer JWT)
       Web chain:  session auth (OTP-verified)
  → Controller (Taxint / Store / Reports / Web)
  → Service layer (business logic, conversion, external calls)
  → LoggingService (api_transactions, conversion_logs)
  → GlobalExceptionHandler (structured errors)

Concurrency

PropertyValue
Core pool size4
Max pool size20
Queue capacity200
Thread prefixTaxint-Chrilan-
Rejection policyCallerRunsPolicy

Architecture decisions

DecisionRationale
Per-store API keys, no defaultFiscal compliance requires store-level device registration
SellerName as primary identifierThe value the POS consistently sends
Fail fast, no fallbacksBetter to reject an invoice than submit wrong data to ZRA
Full request/response loggingAudit trail required for fiscal debugging
Infinite data retentionAll logs and fiscal invoices kept forever
Fiscal invoice persistenceCredit notes need original receipt lookups
PKCE for Oracle STSRequired by Oracle's OAuth2 implementation
OTP via WhatsAppMost accessible 2FA channel in Zambia
Embedded TomcatSimplifies deployment
Flyway + Hibernate validateFlyway owns structure; Hibernate validates entity alignment
priceSequence=1 pricingDine-in price is the fiscal reference

Code standards (contributors)