first commit

This commit is contained in:
Oscar
2026-06-02 15:52:22 +03:00
commit dc44cdd639
105 changed files with 14674 additions and 0 deletions

247
database-schema.md Normal file
View File

@@ -0,0 +1,247 @@
# Схема базы данных
## Обзор
Все идентификаторы — `uuid`. Схема разбита на домены: авторизация, профиль, гео, тарифы, социальные действия, чат, встречи, модерация.
---
## Таблицы
### `user`
Авторизационные данные. Намеренно отделены от профиля — публичная анкета живёт в `profile`.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| phone | string | номер телефона |
| password | string | хешированный пароль |
| status | string | `active` / `banned` / `pending` |
| role_id | uuid FK → role | роль пользователя |
| tariff_id | uuid FK → tariff | текущий тариф |
| payment_id | uuid FK → payment | способ оплаты |
| active_chat_id | uuid FK → chat | активный чат (один пользователь — один чат одновременно) |
| fcm_token | string | токен для push-уведомлений (FCM) |
---
### `profile`
Публичная анкета пользователя. Это то, что видят другие в ленте.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| user_id | uuid FK → user | |
| name | string | |
| birth_date | date | вместо `age` — возраст вычисляется на лету |
| city_id | uuid FK → city | |
| district_id | uuid FK → city_district | район / метро, опционально |
| description | string | текст анкеты |
| nation | string | национальность |
| height | float | опционально |
| weight | float | опционально |
---
### `media`
Фотографии и видео пользователя в анкете. Файлы хранятся в MinIO, здесь только путь.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| user_id | uuid FK → user | |
| path | string | URL в MinIO |
| type | string | `photo` / `video` |
---
### `tag`
Справочник интересов / тегов.
| Поле | Тип |
|---|---|
| id | uuid PK |
| value | string |
### `profile_tag`
Связь M:M между профилем и тегами.
| Поле | Тип |
|---|---|
| profile_id | uuid FK → profile |
| tag_id | uuid FK → tag |
---
### `city`
Справочник городов.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| name | string | |
| lat | decimal | широта центра города |
| lng | decimal | долгота центра города |
### `city_district`
Районы и станции метро внутри города.
| Поле | Тип |
|---|---|
| id | uuid PK |
| city_id | uuid FK → city |
| name | string |
---
### `tariff`
Тарифные планы подписки.
| Поле | Тип |
|---|---|
| id | uuid PK |
| name | string |
| price_per_month | decimal |
| price_per_year | decimal |
### `payment`
Платёжные данные пользователя.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| user_id | uuid FK → user | |
| provider | string | название платёжной системы |
| credentials | string | токен / идентификатор в платёжной системе |
---
### `role`
Роли пользователей: `user`, `moderator`, `admin`.
| Поле | Тип |
|---|---|
| id | uuid PK |
| name | string |
### `permission`
Права доступа, привязанные к роли. Используется для логики AdminPanel.
| Поле | Тип |
|---|---|
| id | uuid PK |
| role_id | uuid FK → role |
| name | string |
---
### `like`
Лайк или дизлайк от одного пользователя другому. При взаимном лайке создаётся `match`.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| source_user | uuid FK → user | |
| target_user | uuid FK → user | |
| type | enum | `like` / `dislike` |
| created_at | timestamp | |
### `match`
Взаимный лайк. После создания открывается возможность чата.
| Поле | Тип |
|---|---|
| id | uuid PK |
| user1_id | uuid FK → user |
| user2_id | uuid FK → user |
| created_at | timestamp |
---
### `chat`
Чат между двумя профилями. Один пользователь может иметь только один активный чат одновременно (`user.active_chat_id`).
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| profile1_id | uuid FK → profile | |
| profile2_id | uuid FK → profile | |
| status | string | `active` / `closed` |
### `message`
Сообщения внутри чата. Доставка в реальном времени через Socket.io. Поддерживает текст и медиавложения.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| chat_id | uuid FK → chat | |
| user_id | uuid FK → user | |
| text | string | текст сообщения, опционально |
| media_url | string | URL файла в MinIO, опционально |
| media_type | enum | `photo` / `voice` / `video`, опционально |
| created_at | timestamp | |
### `greetings`
Справочник готовых приветственных фраз. Пользователь выбирает из списка при открытии нового чата. Не привязан ни к чату, ни к пользователю — это просто набор текстов.
| Поле | Тип |
|---|---|
| id | uuid PK |
| text | string |
---
### `report`
Жалобы пользователей. `entity_type` указывает на что именно жалоба.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| source_user | uuid FK → user | кто подал жалобу |
| entity_id | uuid | id объекта жалобы |
| entity_type | enum | `profile` / `message` |
| description | string | текст жалобы |
---
### `date`
Реальная офлайн-встреча двух пользователей. Создаётся по договорённости в чате.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| user1_id | uuid FK → user | |
| user2_id | uuid FK → user | |
| lat | decimal | координаты места встречи |
| lng | decimal | |
| time | timestamp | дата и время встречи |
| status_id | uuid FK → date_status | |
### `date_status`
Справочник статусов встречи.
| Поле | Тип | Описание |
|---|---|---|
| id | uuid PK | |
| text | string | `pending` / `confirmed` / `cancelled` / `rescheduled` |
---
## Связи
```
user ──────────── profile (1:1)
user ──────────── media (1:N)
user ──────────── role (N:1)
user ──────────── tariff (N:1)
user ──────────── payment (1:1)
user ──────────── chat (активный чат, 1:1)
profile ────────── tag (M:M через profile_tag)
profile ────────── city (N:1)
profile ────────── city_district (N:1, опционально)
city ───────────── city_district (1:N)
role ───────────── permission (1:N)
chat ───────────── message (1:N)
date ───────────── date_status (N:1)
report ─────────── user (N:1)
```