initial commit
This commit is contained in:
445
README.md
Normal file
445
README.md
Normal file
@ -0,0 +1,445 @@
|
||||
# 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).
|
||||
Reference in New Issue
Block a user