2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00
2026-04-21 06:25:33 +07:00

UTMS NG Backend (Spring Boot)

Production-ready Spring Boot 3.x backend for user tenancy, RBAC, maker-checker workflow, module management, Redis caching/session support, ActiveMQ eventing, and i18n.

Table of Contents

Project Overview

The system is organized into modular packages and service layers:

  • api: REST-facing controllers.
  • auth: authentication, authorization, JWT, LDAP integration, token handling, and user-role primitives.
  • core: cross-cutting concerns (errors, base entities, audit, caching, i18n, DB config).
  • tenant: tenant context and tenant isolation filters.
  • workflow: maker-checker workflow engine.
  • module: pluggable feature module registry.
  • messaging: ActiveMQ producer/consumer for async post-approval actions.

Stack and Runtime Versions

The project runs on Java 17 and uses Spring Boot starter dependencies.

  • Java 17+
  • Spring Boot 3.3.5
  • Spring Security
  • Spring Data JPA + Hibernate
  • PostgreSQL
  • Redis
  • ActiveMQ
  • Maven
  • SpringDoc OpenAPI

Main build and dependency file:

High-Level Architecture

The application follows request/response flow with cross-cutting servlet filters:

  1. TenantFilter resolves tenant ID from X-Tenant-Id.
  2. JwtAuthenticationFilter authenticates bearer tokens when present.
  3. Method-level security checks RBAC/permission requirements.
  4. Business services apply transaction boundaries and audit/logging.
  5. Workflow events are published to ActiveMQ on approval completion.

Core architectural file references:

Repository and Package Layout

Top-level structure:

  • src/main/java/id/iptek/utms
  • src/main/resources
  • docs (documentation)
  • docker-compose.yml
  • pom.xml

Important package-level references:

Getting Started

Prerequisites

  • JDK 17
  • PostgreSQL 16
  • Redis 7+
  • ActiveMQ 5.18+
  • Maven
  • PowerShell (for local commands in this environment)

Local run with Docker

  1. Start infrastructure:
docker compose up -d
  1. Build the application image and run as in compose:
docker compose up --build -d
  1. Access services:
  • Backend: http://localhost:9191
  • Swagger UI: http://localhost:9191/swagger-ui.html
  • API docs: http://localhost:9191/v3/api-docs
  • Postgres: localhost:5432
  • Redis: localhost:6379
  • ActiveMQ admin: http://localhost:8161

Configuration

Profiles are defined in:

Common config sections:

  • datasource: PostgreSQL connection
  • data.redis: Redis host/port and cache config
  • activemq: broker and credentials
  • app.ldap: optional LDAP integration (disabled by default)
  • app.security.login.*: login brute-force thresholds
  • app.seed.enabled: bootstrap sample data flag

Brute-force defaults for login:

  • max failed attempts: app.security.login.max-failed-attempts
  • attempt window (seconds): app.security.login.failed-attempt-window-seconds
  • lockout window (seconds): app.security.login.lockout-duration-seconds

Single-session login option:

  • app.security.single-login.enabled (default false)
    • true = user can only have one active session at a time; new login invalidates previous access/refresh session.

Security & AuthN/AuthZ

Login and JWT

RBAC model

  • Roles are prefixed with ROLE_ in authorities via UserPrincipal.
  • Permissions are loaded from Role -> Permission and exposed as authorities directly.
  • Default protected role/permission checks use @PreAuthorize.
  • Common checks:
  • hasRole('ADMIN')
  • hasAuthority('WORKFLOW_APPROVE')
  • hasAuthority('USER_MANAGE')
  • hasAuthority('ROLE_MANAGE')

Optional LDAP

LDAP can be enabled without code changes using profile configuration.

Multi-Tenancy

Tenant is always provided by:

Tenant context is thread-bound:

  • set by TenantContext and used by services and entities.

Tenant isolation strategy:

  • Hibernate tenantFilter is defined on tenant-scoped entities.
  • TenantHibernateFilter enables filter per request.
  • BaseEntity holds tenant_id for all shared tables.
  • TenantService validates active tenant with cache.

Tenant validation for active tenants:

Workflow Engine

Workflow is required for user/role management operations and available as a first-class service.

Workflow state progression:

  • Maker creates request with required steps.
  • Checker role per step enforces which role can approve.
  • Each step is persisted as PENDING.
  • Approve action updates step and request progress.
  • Reject action sets request to REJECTED.
  • Final approval publishes ApprovalCompletedEvent to ActiveMQ and user-role changes are applied by consumer.

Module System

Module operations:

  • list: GET /api/modules
  • toggle by code: POST /api/modules/{code}/toggle

API Documentation

Swagger/OpenAPI:

  • UI: http://localhost:9191/swagger-ui.html
  • JSON spec: http://localhost:9191/v3/api-docs
  • openapi settings: OpenApiConfig

Endpoints

Auth endpoints:

  • POST /api/auth/login
  • POST /api/auth/refresh
  • POST /api/auth/logout

Tenant endpoint:

  • GET /api/tenant/context

User endpoint:

  • GET /api/users/me
  • POST /api/users/management/requests/create
  • POST /api/users/management/requests/update-roles

Role endpoints:

  • POST /api/roles/management/requests/create
  • POST /api/roles/management/requests/update-permissions

Workflow endpoints:

  • POST /api/workflow/request
  • POST /api/workflow/{id}/approve
  • POST /api/workflow/{id}/reject

Module endpoints:

  • GET /api/modules
  • POST /api/modules/{code}/toggle

Audit endpoints:

  • GET /api/audit?limit=50

Health endpoint:

  • GET /actuator/health

Swagger-safe quick sample JSON:

{
  "username": "maker",
  "password": "Passw0rd!"
}
{
  "resourceType": "USER_MANAGEMENT",
  "resourceId": "sample-user",
  "payload": "{\"operation\":\"CREATE_USER\",\"username\":\"alice\"}",
  "requiredSteps": 1
}
{
  "username": "admin",
  "roleCodes": ["ADMIN"]
}

Mandatory headers

  • Tenant:
  • X-Tenant-Id: acme
  • Locale:
  • Accept-Language: en-US or id-ID
  • Authorization:
  • Authorization: Bearer <jwt>

Eventing and Messaging

ActiveMQ integration:

Post-approval process:

Persistence Model

Naming and schema strategy

  • security tables use sec_ prefix.
  • workflow/system/audit tables use sys_ prefix.
  • This is maintained in all entities and confirmed in the schema file.

Database schema reference:

Core entities:

Repositories

i18n and Error Handling

Message bundles:

Message resolution helper:

Global errors:

Observability

Sequence Diagrams

Full controller interaction diagrams are available in:

Useful Commands

Build only:

mvn -q -DskipTests compile

Run tests:

mvn test

Run locally (default profile):

$env:SPRING_PROFILES_ACTIVE="local"; mvn spring-boot:run

Run dev profile:

$env:SPRING_PROFILES_ACTIVE="dev"; mvn spring-boot:run

Run prd profile:

$env:SPRING_PROFILES_ACTIVE="prd"; mvn spring-boot:run

Contributing Notes

Data seeding:

  • enabled in dev and local via profile/setting.
  • seed source: DataSeeder.
  • to add bootstrap users/roles/permissions, modify this component intentionally.

Extending modules:

  • implement Module
  • register as Spring component
  • expose behavior in toggle handlers.

Extending API:

  • add DTOs under auth|workflow|module|api
  • add service under domain package
  • create controller endpoint and secure with @PreAuthorize
  • update docs in this file and docs/sequence-diagrams.md.
Description
UTMS New Gen Backend Code Repositories
Readme 370 KiB
Languages
Java 100%