Files
diploma-server/docs/architecture.md
Evgenii Saenko ea390b1533 Add docker
2025-12-17 11:52:18 +03:00

103 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура и структура сервиса
Документ описывает как организован сервер дипломного проекта: какие слои присутствуют, как они взаимодействуют и где искать ключевые модули.
## Общий обзор
Сервис написан на 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` перед коммитом, чтобы убедиться в корректной работе всего набора.