This is a simple transaction engine implemented in Java 21 with Spring Boot. It supports operations such as purchase, installment purchase, withdrawal, and payment, managing accounts and transactions.
The goal of this project is to implement a simple transaction engine that can handle various types of transactions (purchase, installment purchase, withdrawal, payment) while managing accounts and ensuring data integrity. The application should be able to create accounts, perform transactions, and retrieve account details.
This approach was chosen instead of microservices to reduce operational complexity while still allowing future scalability.
For a detailed explanation of design decisions, trade-offs, and system structure, see ARCHITECTURE.md.
- Java 21 (as the programming language)
- Spring Boot (with Spring Data JPA for database interactions and Spring Web for REST API)
- PostgreSQL (as the relational database)
- Docker & Docker Compose (for containerization, to facilitate deployment and ensure consistency across environments)
- JUnit 5 (for unit testing)
- Mockito (for unit testing)
- Swagger/OpenAPI (for API documentation)
- Spring Actuator (for monitoring and health checks)
- Gradle (build and dependency management)
- Lombok (to reduce boilerplate code)
- Flyway (Database Migrations, to facilitate schema management and versioning)
- Create accounts
- Perform transactions (purchase, installment purchase, withdrawal, payment)
- Retrieve account details
- Docker
- Docker Compose
This application follows the Externalized Configuration principle from the Twelve-Factor App methodology.
All sensitive and environment-specific configurations (such as database credentials) are managed through environment variables instead of being hardcoded in the application.
A .env file is used for local development convenience and is loaded via Docker Compose.
To avoid exposing sensitive information, the application uses environment variables.
- Create a
.envfile:
cp env.example .env- Fill in the required values based on
.env.example.
docker-compose up --build -dThe application will be available at:
http://localhost:8080
docker-compose down -vThis project follows the Testing Pyramid approach:
- Unit Tests: Validate individual components in isolation (fast and reliable)
- Functional Tests: Validate end-to-end behavior simulating real use cases
./gradlew test
./gradlew functionalTestAfter starting containers with Docker, you can use Swagger or CURL to test the application manually:
POST /accounts— Create an accountcurl -X 'POST' \ 'http://localhost:8080/accounts' \ -H 'accept: */*' \ -H 'Content-Type: application/json' \ -d '{ "document_number": "12345678900" }'
GET /accounts/{account_id}— Retrieve an accountcurl -X 'GET' \ 'http://localhost:8080/accounts/{id}' \ -H 'accept: */*'
POST /transactions— Perform transactioncurl -X 'POST' \ 'http://localhost:8080/transactions' \ -H 'accept: */*' \ -H 'Content-Type: application/json' \ -d '{ "account_id": 1, "operation_type_id": 1, "amount": 100 }'
| Account_ID | Document_Number |
|---|---|
| BIGSERIAL | VARCHAR(20) |
| Transaction_ID | Account_ID | OperationType_ID | Amount | EventDate |
|---|---|---|---|---|
| BIGSERIAL | BIGSERIAL | BIGINT | Decimal(10,2) | TIMESTAMP |
| OperationType_ID | Description |
|---|---|
| BIGINT | VARCHAR(255) |
- Swagger UI: http://localhost:8080/swagger-ui/index.html
- Architecture: ARCHITECTURE.md
- Actuator: http://localhost:8081/actuator
- Introduce explicit account balance tracking and authorization rules.
- Implement locking mechanisms (e.g., optimistic or pessimistic locking) to ensure consistency under concurrent access.
- Add idempotency keys on operations to prevent duplicate transaction creation.