446 lines
19 KiB
Markdown
446 lines
19 KiB
Markdown
# 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](#project-overview)
|
|
- [Stack and Runtime Versions](#stack-and-runtime-versions)
|
|
- [High-Level Architecture](#high-level-architecture)
|
|
- [Repository and Package Layout](#repository-and-package-layout)
|
|
- [Getting Started](#getting-started)
|
|
- [Configuration](#configuration)
|
|
- [Security & AuthN/AuthZ](#security--authnauthz)
|
|
- [Multi-Tenancy](#multi-tenancy)
|
|
- [Workflow Engine](#workflow-engine)
|
|
- [Module System](#module-system)
|
|
- [API Documentation](#api-documentation)
|
|
- [Eventing and Messaging](#eventing-and-messaging)
|
|
- [Persistence Model](#persistence-model)
|
|
- [i18n and Error Handling](#i18n-and-error-handling)
|
|
- [Observability](#observability)
|
|
- [Sequence Diagrams](#sequence-diagrams)
|
|
- [Useful Commands](#useful-commands)
|
|
- [Contributing Notes](#contributing-notes)
|
|
|
|
## 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:
|
|
- [pom.xml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/pom.xml)
|
|
|
|
## 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:
|
|
|
|
- [application entrypoint](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/UtmsNgBeApplication.java)
|
|
- [security config](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/config/SecurityConfig.java)
|
|
- [openapi config](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/config/OpenApiConfig.java)
|
|
- [tenant context filter](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantFilter.java)
|
|
- [tenant hibernate filter](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantHibernateFilter.java)
|
|
- [tenant entity listener](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/domain/TenantEntityListener.java)
|
|
- [base entity and auditing](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/domain/BaseEntity.java)
|
|
- [audit trail](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/audit/domain/AuditTrail.java)
|
|
|
|
## 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:
|
|
|
|
- [api controllers](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/api)
|
|
- [auth module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth)
|
|
- [core module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core)
|
|
- [tenant module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant)
|
|
- [workflow module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow)
|
|
- [module system](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module)
|
|
- [messaging](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/messaging)
|
|
|
|
## 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:
|
|
|
|
```shell
|
|
docker compose up -d
|
|
```
|
|
|
|
2) Build the application image and run as in compose:
|
|
|
|
```shell
|
|
docker compose up --build -d
|
|
```
|
|
|
|
3) 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:
|
|
|
|
- [application.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application.yml)
|
|
- [application-dev.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application-dev.yml)
|
|
- [application-prd.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application-prd.yml)
|
|
- [application-local.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application-local.yml)
|
|
- [Docker compose](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/docker-compose.yml)
|
|
|
|
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
|
|
|
|
- login endpoint: `POST /api/auth/login`
|
|
- refresh endpoint: `POST /api/auth/refresh`
|
|
- logout endpoint: `POST /api/auth/logout`
|
|
- JWT utility: [JwtService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/security/JwtService.java)
|
|
- JWT principal adapter: [UserPrincipal](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/security/UserPrincipal.java)
|
|
- token filter: [JwtAuthenticationFilter](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/security/JwtAuthenticationFilter.java)
|
|
- auth service: [AuthService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/service/AuthService.java)
|
|
- rate limit lockout service: [LoginThrottleService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/service/LoginThrottleService.java)
|
|
- token blacklist: [TokenBlacklistService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/service/TokenBlacklistService.java)
|
|
- refresh token entity: [RefreshToken](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/domain/RefreshToken.java)
|
|
|
|
### 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.
|
|
|
|
- `app.ldap.enabled=true` to switch it on.
|
|
- LDAP-specific properties are in [application.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application.yml).
|
|
- Provider wiring is in [LdapAuthConfig](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/config/LdapAuthConfig.java).
|
|
|
|
## Multi-Tenancy
|
|
|
|
Tenant is always provided by:
|
|
|
|
- `X-Tenant-Id` header via [TenantFilter](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantFilter.java)
|
|
- JWT claim `tenant` via [JwtService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/security/JwtService.java)
|
|
|
|
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](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantHibernateFilter.java) enables filter per request.
|
|
- `BaseEntity` holds `tenant_id` for all shared tables.
|
|
- `TenantService` validates active tenant with cache.
|
|
|
|
Tenant validation for active tenants:
|
|
- [TenantService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantService.java)
|
|
- [TenantRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/TenantRepository.java)
|
|
|
|
## Workflow Engine
|
|
|
|
Workflow is required for user/role management operations and available as a first-class service.
|
|
|
|
- workflow service: [ApprovalWorkflowService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/service/ApprovalWorkflowService.java)
|
|
- approval controller: [ApprovalWorkflowController](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/controller/ApprovalWorkflowController.java)
|
|
- workflow entities:
|
|
- [ApprovalRequest](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalRequest.java)
|
|
- [ApprovalStep](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalStep.java)
|
|
- [ApprovalHistory](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalHistory.java)
|
|
- approval DTOs: [CreateApprovalRequest](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/dto/CreateApprovalRequest.java), [ApprovalActionRequest](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/dto/ApprovalActionRequest.java), [ApprovalResponse](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/dto/ApprovalResponse.java)
|
|
|
|
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 domain: [SystemModule](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/domain/SystemModule.java)
|
|
- module registry service: [ModuleRegistryService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/service/ModuleRegistryService.java)
|
|
- module contract: [Module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/service/Module.java)
|
|
- sample module: [NotificationModule](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/service/NotificationModule.java)
|
|
|
|
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](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/config/OpenApiConfig.java)
|
|
|
|
### 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:
|
|
|
|
```json
|
|
{
|
|
"username": "maker",
|
|
"password": "Passw0rd!"
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"resourceType": "USER_MANAGEMENT",
|
|
"resourceId": "sample-user",
|
|
"payload": "{\"operation\":\"CREATE_USER\",\"username\":\"alice\"}",
|
|
"requiredSteps": 1
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
- producer: [ApprovalEventProducer](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/messaging/ApprovalEventProducer.java)
|
|
- consumer: [ApprovalEventConsumer](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/messaging/ApprovalEventConsumer.java)
|
|
- event payload: [ApprovalCompletedEvent](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/messaging/ApprovalCompletedEvent.java)
|
|
- queue name: `approval.completed.queue`
|
|
|
|
Post-approval process:
|
|
- event published when an approval request reaches `APPROVED`.
|
|
- consumer invokes [UserRoleManagementService.applyApprovedRequest](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/service/UserRoleManagementService.java).
|
|
|
|
## 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:
|
|
- [schema.sql](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/db/schema.sql)
|
|
|
|
Core entities:
|
|
|
|
- Tenant: [Tenant](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/tenant/Tenant.java)
|
|
- RBAC:
|
|
- User: [User](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/domain/User.java)
|
|
- Role: [Role](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/domain/Role.java)
|
|
- Permission: [Permission](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/domain/Permission.java)
|
|
- Refresh token: [RefreshToken](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/domain/RefreshToken.java)
|
|
- Workflow:
|
|
- ApprovalRequest: [ApprovalRequest](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalRequest.java)
|
|
- ApprovalStep: [ApprovalStep](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalStep.java)
|
|
- ApprovalHistory: [ApprovalHistory](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/domain/ApprovalHistory.java)
|
|
- Module: [SystemModule](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/domain/SystemModule.java)
|
|
- Audit: [AuditTrail](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/audit/domain/AuditTrail.java)
|
|
|
|
### Repositories
|
|
|
|
- [PermissionRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/repository/PermissionRepository.java)
|
|
- [RoleRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/repository/RoleRepository.java)
|
|
- [UserRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/repository/UserRepository.java)
|
|
- [RefreshTokenRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/auth/repository/RefreshTokenRepository.java)
|
|
- [AuditTrailRepository](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/audit/repository/AuditTrailRepository.java)
|
|
- [Workflow repositories](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/workflow/repository)
|
|
|
|
## i18n and Error Handling
|
|
|
|
Message bundles:
|
|
- default (en_US): [messages.properties](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/i18n/messages.properties)
|
|
- indonesia locale (id_ID): [messages_id.properties](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/i18n/messages_id.properties)
|
|
|
|
Message resolution helper:
|
|
- [MessageResolver](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/i18n/MessageResolver.java)
|
|
|
|
Global errors:
|
|
- [GlobalExceptionHandler](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/exception/GlobalExceptionHandler.java)
|
|
- app exception model:
|
|
- [AppException](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/exception/AppException.java)
|
|
|
|
## Observability
|
|
|
|
- Actuator:
|
|
- health/info endpoints via config in [application.yml](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/resources/application.yml)
|
|
- Audit logger:
|
|
- [AuditLoggingAspect](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/config/AuditLoggingAspect.java)
|
|
- persistent audit trail records:
|
|
- [AuditTrailService](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/audit/service/AuditTrailService.java)
|
|
- [Audit API](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/api/AuditController.java)
|
|
|
|
## Sequence Diagrams
|
|
|
|
Full controller interaction diagrams are available in:
|
|
|
|
- [docs/sequence-diagrams.md](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/docs/sequence-diagrams.md)
|
|
|
|
## Useful Commands
|
|
|
|
Build only:
|
|
|
|
```shell
|
|
mvn -q -DskipTests compile
|
|
```
|
|
|
|
Run tests:
|
|
|
|
```shell
|
|
mvn test
|
|
```
|
|
|
|
Run locally (default profile):
|
|
|
|
```shell
|
|
$env:SPRING_PROFILES_ACTIVE="local"; mvn spring-boot:run
|
|
```
|
|
|
|
Run dev profile:
|
|
|
|
```shell
|
|
$env:SPRING_PROFILES_ACTIVE="dev"; mvn spring-boot:run
|
|
```
|
|
|
|
Run prd profile:
|
|
|
|
```shell
|
|
$env:SPRING_PROFILES_ACTIVE="prd"; mvn spring-boot:run
|
|
```
|
|
|
|
## Contributing Notes
|
|
|
|
Data seeding:
|
|
- enabled in `dev` and `local` via profile/setting.
|
|
- seed source: [DataSeeder](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/core/config/DataSeeder.java).
|
|
- to add bootstrap users/roles/permissions, modify this component intentionally.
|
|
|
|
Extending modules:
|
|
- implement [Module](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/src/main/java/id/iptek/utms/module/service/Module.java)
|
|
- 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](/D:/Projects/Personal/IPTEK/utms-ng/utms-ng-be/docs/sequence-diagrams.md).
|