order-system-services is the executable backend implementation of the Order Processing System.
It follows a modular monolith architecture with explicit boundaries, strong contracts, and
clear separation of concerns.
The system is designed to:
- Be architecture-driven
- Use OpenAPI as a source of truth
- Enforce domain rules explicitly
- Be testable, evolvable, and deployment-ready
This repository is part of a larger Architecture as Code (AaC) initiative and aligns with the architectural decisions documented in the system ADRs.
The system is built on the following principles:
- Architecture is versioned, reviewed, and evolved like code
- OpenAPI, ADRs, and diagrams are treated as first-class artifacts
- Code must conform to architecture, not the other way around
- Single deployable unit
- Strong internal module boundaries
- Explicit dependencies between modules
- Clear migration path toward microservices if needed
- OpenAPI is the source of truth
- API models are generated
- Controllers implement generated interfaces
- No handwritten REST contracts
- Business rules live in the application/domain layer
- Enums, value objects, and services model real concepts
The order-system-services repository is organized as a modular monolith
consisting of a single executable Spring Boot application and several internal modules.
order-system-services
│
├── order-api
├── order-service
├── order-database
├── integration-service
└── pom.xml (parent)
Each module has a single, well-defined responsibility.
| Module | Role | Runtime Type |
|---|---|---|
order-api |
Public API contract (OpenAPI source of truth) | Contract module (no runtime) |
order-service |
Application & domain logic | Spring Boot application |
order-database |
Persistence, schema, migrations | Library module |
integration-service |
External system integrations | Library module |
Key Points
- Exactly one module (
order-service) is a Spring Boot application - All other modules are internal libraries contributing beans via the classpath
- The system is deployed as a single unit, preserving modular boundaries internally
- Module responsibilities are enforced by dependencies, not by separate runtimes
Responsibility
- Defines the public API contract
- Contains the OpenAPI specification
- Generates API models and interfaces
Key Characteristics
- No business logic
- No persistence
- No service dependencies
- Pure contract module
Contents
openapi.yaml- Generated:
- API interfaces (e.g.
OrdersApi) - API models (
Order,OrderItem,Money, etc.)
- API interfaces (e.g.
Key Rule
Other modules depend on
order-api.
order-apidepends on nothing.
Responsibility
- Implements all order-related use cases
- Enforces business rules
- Orchestrates domain services
Key Components
- Controllers (implement generated APIs)
- Application services
- Domain services
- DTOs
- Mappers
- Exception handling
Important Concepts
OrderServiceinterface +OrderServiceImplOrderStatusenum (domain-owned)PricingService– single source of monetary calculationsProductPricingService– pricing abstraction boundary
Key Rules
- Controllers are thin
- No pricing logic outside
PricingService - No persistence logic in controllers
- No REST annotations outside controllers
Responsibility
- Owns database schema
- Owns JPA entities
- Owns repositories
- Owns migrations
Key Characteristics
- Flyway-managed schema
- PostgreSQL-first design
- Testcontainers-based integration tests
Contents
- JPA entities (
OrderEntity,OrderItemEntity) - Repositories (
OrderRepository) - Flyway migrations
- Database integration tests
Key Rule
order-databasecontains no business logic.
Responsibility
- Integration with external systems (ERP, pricing, shipping, etc.)
- Currently a placeholder for future extensions
order-service
├── depends on order-api
├── depends on order-database
└── depends on integration-service (future)
order-api
└── no dependencies
order-database
└── no dependency on order-service
Important
- Dependencies always point inward
- Database never depends on service logic
- API never depends on implementation
- Orders have a well-defined lifecycle via
OrderStatus - Status transitions are explicitly enforced
- Allowed only in states:
CREATED,CONFIRMED - Forbidden in states:
PAID,SHIPPED - Idempotent if already
CANCELLED
- All monetary calculations are centralized
Moneyis a value object- No floating-point arithmetic
- Currency consistency enforced
- Immutable value object
- BigDecimal amount
- ISO currency code
- Safe arithmetic operations
- Calculates:
- Unit price
- Line total
- Order total
- Single source of pricing logic
- Abstraction for future pricing integration
- Currently returns a baseline price
- Replaceable without touching domain logic
The order-service exposes a health endpoint via Spring Boot Actuator.
This endpoint is used by AWS for load balancer health checks and operational monitoring.
GET /actuator/health
curl http://<alb-dns-name>/actuator/health
Response:
{
"status": "UP"
}
- Flyway migration tests
- PostgreSQL Testcontainers
- Schema verification
- Unit tests for:
- Application services
- Business rules
- Controller integration tests using:
@WebMvcTest- Raw JSON payloads
- Mocked dependencies
A ready-to-use Postman collection is provided to test the deployed Order Service running on AWS.
Postman artifacts are stored under the order-service module:
order-service/postman/
├── order-service-aws.postman_collection.json
└── order-service-aws.postman_environment.json
- Open Postman
- Import both files:
order-service-aws.postman_collection.jsonorder-service-aws.postman_environment.json
- Select environment: order-service-aws
The collection covers the core Order Processing use cases:
- Health check
- Create order
- Get order by ID
- Cancel order
- All identifiers (
customerId,productId,orderId) are UUIDs - Requests not matching the OpenAPI contract are rejected with HTTP 400
- Validation is intentionally strict to enforce API correctness
At this stage, the system is:
- Functionally complete
- Architecturally stable
- Test-covered
- Ready for:
- Containerization
- CI/CD
- Environment configuration
- Infrastructure as Code
This section focuses on local execution only. Cloud deployment concerns are intentionally out of scope here and are addressed in the Deployment Readiness section.
The goal is to describe how to run and test the system locally using Docker and Spring profiles.
For local development, a Docker Compose setup is provided to start a PostgreSQL instance
that matches the local Spring profile configuration.
docker compose up
↓
PostgreSQL container starts (localhost:5432)
↓
Spring Boot connects using `local` profile
↓
Flyway runs database migrations
↓
Application / tests are ready
./scripts/db-up.sh
scripts\db-up.bat
./scripts/db-down.sh
scripts\db-down.bat
- Uses PostgreSQL Testcontainers
- Fully isolated
- No local database required
./scripts/run-db-test.sh
- Uses local PostgreSQL Docker container
- Useful for debugging and schema inspection
./scripts/run-db-local.sh
Flyway migrations are executed automatically on startup.
If you are using Rancher Desktop instead of Docker Desktop on Windows, you may encounter Docker context–related issues on first run.
rm -rf ~/.docker/contexts/meta
docker context use default
Then retry:
./scripts/db-up.sh
This is a one-time setup step.
In addition to running the database in isolation, the full Order Processing System (application + database) can be started locally using Docker Compose.
This setup runs:
order-serviceas a Docker container- PostgreSQL as a Docker container
- The application using the
localSpring profile
All configuration is provided via environment variables and Docker networking.
./scripts/app-up.sh
scripts\app-up.bat
This will:
- Stop any standalone database containers (if running)
- Build all modules and the executable application JAR
- Build the Docker image for order-service
- Start the application and database containers
- Apply Flyway migrations automatically on startup
The API will be available at:
http://localhost:8081
./scripts/app-down.sh
scripts\app-down.bat
This stops all containers and cleans up Docker networks and volumes used by the local application stack.
The project uses two Docker Compose configurations:
docker-compose.db.yml
Starts only PostgreSQL (useful for local development and database testing)docker-compose.yml
Starts the full system (application + database)
This separation keeps concerns clear and supports multiple development workflows.
This repository defines the CI pipeline for the Order Processing System application runtime.
The pipeline is responsible for:
- Building the application
- Running unit and integration tests
- Enforcing architectural guardrails (ArchUnit)
- Building a Docker image
- Publishing the image to Amazon ECR
Architectural correctness is enforced before deployment. If a rule is violated, the application is never deployed to AWS.
GitHub Actions → Maven build → ArchUnit → Docker build → ECR push
This repository serves as both:
- A production-ready system
- A reference implementation for Architecture as Code