Backend helpdesk-системы: пользователи создают обращения, поддержка обрабатывает назначенные тикеты, администратор управляет очередью и сотрудниками.
Проект сделан как portfolio-ready модульный монолит: бизнес-правила находятся в service/domain-слое, REST-контроллеры не знают о persistence, схема БД версионируется Flyway, а доступ проверяется и на уровне endpoint, и на уровне конкретного ресурса.
- Java 21, Spring Boot 4.0.7
- Spring Security, stateless JWT (HS256 через Nimbus)
- Spring Data JPA, PostgreSQL 17, Flyway
- Bean Validation, OpenAPI/Swagger UI
- Maven, Docker Compose, JUnit 6, MockMvc
- GitHub Actions CI
- регистрация и login, BCrypt, JWT с TTL;
- роли
USER,SUPPORT,ADMIN; - создание, просмотр, фильтрация и пагинация тикетов;
- назначение сотрудника, приоритеты и контролируемый workflow статусов;
- публичные и внутренние комментарии;
- безопасная загрузка вложений до 10 MB с whitelist MIME-типов;
- audit history для ключевых действий;
- transactional notification stub;
- optimistic locking (
@Version), единый формат ошибок; - health/metrics endpoints, OpenAPI и Docker image.
| Роль | Видимость | Основные действия |
|---|---|---|
| USER | только свои тикеты | создать, комментировать, отменить |
| SUPPORT | только назначенные тикеты | отвечать, менять статус/приоритет, внутренние комментарии |
| ADMIN | все тикеты | назначать поддержку, управлять пользователями, смотреть audit history |
Допустимые переходы:
OPEN -> IN_PROGRESS -> WAITING_FOR_CUSTOMER -> IN_PROGRESS
\-> RESOLVED -> CLOSED
RESOLVED -> IN_PROGRESS
OPEN / IN_PROGRESS / WAITING_FOR_CUSTOMER -> CANCELLED
CLOSED и CANCELLED — терминальные состояния. Начать работу без назначенного сотрудника нельзя.
Требования: Java 21, Maven 3.9+, Docker.
docker compose up -d postgres
mvn spring-boot:runПриложение: http://localhost:8080
Swagger UI: http://localhost:8080/swagger-ui.html
PostgreSQL опубликован на localhost:5433, чтобы не конфликтовать с локальной БД на стандартном 5432.
При первом старте создаётся администратор:
email: admin@example.com
password: Admin123!
Перед любым публичным запуском задайте JWT_SECRET, ADMIN_EMAIL и ADMIN_PASSWORD. Все параметры перечислены в .env.example.
Регистрация:
curl -X POST http://localhost:8080/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"Password123!","displayName":"Alex"}'Создание тикета (подставьте JWT):
curl -X POST http://localhost:8080/api/v1/tickets \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"subject":"Order issue","description":"Package has not arrived","category":"ORDER","priority":"HIGH"}'Фильтрация:
GET /api/v1/tickets/my?status=OPEN&priority=HIGH&q=order&page=0&size=20&sort=createdAt,desc
GET /api/v1/admin/tickets?category=SERVICE&from=2026-01-01T00:00:00Z| Method | Endpoint | Назначение |
|---|---|---|
| POST | /api/v1/auth/register |
регистрация |
| POST | /api/v1/auth/login |
login |
| POST | /api/v1/tickets |
создать тикет |
| GET | /api/v1/tickets/my |
доступные текущему пользователю тикеты |
| GET | /api/v1/tickets/{id} |
карточка тикета |
| PATCH | /api/v1/tickets/{id}/status |
сменить статус |
| PATCH | /api/v1/tickets/{id}/assign |
назначить поддержку (ADMIN) |
| PATCH | /api/v1/tickets/{id}/priority |
сменить приоритет |
| POST/GET | /api/v1/tickets/{id}/comments |
комментарии |
| POST | /api/v1/tickets/{id}/attachments |
загрузить файл |
| GET | /api/v1/attachments/{id}/download |
скачать файл |
| GET | /api/v1/admin/tickets |
глобальная очередь |
| GET | /api/v1/admin/users |
пользователи |
| PATCH | /api/v1/admin/users/{id}/role |
изменить роль |
| PATCH | /api/v1/admin/users/{id}/enabled |
включить/отключить аккаунт |
| GET | /api/v1/admin/tickets/{id}/history |
история тикета |
| Variable | Default | Назначение |
|---|---|---|
DB_URL |
jdbc:postgresql://localhost:5433/support_ticket |
JDBC URL |
DB_USERNAME |
support |
пользователь БД |
DB_PASSWORD |
support |
пароль БД |
JWT_SECRET |
dev-only значение | секрет подписи, минимум 32 bytes |
STORAGE_LOCATION |
./uploads |
каталог файлов |
ADMIN_EMAIL |
admin@example.com |
bootstrap admin |
ADMIN_PASSWORD |
Admin123! |
пароль bootstrap admin |
mvn test
mvn verifyUnit-тесты проверяют workflow и файловое хранилище. Интеграционные MockMvc-тесты поднимают полный Spring-контекст и проверяют JWT, разграничение доступа, validation, комментарии и жизненный цикл тикета.
com.portfolio.support
├── auth # регистрация, login, JWT
├── security # SecurityFilterChain, current user
├── ticket # основной aggregate, workflow, filters, comments
├── attachment # metadata + storage abstraction
├── audit # история изменений
├── notification # transactional notification stub
├── admin # управление пользователями и аудит
└── shared # базовые entity, errors, pagination
Следующие естественные шаги развития: refresh-token rotation, S3/MinIO storage, outbox pattern для уведомлений, SLA/escalation jobs и полнотекстовый поиск PostgreSQL.