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

9.2 KiB
Raw Permalink Blame History

Структура БД и модель данных

Документ описывает схемы PostgreSQL, которые используются приложением, а также слой абстракции на базе Ktorm ORM.

Технологический стек

  • PostgreSQL основная СУБД. Подключение выполняется через HikariCP (см. app/Database.kt), параметры берутся из переменных окружения DB_*.
  • Ktorm ORM легковесная ORM, которая:
    • предоставляет интерфейсы Entity для объектного представления строк;
    • описывает таблицы через object Table<T> (например, object NewsT : Table<News>("t_news"));
    • дает Database.sequenceOf(Table) для CRUD-операций и построения SQL через DSL.

Каждая доменная сущность имеет:

  1. interface <Entity> : Entity<<Entity>> декларация полей.
  2. object <Table> : Table<<Entity>>("table_name") описание колонок/ключей и связей через bindTo/references.
  3. DTO для сериализации в API.

Таблицы

t_admins

Колонка Тип Описание
id bigint (PK) Идентификатор администратора
username varchar Уникальное имя пользователя
password_hash varchar Хеш пароля (bcrypt)
created_at timestamp Дата регистрации
last_login_at timestamp nul. Время последней авторизации

Сущность: AdminEntity, таблица: AdminUsers. Используется модулем admin для регистрации, логина, смены паролей и удаления аккаунтов.

t_news

Колонка Тип Описание
id bigint (PK) Идентификатор новости
title varchar Заголовок
slug varchar Уникальный slug для ссылок
summary varchar Краткое описание
content text Основной текст
status varchar DRAFT | PUBLISHED | ARCHIVED
published_at timestamp nul. Дата публикации
image_url varchar nul. Ссылка на изображение
created_at timestamp Дата создания
updated_at timestamp Дата последнего обновления

Сущность: News, таблица: NewsT. Репозиторий использует фильтры по статусу и slug для публичных и админских запросов.

t_service_categories

Колонка Тип Описание
id bigint (PK) Идентификатор категории
name varchar Название
slug varchar Уникальный slug

Сущность: ServiceCategoryEntity, таблица: ServiceCategories. Используется как справочник категорий услуг.

t_services

Колонка Тип Описание
id bigint (PK) Идентификатор услуги
title varchar Название
slug varchar Уникальный slug
description text Подробное описание
price_from decimal nul. Нижняя граница стоимости
image_url varchar nul. Изображение
status varchar PUBLISHED | DRAFT | ARCHIVED
category_id bigint FK Ссылка на t_service_categories.id (может быть NULL)
created_at timestamp Дата создания
updated_at timestamp Дата обновления

Сущность: ServiceEntity, таблица: Services. Поле category смоделировано через references(ServiceCategories) и возвращает ServiceCategoryEntity?. Сервис объединяет услуги и категории для публичного и админского API.

t_users (лиды)

Колонка Тип Описание
id bigint (PK) Идентификатор лида
full_name varchar Имя и фамилия
email varchar Контактный email
phone varchar nul. Телефон
created_at timestamp Дата поступления заявки

Сущность: LeadEntity, таблица: Leads. Несмотря на название таблицы t_users, фактически хранит только заявки. Админский модуль использует пагинацию и поиск по full_name/email.

Связи между сущностями

  • Service → ServiceCategory (многие к одному): Services.category_id ссылается на ServiceCategories.id. Ktorm позволяет навигировать через ServiceEntity.category. При выборе услуг можно жадно загружать категорию и формировать вложенный DTO.
  • Admin, News, Leads независимые сущности без внешних ключей на другие таблицы (в текущей версии).
  • Status/enum поля находятся в бизнес-логике: нет отдельных таблиц для статусов, их значения валидируются сервисами.

Использование Ktorm

  • Entity интерфейсы объявляют свойства и их типы. Экземпляры создаются через Entity.Factory.

  • Table объекты задают имя таблицы, колонки и связи. Пример:

    object Services : Table<ServiceEntity>("t_services") {
        val title = varchar("title").bindTo { it.title }
        val category = long("category_id").references(ServiceCategories) { it.category }
    }
    
  • Расширения Database в каждом модуле есть свой val Database.<entities> (например, Database.news) для получения sequenceOf(Table):

    val Database.news get() = this.sequenceOf(NewsT)
    

    Это скрывает детали доступа к данным и дает типобезопасные операции (filter, sortedBy, take, drop, insert, update и т.д.).

  • DTO слой отделяет Ktorm-entity от сериализуемых объектов (например, NewsDTO, ServiceDTO). Преобразование выполняется в сервисах.

Итог

База данных состоит из пяти основных таблиц, объединенных единым пулом соединений и общими практиками (таймстемпы, статусы, slug). Слабое связывание между сущностями делает схему гибкой, а Ktorm обеспечивает лаконичный и типобезопасный доступ к данным без тяжелых ORM-схем. Диаграмма CRUD-слоя (docs/crud-model.svg) дополняет данное описание визуальным представлением потока данных.