Add docker

This commit is contained in:
Evgenii Saenko
2025-12-17 11:52:18 +03:00
parent 2d5b329b36
commit ea390b1533
38 changed files with 1359 additions and 165 deletions

102
docs/architecture.md Normal file
View File

@@ -0,0 +1,102 @@
# Архитектура и структура сервиса
Документ описывает как организован сервер дипломного проекта: какие слои присутствуют, как они взаимодействуют и где искать ключевые модули.
## Общий обзор
Сервис написан на Kotlin с использованием Ktor и разворачивается как Netty-приложение (`Application.kt`). Приложение поднимает инфраструктурные плагины (HTTP, сериализация, безопасность) и регистрирует доменные маршруты. Все функции сгруппированы в повторяющийся паттерн `Controller → Service → Repository → Entity`, что делает поддержку CRUD-операций симметричной во всех доменных областях.
Высокоуровневый поток запросов:
1. HTTP-вызов попадает в `Routing.kt`, где маршруты разделены на публичную и админскую зоны (`/api/v1/...`).
2. Контроллер модуля занимается десериализацией запроса, базовой валидацией и формированием ответа.
3. Сервис инкапсулирует бизнес-правила: публикация материалов, фильтрация, проверка прав, подготовка DTO.
4. Репозиторий обращается к PostgreSQL через Ktorm, используя HikariCP-пул соединений.
5. Исключения (`ValidationException`, `NotFoundException`) перехватывает `StatusPages`, что обеспечивает единый контракт ошибок.
Графическая схема слоев расположена в `docs/crud-model.svg`.
## Структура каталогов
```
src/main/kotlin
├── app # Bootstrap: Application, Routing, Security, HTTP, Database
├── shared # Переиспользуемые DTO, пагинация, ошибки
└── modules # Доменные модули (admin, news, service, serviceCategory, lead)
src/main/resources
├── application.yaml # Конфигурация Ktor
└── openapi # Спецификации API
src/test/kotlin # Зеркало production-пакетов для тестов
docs/
├── crud-model.svg # Диаграмма последовательности CRUD
└── architecture.md # Текущий документ
```
## Инфраструктурный слой (`app/*`)
- **Application.module** точка входа, выстраивает последовательность `configureDatabase → configureHTTP → configureSerialization → configureSecurity → configureRouting`.
- **Database.kt** инициализация пула HikariCP (настройки берутся из `.env`), регистрация `Database` в `Application.attributes`.
- **Http.kt** подключает плагины Ktor (CORS, Compression, CachingHeaders, StatusPages, Swagger UI). Здесь же централизованно обрабатываются исключения.
- **Serialization.kt** `ContentNegotiation` с `kotlinx.serialization`.
- **Security.kt** загрузка параметров JWT из окружения, настройка схемы `admin-auth`, валидация `JWTPrincipal`.
- **Routing.kt** собирает зависимости модулей, подключает публичные маршруты и оборачивает админские роуты в `authenticate("admin-auth")`.
## Доменные модули (`modules/*`)
Каждый модуль состоит из четырех файлов:
- `Controller.kt` набор Ktor-маршрутов для публичной и/или админской зоны.
- `Service.kt` бизнес-логика. Например, `NewsService` отвечает за публикацию, пагинацию и преобразование сущностей в DTO, а `ServiceService` поддерживает фильтры по статусу, категории и ценовому диапазону.
- `Repository.kt` слой доступа к данным на Ktorm: построение SQL, пагинация, CRUD-операции, трансформации в `Entity`.
- `Entity.kt` / DTO описания таблиц, модели для сериализации и транспортировки данных.
### Admin
Отвечает за регистрацию, авторизацию и управление администраторами. Использует `BcryptPasswordHasher` для хранения паролей и `TokenService` для выпуска JWT. Публичная часть (`/admin/login`) возвращает токен; защищенная (`/admin/*`) требует `admin-auth`.
### News
Два набора маршрутов: публичные (`/news`, `/news/{slug}`) и админские (`/admin/news`). Сервис применяет правила публикации и формирует страницы (`Page<T>`). Репозиторий обрабатывает SQL для списков и выборок по `slug`.
### Services и Service Categories
`ServiceController` поддерживает сложные фильтры (категория, диапазон цен, статус). `ServiceService` связывает услуги с категориями, обеспечивая получение вложенных DTO. `ServiceCategory*` модули обслуживают справочник категорий и проверяют уникальность `slug`.
### Leads
`publicLeadRoutes` принимает заявки с сайта (`POST /leads`), `adminLeadRoutes` предоставляет CRUD для операторов. Сервис выполняет базовую валидацию и поиск по строке `q`.
## Общие компоненты (`shared/*`)
- `shared.pagination.Page` универсальный ответ для списков.
- `shared.errors.ValidationException/NotFoundException` типы, которые перехватываются `StatusPages` и автоматически конвертируются в HTTP-ответ.
## Работа с БД
- **База** PostgreSQL, подключение через Ktorm + HikariCP (`jdbc:postgresql://...`).
- **Пулы** настраиваются через переменные окружения (`DB_HOST`, `DB_POOL_MAX` и т.д.).
- **Репозитории** реализованы вручную на SQL Builder, что дает контроль над запросами и связями между таблицами (`services``service_categories`, `news`, `leads`, `admins`).
## Безопасность
- Единственная схемa аутентификации JWT `admin-auth`.
- Конфигурация (`JWT_SECRET`, `JWT_ISSUER`, `JWT_AUDIENCE`, `JWT_EXPIRES_MIN`) читается из `.env` или переменных окружения.
- Public маршруты доступны без токена, все `admin*Routes` подключены внутри `authenticate`.
## Сборка и эксплуатация
- Основные команды Gradle:
- `./gradlew run` локальный сервер.
- `./gradlew test` прогон тестов (обязателен перед пушем).
- `./gradlew buildFatJar` сборка standalone JAR.
- `./gradlew buildImage` / `runDocker` сборка и запуск docker-образа.
- Конфигурация HTTP-порта, логирования и OpenAPI лежит в `src/main/resources/application.yaml` и `resources/openapi`.
- Для обновления документации добавляйте артефакты в `docs/` (например, текущую архитектурную схему и диаграмму CRUD).
## Тестирование
Тесты зеркалируют production-пакеты (`src/test/kotlin/...`). При добавлении новой функциональности рекомендуется:
1. Класть тесты в соответствующий пакет модуля (например, `modules/news/NewsServiceTest.kt`).
2. Проверять ветки успеха, валидации и авторизации.
3. Запускать `./gradlew test` перед коммитом, чтобы убедиться в корректной работе всего набора.