248 lines
7.9 KiB
Markdown
248 lines
7.9 KiB
Markdown
# Схема базы данных
|
||
|
||
## Обзор
|
||
|
||
Все идентификаторы — `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)
|
||
```
|