En esta guía (8 elementos)
Architecture Overview
Architecture Overview
Project-agnostic catalog. Part of the Diagram Catalog. Covers: high-level architectural pattern, hexagonal implementation, module structure.
Replace
com.example.platform/platform-serviceplaceholders with your project’s actual package and service name when applying patterns.
1. Architecture Overview
1.1 Main Architectural Pattern
The project implements Hexagonal Architecture (Ports & Adapters) combined with Clean Architecture, structured in clearly defined layers:
┌─────────────────────────────────────────────────────────────┐│ Entry Points (Inbound Adapters — Infrastructure) ││ REST, GraphQL, Schedulers, Webhooks, Kafka Consumers │└──────────────────┬──────────────────────────────────────────┘ │ (Inbound Ports)┌─────────────────▼────────────────────────────────────────┐│ Application Layer ││ • Use Cases (Business Logic) ││ • Inbound Ports (Command/Query Interfaces) ││ • Outbound Ports (Repository/Publisher Interfaces) ││ • Commands (Input DTOs) │└──────────────┬─────────────────┬──────────────────────────┘ │ │ (Outbound Ports)┌──────────────▼─┐ ┌────────────▼────────────────────┐│ Domain Layer │ │ Driven Adapters ││ • Entities │ │ • JDBC Repositories ││ • Value Objs │ │ • Kafka Publishers ││ • Exceptions │ │ • Redis Cache ││ • Utils │ │ • Metrics Publishers │└────────────────┘ └─────────────────────────────────┘1.2 Core Principles
- Dependency Inversion: All dependencies point inward (toward Domain)
- Port-Based Design: All external communication through ports
- Framework Independence: Domain and Application layers are pure Kotlin
- Testability: Ports enable easy mocking and unit testing
- Single Responsibility: Each layer has a clear, distinct purpose
2. Hexagonal Architecture Implementation
2.1 Layers Description
Domain Layer (Core/Center)
- Location:
domain/ - Purpose: Contains business entities and domain logic
- Dependencies: None (completely independent)
- Contains:
Organization,User(Entities)OrganizationStatus,Roles(Enums)OrganizationNotFoundException(Domain Exceptions)MdcUtil,TraceContextUtil(Domain Utilities)
Application Layer (Use Cases)
- Location:
application/ - Purpose: Orchestrates business workflows
- Dependencies: Domain only
- Contains:
- Inbound Ports: Define how external world invokes the app
- Outbound Ports: Define how app communicates with infrastructure
- Use Cases: Implement business logic using domain entities
- Commands: Input DTOs for use cases
Infrastructure Layer (Adapters)
- Location:
infrastructure/ - Purpose: Implements technical details
- Dependencies: Application, Domain, External libraries
- Contains:
- Entry Points:
rest-controller: REST API endpoints.graphql-controllers: GraphQL schema and resolvers.webhooks-controller: External webhook handlers.scheduler-task: Periodic background tasks.kafka-consumer: Message queue consumers.
- Driven Adapters: JDBC, Kafka, Redis, Metrics
- Entry Points:
Bootstrap Layer (Configuration)
- Location:
bootstrap/ - Purpose: Dependency injection and app configuration
- Dependencies: All other layers
- Contains:
- Spring Boot configuration
- Bean definitions
- Application properties
2.2 Complete Layer Diagram
┌─────────────────────────────────────────────────────────────────┐│ BOOTSTRAP LAYER ││ • Spring Boot Configuration (UseCaseConfig, ScheduleConfig) ││ • Dependency Injection (Connects Ports ↔ Adapters) ││ • Application Properties (application.yml) │└────────────────────────┬────────────────────────────────────────┘ │ wires dependencies ┌────────────────┴────────────────┐ │ │┌───────▼────────────────────┐ ┌────────▼──────────────────────┐│ ENTRY POINTS │ │ DRIVEN ADAPTERS ││ (Infrastructure) │ │ (Infrastructure) ││ │ │ ││ • REST Controllers │ │ • JDBC Repositories ││ - OrganizationController │ │ - OrganizationRepoAdapter ││ │ │ - UserRepositoryAdapter ││ • Schedulers │ │ - OutboxRepositoryAdapter ││ - OutboxTaskScheduler │ │ - JdbcTransaction<R> ││ │ │ ││ • Filters │ │ • Kafka Publishers ││ - TraceIdFilter │ │ - OrganizationKafkaAdapter ││ │ │ - UserKafkaAdapter │└────────────┬───────────────┘ │ - OutboxKafkaAdapter │ │ implements │ │ │ inbound ports │ • Redis Cache │ │ │ - OrganizationCacheAdapter │┌────────────▼────────────────────▼───────────────────────────────┐│ APPLICATION LAYER ││ ││ ┌──────────────────────────────────────────────────────────┐ ││ │ INBOUND PORTS │ ││ │ • CreateOrganizationPort │ ││ │ • GetOrganizationByIdPort │ ││ │ • ChangeOrganizationStatusPort │ ││ │ • SendOutboxMessagesPort (SDK) │ ││ └────────────┬─────────────────────────────────────────────┘ ││ │ implemented by ││ ┌────────────▼─────────────────────────────────────────────┐ ││ │ USE CASES │ ││ │ • CreateOrganizationUseCase │ ││ │ • GetOrganizationByIdUseCase │ ││ │ • ChangeOrganizationStatusUseCase │ ││ │ • SendOutboxMessagesUseCase (SDK) │ ││ └────────────┬─────────────────────────────────────────────┘ ││ │ depends on ││ ┌────────────▼─────────────────────────────────────────────┐ ││ │ OUTBOUND PORTS │ ││ │ Repositories: │ ││ │ • OrganizationRepositoryPort │ ││ │ • UserRepositoryPort │ ││ │ • OutboxRepositoryPort (SDK) │ ││ │ │ ││ │ Messaging: │ ││ │ • MessagePublisherPort (SDK — consumed ONLY by the │ ││ │ SDK dispatcher, NEVER by application use cases) │ ││ │ │ ││ │ Domain factories (no annotations): │ ││ │ • EventMessageFactory (SDK) │ ││ │ • OutboxEventFactory (SDK) │ ││ │ │ ││ │ Support: │ ││ │ • TransactionPort<R> │ ││ │ • ChainablePort<T> │ ││ └──────────────────────────────────────────────────────────┘ ││ ││ ┌──────────────────────────────────────────────────────────┐ ││ │ COMMANDS │ ││ │ • CreateOrganizationCommand │ ││ │ • CommandMappers (to Domain) │ ││ └──────────────────────────────────────────────────────────┘ │└────────────────────────┬─────────────────────────────────────┘ │ uses┌────────────────────────▼─────────────────────────────────────┐│ DOMAIN LAYER ││ ││ • Entities: Organization, User ││ • Value Objects: (future implementation) ││ • Enums: OrganizationStatus, Roles ││ • Exceptions: OrganizationNotFoundException ││ • Utils: MdcUtil, TraceContextUtil ││ ││ ⚠️ NO DEPENDENCIES - Pure Kotlin │└───────────────────────────────────────────────────────────────┘3. Module Structure
3.1 Directory Tree
platform-service/│├── domain/ # Core business logic│ └── src/main/kotlin/.../domain/│ ├── Organization.kt│ ├── User.kt│ ├── enums/│ │ ├── OrganizationStatus.kt│ │ └── Roles.kt│ ├── exception/│ │ └── OrganizationNotFoundException.kt│ ├── support/│ │ └── OutboxMessage.kt│ └── util/│ ├── MdcUtil.kt│ └── TraceContextUtil.kt│├── application/ # Use cases and ports│ └── src/main/kotlin/.../│ ├── port/│ │ ├── inbound/ # Entry contracts (service-owned)│ │ │ ├── CreateOrganizationPort.kt│ │ │ ├── GetOrganizationByIdPort.kt│ │ │ └── ChangeOrganizationStatusPort.kt│ │ │ # SendOutboxMessagesPort lives in codehuntersio-sdk-event-messaging│ │ ││ │ └── outbound/ # Exit contracts (service-owned)│ │ └── repository/│ │ ├── OrganizationRepositoryPort.kt│ │ ├── UserRepositoryPort.kt│ │ └── support/│ │ ├── TransactionPort.kt│ │ ├── TransactionCallbackPort.kt│ │ └── ChainablePort.kt│ │ # NO publisher/ folder.│ │ # OutboxRepositoryPort + MessagePublisherPort + OutboxEventFactory│ │ # come from codehuntersio-sdk-event-messaging — inject directly in use cases.│ ││ └── usecase/ # Business logic│ └── organization/│ ├── CreateOrganizationUseCase.kt│ ├── GetOrganizationByIdUseCase.kt│ ├── ChangeOrganizationStatusUseCase.kt│ └── command/│ ├── CreateOrganizationCommand.kt│ └── mapper/│ └── CommandMapper.kt│├── infrastructure/ # Technical implementations│ ├── entry-points/ # Inbound adapters│ │ ├── rest-controller/│ │ │ └── .../controller/organization/│ │ │ ├── OrganizationController.kt│ │ │ └── model/│ │ │ ├── request/│ │ │ │ └── CreateOrganizationRequest.kt│ │ │ └── response/│ │ │ ├── CreatedOrganizationResponse.kt│ │ │ └── OrganizationResponse.kt│ │ ││ │ └── scheduler-task/│ │ └── OutboxTaskScheduler.kt│ ││ └── driven-adapters/ # Outbound adapters│ ├── jdbc-repository/│ │ └── OrganizationRepositoryAdapter.kt│ ├── kafka-producer/│ │ └── OrganizationKafkaPublisherAdapter.kt│ ├── redis-cache/│ │ └── OrganizationCacheAdapter.kt│ └── metrics-publisher/│ └── OrganizationMetricsAdapter.kt│└── bootstrap/ # Configuration └── src/main/kotlin/.../config/ ├── UseCaseConfig.kt ├── ScheduleConfig.kt └── resources/ └── application.yml