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