Architecture Overview¶
Türkçe
Bu sayfa ICOSYS platformunun genel mimarisini, servis yapısını, katmanlarını ve portlarını açıklar. Yeni başlayanlar için büyük resmi anlamak açısından idealdir.
System Architecture¶
ICOSYS is a multi-service enterprise platform following a microservices-inspired architecture. Each business domain runs as an independent Spring Boot service with its own database schema, while a single React SPA serves as the unified frontend.
┌──────────────────────────────────┐
│ React SPA (Vite) │
│ http://localhost:5173 │
│ │
│ Zustand ─ React Router ─ Axios │
└──────────┬──────────┬─────────────┘
│ REST/JWT │
┌─────────────┼──────────┼──────────────┐
│ │ │ │
┌──────▼──────┐ ┌───▼────┐ ┌───▼────┐ ┌────▼────┐
│ ICGLB │ │ BPM │ │ DMS │ │ Future │
│ :8010 │ │ :8020 │ │ :8030 │ │ :80XX │
│ Core │ │ Partner│ │ Docs │ │ │
└──────┬──────┘ └───┬────┘ └───┬────┘ └────┬────┘
│ │ │ │
┌──────▼────────────▼──────────▼──────────────▼────┐
│ MySQL 8 │
│ icglb2 │ icbpm │ icdms │ ... │
└──────────────────────────────────────────────────┘
Services¶
Service Registry¶
| Service | Port | Context Path | Database | Description |
|---|---|---|---|---|
| ICGLB | 8010 | /icglb/services |
icglb2 |
Core platform — users, accounts, auth, countries, config |
| BPM | 8020 | /icbpm/services |
icbpm |
Business Partner Management — partners, branches, contracts, accruals |
| DMS | 8030 | /icdms/services |
icdms |
Document Management — file upload/download, metadata, sharing |
| React SPA | 5173 | / |
- | Frontend (dev server) |
Türkçe
Yeni modül eklerken port 80XX formatında sıradaki boş port seçilir.
Context path her zaman /ic{module}/services kalıbını takip eder.
Service Responsibilities¶
ICGLB (Core Platform)
- User authentication (login, JWT issuing)
- Account and user management
- CrProcess (tenant/process) management
- Country, city, and reference data
- System configuration
- Health monitoring
BPM (Business Partner Management)
- Business partner CRUD
- Branch management
- Contract lifecycle
- Accrual period management
- Partner-related workflows
DMS (Document Management)
- File upload with magic-byte validation
- Multi-provider storage (LOCAL, future: S3)
- Signed URL generation for secure downloads
- Share links with optional password protection
- PDF/DOCX/XLSX text extraction
- File metadata and tagging
Layered Architecture¶
Each service follows the same layered structure:
┌─────────────────────────────────────────────┐
│ Controller Layer (@RestController) │ ← HTTP request/response
├─────────────────────────────────────────────┤
│ Service Layer (@Service + @Transactional) │ ← Business logic
├─────────────────────────────────────────────┤
│ Repository Layer (JPA + Specification) │ ← Data access
├─────────────────────────────────────────────┤
│ Entity Layer (@Entity) │ ← Domain model
└─────────────────────────────────────────────┘
Controller Layer¶
@RestControllerwith@RequestMapping("/api/{entity}")- Constructor injection via
@RequiredArgsConstructor - Returns
ResponseEntity<T>for all endpoints - Standard CRUD: GET
/{id}, POST/, PUT/{id}, DELETE/{id}, POST/list, GET/stats
Service Layer¶
- Extends
AbstractCrudService<Entity, ID, EditDto, ListDto, FilterDto> - Inherits full CRUD:
findById,create,update,delete,findPaged,getStats - Lifecycle hooks:
validateForCreate,beforeCreate,afterCreate, etc. @Transactionalon public methods only
Repository Layer¶
- Extends
ICrudRepository<Entity, ID>(which extendsJpaRepository+JpaSpecificationExecutor) - Spring Data query derivation:
findByCrProcess_Id(),existsBy*() - Specifications for dynamic filtering
Entity Layer¶
- All entities extend
AbstractICEntity6(inherits audit fields, version, crProcess, xrefId) @TableGeneratorfor ID generation per module- One schema per module:
icglb2,icbpm,icdms
Cross-Cutting Concerns¶
Authentication Flow¶
Client ICGLB (:8010) BPM/DMS (:8020/8030)
│ │ │
├── POST /api/auth/login ──► │
│ ├── Validate credentials │
│ ◄── JWT token ──────────┤ │
│ │ │
├── GET /api/branch/1 ─────┼────── Authorization: Bearer JWT ──►
│ │ ├── Validate JWT
│ │ ├── Extract roles
│ ◄───────────────────────┼──── Response ──────────────┤
Türkçe
JWT token ICGLB servisi tarafından üretilir. Diğer servisler (BPM, DMS) aynı JWT secret ile token'ı doğrular — merkezi bir auth gateway yoktur, her servis kendi doğrulamasını yapar.
Security Layers¶
| Layer | Technology | Description |
|---|---|---|
| Rate Limiting | Bucket4j | Per-endpoint: 60 (public), 100 (API key), 200 (JWT) req/min |
| IP Filtering | Custom filter | Whitelist mode — only allowed IPs can access |
| Authentication | JWT (JJWT 0.12.5) | 8-hour token expiry |
| Authorization | Spring Security | Role-based (@Secured) + owner/admin bypass |
| CORS | Spring Security | Per-environment allowed origins |
| Input Validation | Jakarta Validation | @NotNull, @Size, @Pattern |
| File Validation | Magic bytes | DMS validates actual file content, not just extension |
Tenant Isolation¶
Every entity belongs to a CrProcess (tenant). This is enforced at multiple levels:
- Entity level:
AbstractICEntity6.crProcess— mandatory@ManyToOne - Specification level: First predicate is always
crProcess.id = ? - Service level:
beforeCreate()hook sets crProcess from DTO - Frontend level:
crProcessIdsent in every filter request
Türkçe
crProcessId filtrelenmeden yapılan sorgular tüm tenant verilerini döndürür!
Specification'da ilk predicate HER ZAMAN crProcess.id filtresi olmalıdır.
Error Handling¶
Exception thrown in Service
│
▼
GlobalExceptionHandler (@ControllerAdvice)
├── Generate unique refId (UUID)
├── Log to database (exception_log table)
├── Log to file (fallback if DB fails)
└── Return standardized error response:
{
"errorCode": "IC-BPM-2008",
"message": "Accrual period already exists",
"refId": "a1b2c3d4-...",
"httpStatus": 409
}
Error code format: IC-{MODULE}-{CATEGORY}{NUMBER}
| Category | Range | Description |
|---|---|---|
| Auth | 1xxx | Authentication/authorization failures |
| Validation | 2xxx | Input validation errors |
| API | 3xxx | API/network errors |
| Data | 4xxx | CRUD/data access errors |
| File | 5xxx | File/upload errors |
| Config | 6xxx | Configuration/system errors |
Logging¶
| Setting | Value |
|---|---|
| Framework | SLF4J + Logback |
| Pattern | %d{yyyy-MM-dd HH:mm:ss} %-5level [%logger{36}] [%thread] - %msg%n |
| File rotation | 10 MB per file, 7 days retention |
| Log directory | C:/server/ICOSYS/log/{module}/ |
Shared Libraries¶
These projects provide shared functionality used by all service modules:
| Project | Purpose |
|---|---|
ICOM-Api-4.0 |
Core interfaces (ICrudRepository, base entities) |
ICOM-Services-Api-1.0 |
CrudService interface, ServiceException |
ICOM-Micro-Services-Api-1.0 |
AbstractCrudService, GlobalExceptionHandler, ErrorCodes, JWT filters, rate limiting |
Icglb-Entities-1.0 |
Core JPA entities (CrProcess, AbstractICEntity4/5/6) |
Icglb-Entities-Dto-1.0 |
Core DTOs (ICEntity6Dto, ICEntity6FilterDto, PageRequest/Response) |
Environment Configuration¶
Each service has 4 properties files:
| File | Purpose |
|---|---|
application.properties |
Common settings (context-path, JPA, jackson, actuator) |
application-dev.properties |
Development (ports, DB, secrets with fallbacks, CORS: *) |
application-test.properties |
Test (restricted CORS, test overrides) |
application-prod.properties |
Production (restricted CORS, no secret fallbacks) |
Türkçe
Ortam değişkenleri ${ENV_VAR:fallback} kalıbıyla tanımlanır.
Production'da fallback değeri OLMAMALIDIR — tüm secret'lar environment variable olarak verilmelidir.