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

8.8 KiB
Raw Permalink Blame History

Архитектура и структура сервиса

Документ описывает как организован сервер дипломного проекта: какие слои присутствуют, как они взаимодействуют и где искать ключевые модули.

Общий обзор

Сервис написан на 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, что дает контроль над запросами и связями между таблицами (servicesservice_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 перед коммитом, чтобы убедиться в корректной работе всего набора.