Add docker
This commit is contained in:
119
docs/db-structure.md
Normal file
119
docs/db-structure.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Структура БД и модель данных
|
||||
|
||||
Документ описывает схемы 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 объекты** – задают имя таблицы, колонки и связи. Пример:
|
||||
|
||||
```kotlin
|
||||
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)`:
|
||||
|
||||
```kotlin
|
||||
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`) дополняет данное описание визуальным представлением потока данных.
|
||||
Reference in New Issue
Block a user