Files
docs/data-model.md
T

12 KiB
Raw Blame History

Модели данных

Эта страница описывает основные сущности, найденные в apps/backend/src/Entity и apps/cabinet/src/Entity. В проектах есть много справочных полей; ниже выделены доменные ядра и связи, которые важны для понимания системы.

Backend ER-схема

erDiagram
  SPECIALIST ||--o{ LOCATION : "id -> specialist_id"
  SPECIALIST ||--o{ REVIEW : "id -> specialist_id"
  SPECIALIST ||--o{ SPECIALIST_DOCS : "id -> specialist_id"
  SPECIALIST ||--o{ SPECIALIST_DCODE_DESCRIPTION : "id -> specialist_id"
  SPECIALIST }o--o{ STOCK : "join table"
  RECORD ||--o| ALERT_SMS : "id -> record_id"
  WIDGET_FORM ||--o{ WIDGET_FORM_INPUT : "id -> widget_form_id"

  SPECIALIST {
    int id PK
    string name
    string alias
    int region_id
    string post
    string experience
    bool active
    bool display_schedule
    jsonb dcodes
  }

  LOCATION {
    bigint id PK
    int specialist_id FK
    bigint dcode
    bigint department
    int filial
    bool online_mode
    date nearest_date
  }

  REVIEW {
    int id PK
    int specialist_id FK
    bool active
    date date_create
    string author
    float rating
    string source
    int external_id
  }

  SPECIALIST_DOCS {
    int id PK
    int specialist_id FK
    string name
    string picture
    bool active
    string type
  }

  SPECIALIST_DCODE_DESCRIPTION {
    int id PK
    int specialist_id FK
    bigint dcode
    bigint department
    text content
  }

  STOCK {
    int id PK
    string name
    text content
    date start_date
    date end_date
  }

  RECORD {
    int id PK
    int specialist_id
    string phone
    datetime create_at
    string hash
    json reserve
  }

  ALERT_SMS {
    int id PK
    int record_id FK
    datetime date_create
    text response
  }

  WIDGET_FORM {
    int id PK
    string name
  }

  WIDGET_FORM_INPUT {
    int id PK
    int widget_form_id FK
    string text
    string type
    string bitrix24_id
    int sort
  }

Backend: перевод сущностей

Сущность на диаграмме Русское название Смысл
SPECIALIST Врач Карточка врача в новом API
LOCATION Локация приема Привязка врача к отделению, филиалу и режиму приема
REVIEW Отзыв Отзыв о враче
SPECIALIST_DOCS Документ врача Сертификат/документ/изображение врача
SPECIALIST_DCODE_DESCRIPTION Описание врача по dcode Текстовое описание для конкретного кода врача/отделения
STOCK Акция Акция, связанная с врачами через ManyToMany
RECORD Запись пациента Локальная запись факта бронирования
ALERT_SMS SMS-уведомление Ответ SMS-провайдера по записи
WIDGET_FORM Форма виджета Конструктор формы
WIDGET_FORM_INPUT Поле формы Поле формы виджета

Backend: ключи связей

Связь Тип Ключи
Врач -> Локация приема OneToMany / ManyToOne specialist.id = location.specialist_id
Врач -> Отзыв OneToMany / ManyToOne specialist.id = review.specialist_id
Врач -> Документ врача OneToMany / ManyToOne Doctrine создает specialist_docs.specialist_id -> specialist.id
Врач -> Описание по dcode ManyToOne на стороне описания specialist_dcode_description.specialist_id -> specialist.id
Врач <-> Акция ManyToMany join-таблица генерируется Doctrine; владелец связи Stock::$specialist
Запись -> SMS-уведомление OneToOne Doctrine создает alert_sms.record_id -> record.id
Форма виджета -> Поле формы OneToMany / ManyToOne Doctrine создает widget_form_input.widget_form_id -> widget_form.id

Record.specialistId в backend не является Doctrine-связью с Specialist: это логический внешний идентификатор врача, сохраненный как число.

Backend справочники и контент

classDiagram
  class Department {
    id
    did
    name
    groupName
    onlineMode
    alias
    active
  }

  class Filial {
    id
    fid
    name
    address
    regionId
    siteId
    company
    phone
    email
  }

  class PriceDepartment {
    id
    name
    groupId
    doctCount
    viewInWeb
  }

  class PriceList {
    id
    kodoper
    schname
    specname
    speccode
    priceInfo
    discprice
    filial
    groupId
  }

  class SiteService {
    id
    name
    alias
    regionId
    anons
    content
    faq
    tags
    clinics
  }

  class Disease {
    id
    name
    alias
    regionId
    symptom
    content
    tags
    staffList
  }

  class MedicalCenter {
    id
    name
    alias
    regionId
    doctors
    services
    content
  }

  class Article {
    id
    name
    alias
    doctors
    services
    content
  }

  class News {
    id
    name
    alias
    regionId
    content
    photos
  }

  class Promo {
    id
    name
    alias
    regionId
    clinics
    period
  }

Cabinet ER-схема

erDiagram
  CITY ||--o{ FILIAL : "id -> city_id"
  CITY ||--o{ REVIEW_SOURCE : "id -> city_id"
  CITY ||--o| BANNER : "id -> city_id"
  FILIAL ||--o{ REVIEW_SOURCE : "id -> filial_id"
  CATEGORY_PAGE ||--o{ PAGE : "id -> category_id"
  RECORD ||--o| ALERT_SMS : "id -> record_id"
  WIDGET_FORM ||--o{ WIDGET_FORM_INPUT : "id -> widget_form_id"

  CITY {
    int id PK
    string name
    int region_id
    int time_zone
  }

  FILIAL {
    int id PK
    int city_id FK
    int fid
    string name
    string address
    int site_id
    bool active
    string company
  }

  REVIEW_SOURCE {
    int id PK
    int city_id FK
    int filial_id FK
    string name
    int count_row
    bool active
    float rating
    date date_create
  }

  BANNER {
    int id PK
    int city_id FK
    string href
    string src
    bool active
  }

  CATEGORY_PAGE {
    int id PK
    string name
    bool active
  }

  PAGE {
    int id PK
    int category_id FK
    string name
    string alias
    text description
    bool active
  }

  RECORD {
    int id PK
    int specialist_id
    string phone
    datetime create_at
    string hash
    json reserve
  }

  ALERT_SMS {
    int id PK
    int record_id FK
    datetime date_create
    text response
  }

  WIDGET_FORM {
    int id PK
    string name
  }

  WIDGET_FORM_INPUT {
    int id PK
    int widget_form_id FK
    string text
    string type
    string bitrix24_id
    int sort
  }

Cabinet: перевод сущностей

Сущность на диаграмме Русское название Смысл
CITY Город Региональная привязка кабинета
FILIAL Филиал Клиника/филиал, привязанный к городу
REVIEW_SOURCE Источник отзывов Внешний источник рейтинга/отзывов по городу или филиалу
BANNER Баннер Региональный баннер
CATEGORY_PAGE Категория страниц Группа CMS-страниц
PAGE Страница CMS-страница
RECORD Запись пациента Локальная запись факта бронирования
ALERT_SMS SMS-уведомление Ответ SMS-провайдера по записи
WIDGET_FORM Форма виджета Конструктор формы
WIDGET_FORM_INPUT Поле формы Поле формы виджета

Cabinet: ключи связей

Связь Тип Ключи
Город -> Филиал OneToMany / ManyToOne Doctrine создает filial.city_id -> city.id
Город -> Источник отзывов OneToMany / ManyToOne Doctrine создает review_source.city_id -> city.id, nullable=false
Город -> Баннер OneToOne Doctrine создает banner.city_id -> city.id
Филиал -> Источник отзывов OneToMany / ManyToOne Doctrine создает review_source.filial_id -> filial.id
Категория страниц -> Страница OneToMany / ManyToOne Doctrine создает page.category_id -> category_page.id, nullable=false
Запись -> SMS-уведомление OneToOne Doctrine создает alert_sms.record_id -> record.id
Форма виджета -> Поле формы OneToMany / ManyToOne Doctrine создает widget_form_input.widget_form_id -> widget_form.id

Record.specialistId, SpecialistView.dcode, LocationView.specialistId, PriceList.filial, PriceList.groupId, PriceList.kodoper в cabinet используются как логические внешние ключи и фильтры, но не оформлены как Doctrine relations.

Cabinet представления и справочники

classDiagram
  class SpecialistView {
    id
    name
    speciality
    category
    experience
    description
    alias
    dcode
    regionId
    kodoper
    acceptsDms
  }

  class LocationView {
    id
    dcode
    department
    filial
    specialistId
    onlineMode
    active
    nearestDate
  }

  class PriceDepartment {
    id
    name
    groupId
    groupName
    doctCount
    viewInWeb
  }

  class PriceList {
    id
    kodoper
    schname
    specname
    speccode
    priceInfo
    discprice
    filial
    groupId
  }

  class User {
    id
    email
    roles
    uid
    token
    fullName
    phone
    confirm
    createdAt
    lastActivityAt
  }

  class Usrlog {
    id
    pcode
    agent
    clientIp
    method
    createdAt
  }

  class DirectCompany {
    id
    name
    companyId
    city
  }

  class DirectReport {
    id
    date
    adGroupId
    campaignId
    adId
    impressions
    clicks
    cost
    conversions
  }

Общие доменные понятия

  • Specialist / SpecialistView - врач. В backend это полноценная сущность с явными связями; в cabinet это view-модель для чтения.
  • Location / LocationView - где и как врач принимает.
  • PriceList и PriceDepartment - прайс и группы услуг.
  • Record - запись пациента, хранит payload бронирования в reserve.
  • AlertSms - SMS-уведомление по записи.
  • Filial и Department - филиалы и отделения.
  • Review и ReviewSource - отзывы и источники отзывов.
  • WidgetForm и WidgetFormInput - динамические формы для виджетов.

Особенности модели

  • В backend используются PHP attributes Doctrine, в cabinet - annotations.
  • Часть связей хранится не как Doctrine relation, а как внешние идентификаторы (dcode, fid, did, regionId, groupId, kodoper). Это важно: не все связи можно увидеть по ManyToOne.
  • backend подключается к нескольким источникам данных: основной PostgreSQL, Bitrix MySQL и базе cabinet.
  • cabinet содержит view-сущности (SpecialistView, LocationView), поэтому часть данных, вероятно, приходит из SQL views или синхронизированных таблиц.