Перейти к содержанию

Схема базы данных

ER-диаграмма (основные сущности)

erDiagram
    Tenant ||--o{ User : has
    Tenant ||--o{ Patient : has
    Tenant ||--o{ Department : has
    Department ||--o{ Patient : contains
    Patient ||--o{ Document : has
    Patient ||--o{ Prediction : has
    Patient ||--o{ DicomStudy : has
    User ||--o{ Document : uploads
    User }o--|| Department : belongs
    User ||--o{ ChatSession : has
    ChatSession ||--o{ ChatMessage : contains
    User ||--o{ Progress : tracks
    DicomStudy ||--o{ DicomSeries : contains
    DicomSeries ||--o{ DicomFrame : contains
    Document ||--o{ ParsedData : extracts
    Tenant ||--o{ Subscription : has
    User ||--o| UserPreference : has
    User ||--o| TelegramUser : links

Note

ClinicalCase и Test — справочники сценариев/экзаменов (без обязательного FK на User). Векторное хранилище RAG — Chroma (не таблица Postgres).

Основные таблицы

tenants

Поле Тип Описание
id INTEGER PK
name VARCHAR Название клиники
subdomain VARCHAR UNIQUE Поддомен для входа

users

Поле Тип Описание
id INTEGER PK
tenant_id FK Клиника
email VARCHAR UNIQUE
role ENUM RBAC-роль (student, resident, doctor, …)
department_id FK nullable Отделение
password_hash VARCHAR bcrypt hash

patients

Поле Тип Описание
id INTEGER PK
tenant_id FK
department_id FK
full_name VARCHAR Шифруется при необходимости
date_of_birth DATE
attending_doctor_id FK nullable

documents

Поле Тип Описание
id INTEGER PK
patient_id FK
file_path VARCHAR Зашифрованный путь
status ENUM uploaded/processing/parsed/failed
document_type VARCHAR

dicom_studies / dicom_series / dicom_frames

Иерархия DICOM: Study → Series → Frame (PNG preview).

predictions

Поле Тип Описание
readmission_risk FLOAT 0–1
complication_risk FLOAT 0–1
risk_level VARCHAR low/medium/high
gpt_explanation TEXT

Обучение

chat_sessions (ChatSession)

Поле Тип Описание
id INTEGER PK
public_id UUID Публичный идентификатор
user_id FK → users Владелец сессии
title VARCHAR nullable Заголовок чата
language VARCHAR Язык (en / ru, …)
created_at / updated_at DATETIME

chat_messages (ChatMessage)

Поле Тип Описание
id INTEGER PK
public_id UUID
session_id FK → chat_sessions Каскадное удаление
role VARCHAR user / assistant / system
content TEXT Текст сообщения
sources JSON nullable Источники RAG
created_at DATETIME

clinical_cases (ClinicalCase)

Поле Тип Описание
id INTEGER PK
public_id UUID
title VARCHAR Название кейса
description TEXT Описание
specialty VARCHAR nullable Специальность
difficulty VARCHAR nullable Сложность
steps JSON nullable Пошаговый сценарий
created_at DATETIME

tests (Test)

Поле Тип Описание
id INTEGER PK
public_id UUID
title VARCHAR Название экзамена/квиза
description TEXT nullable
category VARCHAR nullable Категория
difficulty VARCHAR nullable
questions JSON nullable Вопросы и варианты
created_at DATETIME

progress (Progress)

Поле Тип Описание
id INTEGER PK
public_id UUID
user_id FK → users
module VARCHAR tutor / cases / exam (и др.)
score FLOAT nullable Балл
time_spent INTEGER nullable Секунды
completed_at DATETIME
extra_data JSON nullable Доп. метаданные

Миграции

Legacy: SQL/Python-файлы в app/db/migrations/ (001–031) — заморожены; применяются через run_migrations() после create_all при ALEMBIC_ENABLED=false.

Alembic (рекомендуется для prod): каталог alembic/, baseline 001_baseline. Включите ALEMBIC_ENABLED=true — тогда deploy.sh выполняет alembic upgrade headpg_advisory_lock на PostgreSQL) вместо create_all.

# Локально / в контейнере
docker compose exec app alembic upgrade head

# Или через deploy helper
python scripts/run_alembic_migrate.py

Генерация схемы

Просмотр моделей (пакет app/models/):

grep "^class " app/models/*.py

Индексы

  • patients(tenant_id, department_id)
  • documents(patient_id, status)
  • dicom_studies(patient_id, study_uid)
  • chat_sessions(user_id), chat_messages(session_id)
  • progress(user_id, module)

Анонимизация (researcher)

В access.py поля full_name, phone, email заменяются на P-{id} ANON при сериализации.