RESTful бекенд-застосунок для ведення особистих фінансів на базі Spring Boot 4
Smart Expense Tracker API — це повноцінний RESTful бекенд для керування особистими фінансами. Застосунок дозволяє користувачам реєструватися, вести кілька рахунків у різних валютах, записувати доходи та витрати, встановлювати бюджети на категорії й отримувати детальну аналітику.
- Реєстрація та вхід користувача
- Stateless-сесії на базі JWT Access + Refresh токенів
- Оновлення токена через
/api/auth/refresh - Logout з анулюванням Refresh Token
- Рольова авторизація:
USERтаADMIN
- Створення декількох рахунків на одного користувача
- Типи рахунків:
CASH,CARD,SAVINGS,INVESTMENT - Підтримка валют:
UAH,USD,EUR - Баланс рахунку обчислюється автоматично на основі транзакцій
- Запис доходів (
INCOME) та витрат (EXPENSE) - Прив'язка транзакції до рахунку та категорії
- Фільтрація за типом, категорією та часовим діапазоном
- Пагінований список транзакцій
- При видаленні транзакції баланс рахунку перераховується автоматично
- Власні категорії доходів та витрат для кожного користувача
- Встановлення місячного бюджету на категорію
- Іконки категорій (iconCode)
- Загальна статистика — сума доходів, витрат та загальний баланс за обраний період
- Аналітика за категоріями — розбивка витрат/доходів по категоріях з відсотками
- Місячна статистика — агреговані доходи та витрати згруповані помісячно
- Статус бюджетів — порівняння лімітів категорій з поточними витратами
- Перегляд та управління користувачами (тільки для ролі
ADMIN)
| Категорія | Технологія |
|---|---|
| Мова | Java 21 |
| Фреймворк | Spring Boot 4.0.3 |
| Безпека | Spring Security + JWT (jjwt 0.11.5) |
| ORM | Spring Data JPA / Hibernate |
| БД (prod) | PostgreSQL 15 |
| БД (test) | H2 in-memory |
| Міграції | Liquibase |
| Валідація | Jakarta Bean Validation |
| Маппінг | MapStruct 1.6.3 |
| Кешування | Spring Cache + Caffeine |
| Документація | SpringDoc OpenAPI 3 (Swagger UI) |
| Тестування | JUnit 5 + Mockito + Spring Security Test |
| Збірка | Gradle |
| Контейнеризація | Docker + Docker Compose |
| CI/CD | GitHub Actions |
Проєкт побудовано за класичною Layered Architecture:
Controller → Service → Repository → Database
↕ ↕
DTO ↔ Entity (MapStruct)
src/main/java/com/github/deniskoriavets/smartexpensetracker/
├── config/ # Конфігурації (Cache, OpenAPI)
├── controller/ # REST-контролери
│ ├── AuthController
│ ├── AccountController
│ ├── TransactionController
│ ├── CategoryController
│ ├── AnalyticsController
│ └── AdminController
├── dto/ # Data Transfer Objects
│ ├── account/
│ ├── analytics/
│ ├── auth/
│ ├── category/
│ ├── transaction/
│ └── user/
├── entity/ # JPA-сутності
│ ├── enums/ # AccountType, CategoryType, Currency, Role, TransactionType
│ ├── Account
│ ├── Category
│ ├── Transaction
│ ├── User
│ └── RefreshToken
├── exception/ # Глобальна обробка помилок
├── mapper/ # MapStruct-маппери
├── repository/ # Spring Data JPA репозиторії
├── security/ # JWT-фільтр, конфігурація безпеки
└── service/ # Бізнес-логіка
- Docker та Docker Compose
- JDK 21 (для локального запуску без Docker)
git clone https://github.com/DenisKoriavets/smart-expense-tracker.git
cd smart-expense-trackerСтворіть файл .env у корені проєкту:
JWT_SECRET_KEY=your-very-secret-key-at-least-256-bits-long
⚠️ Ніколи не комітьте.envу репозиторій. Він вже є у.gitignore.
# Зібрати Docker-образ застосунку
docker build -t smart-expense-tracker:latest .
# Запустити застосунок та базу даних
docker compose up -dЗастосунок буде доступний за адресою: http://localhost:8080
Переконайтесь, що PostgreSQL запущено та налаштовано, потім:
./gradlew bootRun| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
POST |
/register |
Реєстрація нового користувача | ❌ |
POST |
/login |
Вхід та отримання токенів | ❌ |
POST |
/refresh |
Оновлення Access Token | ❌ |
POST |
/logout |
Вихід із системи | ❌ |
| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
POST |
/ |
Створити рахунок | ✅ |
GET |
/ |
Отримати всі рахунки користувача | ✅ |
GET |
/{id} |
Отримати рахунок за ID | ✅ |
PUT |
/{id} |
Оновити рахунок | ✅ |
DELETE |
/{id} |
Видалити рахунок | ✅ |
| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
POST |
/ |
Створити транзакцію | ✅ |
GET |
/account/{accountId} |
Транзакції рахунку (з фільтрами та пагінацією) | ✅ |
GET |
/{id} |
Отримати транзакцію за ID | ✅ |
PUT |
/{id} |
Оновити транзакцію | ✅ |
DELETE |
/{id} |
Видалити транзакцію | ✅ |
Query-параметри для GET /account/{accountId}:
type — INCOME | EXPENSE
categoryId — UUID категорії
from — дата від (ISO 8601, напр. 2025-01-01T00:00:00)
to — дата до (ISO 8601)
page, size — пагінація (Spring Pageable)
| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
POST |
/ |
Створити категорію | ✅ |
GET |
/ |
Отримати всі категорії | ✅ |
GET |
/{id} |
Отримати категорію за ID | ✅ |
PUT |
/{id} |
Оновити категорію | ✅ |
DELETE |
/{id} |
Видалити категорію | ✅ |
| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
GET |
/summary |
Загальна статистика за період | ✅ |
GET |
/categories |
Аналітика за категоріями | ✅ |
GET |
/monthly |
Місячна статистика | ✅ |
GET |
/budgets |
Статус бюджетів поточного місяця | ✅ |
| Метод | Endpoint | Опис | Auth |
|---|---|---|---|
GET |
/users |
Список усіх користувачів | ✅ ADMIN |
PUT |
/users/{id}/deactivate |
Деактивувати користувача | ✅ ADMIN |
Після запуску застосунку інтерактивна документація API доступна за адресою:
http://localhost:8080/swagger-ui.html
Специфікація OpenAPI у JSON:
http://localhost:8080/api-docs
Проєкт містить юніт- та інтеграційні тести для всіх шарів застосунку.
# Запустити всі тести
./gradlew test
# Запустити тести з детальним виводом
./gradlew test --info| Шар | Тести |
|---|---|
| Controllers | AccountControllerTest, AuthControllerTest, CategoryControllerTest, TransactionControllerTest, AnalyticsControllerTest |
| Services | AccountServiceTest, CategoryServiceTest, TransactionServiceTest, AnalyticsServiceTest |
| Repositories | AccountRepositoryTest, CategoryRepositoryTest, TransactionRepositoryTest, UserRepositoryTest |
Тести використовують H2 in-memory базу даних через профіль
test, що дозволяє запускати їх без PostgreSQL.
Схема БД керується через Liquibase і версіонується у вигляді міграцій:
src/main/resources/db/changelog/migrations/
├── 001-create-users-table.xml
├── 002-create-accounts-table.xml
├── 003-create-categories-table.xml
├── 004-create-transactions-table.xml
└── 005-create-refresh-tokens-table.xml
Міграції застосовуються автоматично при старті застосунку.
Застосунок підтримує профілі Spring:
| Профіль | Файл | Опис |
|---|---|---|
dev (default) |
application-dev.yaml |
Локальна розробка, PostgreSQL |
test |
application-test.yaml |
Тести, H2 in-memory |
Зміна активного профілю:
SPRING_PROFILES_ACTIVE=dev ./gradlew bootRunGitHub Actions автоматично запускає pipeline при кожному push або pull request у гілку master:
- Checkout — клонування репозиторію
- Setup JDK 21 (Temurin distribution)
- Gradle Build — збірка та запуск тестів (
./gradlew clean build) - Docker Build — побудова Docker-образу
Конфігурація: .github/workflows/ci.yaml
- Паролі зберігаються у хешованому вигляді (BCrypt)
- Stateless-автентифікація через JWT Access Token (короткоживучий)
- Refresh Token зберігається у БД і може бути анульований при logout
- Всі ендпоінти (крім
auth/*та Swagger) захищені JWT-фільтром - Адмін-ендпоінти доступні тільки для ролі
ROLE_ADMIN - Кешування (Caffeine) з TTL 5 хвилин для часто запитуваних даних
Denis Koriavets