forge-kit

ADR-0012: Clean Architecture Package Structure Standards

Date: 2025-12-10
Status: Accepted
Context: Standardization of Java package structure across all modules using Clean Architecture principles


Context

The codebase had inconsistent package structures across modules:

This inconsistency made the codebase harder to navigate, understand, and maintain. New developers had to learn different patterns for each module.


Decision

We will adopt Clean Architecture package structure standards across all modules. All API and implementation modules must follow these standards.

Core Principles

  1. Separation of Concerns: Clear boundaries between domain, infrastructure, and presentation layers
  2. Consistent Structure: Same package structure across all modules of the same type
  3. Naming Conventions: Consistent naming patterns for interfaces, implementations, and utilities
  4. API/Implementation Separation: Clear separation between API contracts (forge-api) and implementations (forge-impl)

Repository Structure

Forge Kit is organized as a library/framework repository with two main module categories:


Package Structure Standards

Base Package Pattern

All modules follow the pattern: io.forge.kit.{module}.{api|impl}.{layer}


API Modules (forge-api/{module}-api)

API modules define contracts, interfaces, annotations, and shared DTOs:

io.forge.kit.{module}.api/
├── domain/                               # Domain interfaces and contracts
│   ├── exception/                        # Domain exceptions
│   ├── support/                          # Support interfaces/utilities
│   └── [Domain interfaces]
├── dto/                                  # Data transfer objects
│   └── [DTOs]
├── infrastructure/                       # Infrastructure contracts
│   └── [Infrastructure interfaces]
├── rest/                                 # REST layer annotations
│   ├── exception/                        # Exception-related annotations
│   └── [REST annotations]
├── jwt/                                  # JWT-related contracts (if applicable)
│   └── [JWT interfaces]
├── key/                                  # Key resolution contracts (if applicable)
│   └── resolver/
│       └── [Key resolver interfaces]
├── faulttolerance/                       # Circuit breaker contracts (if applicable)
│   └── [Fault tolerance interfaces]
└── persistence/                          # Persistence contracts (if applicable)
    └── [Persistence interfaces]

Implementation Modules (forge-impl/{module})

Implementation modules provide concrete implementations of API contracts:

io.forge.kit.{module}.impl/
├── domain/                               # Domain implementations
│   ├── exception/                        # Exception mappers/handlers
│   ├── recorder/                         # Metrics recorders (if applicable)
│   ├── support/                          # Support implementations
│   └── [Domain implementations]
├── dto/                                  # Implementation-specific DTOs (if any)
│   └── [DTOs]
├── infrastructure/                       # Infrastructure implementations
│   ├── config/                           # Configuration producers
│   ├── [Infrastructure implementations]
│   └── [Sub-packages for specific concerns]
├── rest/                                 # REST layer implementations
│   ├── exception/                        # Exception mappers
│   └── [REST implementations]
├── jwt/                                  # JWT implementations (if applicable)
│   └── [JWT implementations]
├── key/                                  # Key resolution implementations (if applicable)
│   └── resolver/
│       └── [Key resolver implementations]
├── strategy/                             # Strategy implementations (if applicable)
│   └── [Strategy implementations]
├── faulttolerance/                       # Circuit breaker implementations (if applicable)
│   ├── recorder/
│   └── [Fault tolerance implementations]
├── persistence/                          # Persistence implementations (if applicable)
│   ├── recorder/
│   └── [Persistence implementations]
├── logging/                              # Logging implementations (if applicable)
│   └── [Logging implementations]
├── lang/                                 # Language utilities (if applicable)
│   └── [Language utilities]
├── inject/                               # CDI utilities (if applicable)
│   └── [CDI implementations]
├── reference/                            # Reference implementations/examples
│   └── [Reference code]
└── test/                                 # Test profiles and test utilities
    └── [Test profiles]

Naming Conventions

Interfaces (API Modules)

Implementations (Implementation Modules)

Annotations (API Modules)

DTOs


Layer Guidelines

Domain Layer

Infrastructure Layer

REST/Presentation Layer

DTO Layer


Module-Specific Patterns

Security Module

Metrics Module

Throttle Module

Common Module

Health Module


Examples

Good Structure: Security Module

API (forge-api/forge-security-api):

io.forge.kit.security.api/
├── domain/
│   ├── exception/
│   │   └── AuthenticationException.java
│   ├── TokenValidator.java
│   ├── ServiceAuthenticationProvider.java
│   └── UserAuthenticationProvider.java
├── dto/
│   ├── AuthIdentity.java
│   ├── AuthResponse.java
│   └── TokenValidation.java
├── jwt/
│   ├── JwtPrincipal.java
│   └── JwtPrincipalExtractor.java
└── rest/
    ├── AllowedServices.java
    └── Secured.java

Implementation (forge-impl/forge-security):

io.forge.kit.security.impl/
├── infrastructure/
│   └── AllowedServicesResolver.java
├── jwt/
│   ├── JwtPayloadParser.java
│   ├── JwtPrincipalResolver.java
│   ├── JwtServicePrincipalAccessor.java
│   ├── JwtTokenExtractor.java
│   └── JwtUserPrincipalAccessor.java
└── rest/
    └── exception/
        └── AuthenticationExceptionMapper.java

Consequences

Positive:


Implementation

New Modules

All new modules must follow these standards from creation.

Existing Modules

Existing modules should be refactored to follow these standards when:

Note: Not all modules need immediate refactoring. Standards apply to new code and major changes.


Validation

Code reviews should verify:


Deviations and Notes

The current structure generally follows these standards. Key observations:

  1. API/Implementation Separation: Clear separation between forge-api and forge-impl modules
  2. Layer Organization: Consistent use of domain/, infrastructure/, rest/, dto/ layers
  3. Package Naming: Consistent io.forge.kit.{module}.{api|impl}.{layer} pattern
  4. Module-Specific Layers: Appropriate use of specialized layers (jwt/, key/, faulttolerance/, persistence/)

Minor Observations:


Decision Owner: Architecture Team

Review Cycle: Review annually or when new module types are introduced