Data Dictionary
Источник:
backend/app/models/auth.py,catalog.py,booking.py,notification.pyORM: SQLAlchemy 2.0 (Mapped columns), PostgreSQL 16
Business
Таблица:
businesses
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
slug |
String, unique, indexed | да | URL-идентификатор бизнеса (например, 7001234567) |
- |
name |
String | да | Название бизнеса | - |
phone |
String | нет | Телефон бизнеса | да |
email |
String | нет | Email бизнеса | да |
address |
String | нет | Адрес (строка из 2GIS suggest) | - |
city |
String | нет | Город | - |
description |
Text | нет | Описание бизнеса | - |
telegram_chat_id |
String | нет | Chat ID для Telegram уведомлений | - |
created_at |
DateTime | да | Дата создания (server_default=now) | - |
updated_at |
DateTime | да | Дата обновления (onupdate=now) | - |
Связи:
- users -> User (one-to-many)
- services -> Service (one-to-many)
- masters -> Master (one-to-many)
- categories -> Category (one-to-many)
- schedules -> Schedule (one-to-many, where master_id IS NULL)
- bookings -> Booking (one-to-many)
User
Таблица:
users
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
email |
String, unique, indexed | да | Email (или placeholder tg_{id}@telegram.mini.app) |
да |
password_hash |
String | да | bcrypt hash (пустой для Telegram-only users) | - |
full_name |
String | нет | Полное имя | да |
telegram_id |
String, unique | нет | Telegram user ID | да |
role |
String (Enum) | да | Роль: OWNER, ADMIN, STAFF, CUSTOMER |
- |
business_id |
Integer (FK -> businesses.id) | нет | Привязка к бизнесу | - |
created_at |
DateTime | да | Дата создания | - |
updated_at |
DateTime | да | Дата обновления | - |
Роли:
- OWNER - владелец бизнеса (не используется отдельно от ADMIN)
- ADMIN - администратор (создается при регистрации)
- STAFF - сотрудник
- CUSTOMER - клиент (создается при Telegram auth)
Category
Таблица:
categories
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
name |
String | да | Название категории | - |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
Связи:
- services -> Service (one-to-many)
Service
Таблица:
services
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
name |
String | да | Название услуги | - |
description |
Text | нет | Описание услуги | - |
duration |
Integer | да | Длительность в минутах (min=1, default=30) | - |
price |
Float | да | Цена в тенге (default=0) | - |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
category_id |
Integer (FK -> categories.id) | нет | Привязка к категории | - |
is_active |
Boolean | да | Активна ли услуга (default=True) | - |
Связи:
- masters -> Master (many-to-many через master_services)
- category -> Category (many-to-one)
- bookings -> Booking (one-to-many)
Master
Таблица:
masters
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
name |
String | да | Имя мастера | да |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
is_active |
Boolean | да | Активен ли мастер (default=True) | - |
Связи:
- services -> Service (many-to-many через master_services)
- schedules -> Schedule (one-to-many)
- bookings -> Booking (one-to-many)
master_services (Association Table)
Таблица:
master_services
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
master_id |
Integer (FK -> masters.id, PK) | да | ID мастера | - |
service_id |
Integer (FK -> services.id, PK) | да | ID услуги | - |
Schedule
Таблица:
schedules
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
master_id |
Integer (FK -> masters.id) | нет | NULL = расписание бизнеса, NOT NULL = расписание мастера | - |
day_of_week |
Integer | да | День недели: 0=Понедельник, 6=Воскресенье | - |
start_time |
String | да | Начало рабочего дня (формат "HH:MM") | - |
end_time |
String | да | Конец рабочего дня (формат "HH:MM") | - |
break_start_time |
String | нет | Начало перерыва (формат "HH:MM") | - |
break_end_time |
String | нет | Конец перерыва (формат "HH:MM") | - |
is_active |
Boolean | да | Рабочий ли день (default=True) | - |
Бизнес-логика: - Двухуровневая система: Master schedule (если есть) > Business schedule (fallback) - При регистрации создается 7 записей (Пн-Пт: 09:00-18:00 active, Сб-Вс: inactive)
Booking
Таблица:
bookings
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
service_id |
Integer (FK -> services.id) | да | Выбранная услуга | - |
master_id |
Integer (FK -> masters.id) | нет | Назначенный мастер (auto-assign если не выбран) | - |
client_id |
Integer (FK -> clients.id) | нет | Привязка к клиенту (upsert по телефону) | - |
first_name |
String | да | Имя клиента (денормализовано) | да |
phone |
String | да | Телефон клиента (денормализовано) | да |
notes |
Text | нет | Комментарий клиента | - |
start_at |
DateTime | да | Дата и время начала записи | - |
end_at |
DateTime | да | Дата и время окончания (start_at + service.duration) | - |
status |
String (Enum) | да | Статус: pending, confirmed, cancelled, completed, rejected |
- |
price_snapshot |
Float | нет | Цена на момент записи (snapshot из service.price) | - |
created_at |
DateTime | да | Дата создания | - |
updated_at |
DateTime | да | Дата обновления | - |
Статусы:
pending -> confirmed -> completed
| |
v v
rejected cancelled
Client
Таблица:
clients
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
business_id |
Integer (FK -> businesses.id) | да | Привязка к бизнесу | - |
first_name |
String | да | Имя клиента | да |
phone |
String | да | Телефон клиента (уникален в рамках бизнеса) | да |
created_at |
DateTime | да | Дата создания | - |
Бизнес-логика: - Upsert по (business_id, phone) при создании бронирования - Имя обновляется при каждом бронировании
RescheduleProposal
Таблица:
reschedule_proposals
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
booking_id |
Integer (FK -> bookings.id) | да | Привязка к бронированию | - |
proposed_date |
Date | да | Предложенная новая дата | - |
proposed_time |
String | да | Предложенное новое время (формат "HH:MM") | - |
old_date |
Date | да | Оригинальная дата (для отката) | - |
old_time |
String | да | Оригинальное время | - |
status |
String (Enum) | да | PENDING, ACCEPTED, DECLINED, EXPIRED |
- |
created_at |
DateTime | да | Дата создания | - |
Бизнес-логика:
- Lazy expiration: статус EXPIRED проставляется при GET, не по cron
- При ACCEPTED: обновляется booking.start_at и booking.end_at
- При DECLINED: бронирование остается без изменений
Subscription
Таблица:
subscriptions
| Поле | Тип | Обязательное | Описание | PII |
|---|---|---|---|---|
id |
Integer (PK) | да | Auto-increment ID | - |
context_type |
Enum | да | Тип контекста подписки | - |
context_ref |
String | да | Ссылка на контекст (business_id, phone, booking_id) | да* |
channel |
Enum | да | Канал: TELEGRAM, WHATSAPP, SMS |
- |
telegram_chat_id |
String | нет | Telegram chat ID (для канала TELEGRAM) | - |
is_active |
Boolean | да | Активна ли подписка (default=True) | - |
created_at |
DateTime | да | Дата создания | - |
Context Types:
| Тип | context_ref содержит | Назначение |
|---|---|---|
PROVIDER_BUSINESS |
business_id (int as string) | Уведомления провайдера о новых записях |
CLIENT_PHONE |
Телефон клиента | Уведомления клиента по телефону |
CLIENT_BOOKING |
booking_id (int as string) | Уведомления клиента о конкретной записи |
*context_ref помечен PII т.к. может содержать телефон (CLIENT_PHONE)
Каналы:
- TELEGRAM - единственный реально используемый
- WHATSAPP, SMS - определены в enum, но не реализованы
ER-диаграмма (упрощенная)
ERROR 11 Syntax Error? Some diagram description contains errors
PII Summary
| Сущность | PII поля | Основание |
|---|---|---|
| Business | phone, email | Контактные данные бизнеса |
| User | email, full_name, telegram_id | Персональные данные пользователя |
| Master | name | Имя физического лица |
| Booking | first_name, phone | Контактные данные клиента |
| Client | first_name, phone | Контактные данные клиента |
| Subscription | context_ref (при CLIENT_PHONE) | Телефон клиента |
Типы данных (PostgreSQL mapping)
| SQLAlchemy Type | PostgreSQL Type | Используется в |
|---|---|---|
| Integer | integer / serial | Все PK, FK |
| String | varchar | Большинство текстовых полей |
| Text | text | description, notes |
| Float | double precision | price, price_snapshot |
| Boolean | boolean | is_active |
| DateTime | timestamp without time zone | created_at, updated_at, start_at, end_at |
| Date | date | proposed_date, old_date |
| Enum (Python) | varchar (хранится как строка) | role, status, context_type, channel |