Backend service for managing bank cards, users and transfers between a user's own cards.
The project is built with Spring Boot and demonstrates authentication, role-based authorization, transactional business logic, persistence with PostgreSQL, database migrations and API documentation.
- registration and login;
- JWT access and refresh tokens;
- Spring Security;
- role-based access for
USERandADMIN.
- create, activate, block and delete cards;
- list cards with pagination and filtering;
- mask card numbers in API responses;
- encrypt sensitive card data before persistence;
- access control so users operate only on their own cards.
- transfers between cards owned by the same user;
- balance validation;
- transactional balance updates.
- REST API;
- PostgreSQL;
- Liquibase migrations;
- Docker and Docker Compose;
- OpenAPI / Swagger UI;
- JUnit / Mockito tests;
- JaCoCo coverage reports.
- Java 17
- Spring Boot 3
- Spring MVC
- Spring Security
- Spring Data JPA / Hibernate
- PostgreSQL
- Liquibase
- JWT (
java-jwt) - Docker / Docker Compose
- OpenAPI / Swagger
- Maven
- JUnit 5 / Mockito
- JaCoCo
The application follows a layered structure:
controller -> service -> repository -> PostgreSQL
|
+-> mapping / validation / security rules
Main packages:
src/main/java/com/example/bankcards
├── config # Security and OpenAPI configuration
├── controller # REST endpoints
├── dto # Request / response models
├── entity # JPA entities
├── exception # Domain and API exceptions
├── mapper # Entity / DTO mapping
├── repository # Spring Data repositories
├── security # JWT utilities
└── service # Business logic
- JDK 17+
- Docker and Docker Compose
Create a .env file in the project root:
DB_NAME=bank
DB_USER=postgres
DB_PASSWORD=postgres
DB_URL=jdbc:postgresql://db:5432/bank
JWT_SECRET=replace-with-a-long-random-secret
SPRING_PROFILES_ACTIVE=localdocker compose up --buildThe application will be available at:
http://localhost:8080
PostgreSQL is exposed locally on port 5433.
After startup, Swagger UI is available at:
http://localhost:8080/swagger-ui/index.html
OpenAPI JSON:
http://localhost:8080/v3/api-docs
Run the test suite:
./mvnw testRun tests and generate the JaCoCo report:
./mvnw clean testThe HTML coverage report is generated under:
target/site/jacoco/index.html
- JWT secrets are supplied through environment variables and must not be committed to the repository.
- Card numbers are not returned to clients in full; API responses use masked values.
- Role-based authorization restricts administrative operations.
- Transfer operations validate card ownership before changing balances.
Areas intentionally worth evolving toward a more production-oriented implementation:
- optimistic or pessimistic locking for concurrent balance updates;
- integration tests with PostgreSQL / Testcontainers;
- refresh-token revocation strategy;
- structured error responses and centralized exception handling;
- CI pipeline with automated test execution;
- observability with application metrics and tracing.