Files
docs/apps/online-consultation.md
T

9.3 KiB
Raw Permalink Blame History

title
title
Онлайн-консультация в личном кабинете

Онлайн-консультация (cabinet)

Как устроена запись на онлайн-приём в apps/cabinet: маршруты, MIS/Widget API, оплата и видеоконференция. Связано с расписанием врачей.


TL;DR

Этап Где Внешний ресурс
Список онлайн-врачей GET /online-specialists (нужен login) PostgreSQL location_view (online_mode=true)
Слоты GET /api/interval?onlineMode=1 MISwidget.sovamed.ru
Запись webSDK.scheduleRecReserve({ onlineType: 1 }) Infoclinica SDK в браузере
Оплата / видео /case-history webSDK.loadPaymentView, openConference

Cron upload:doctors 1 (backend) обновляет ближайшие даты для онлайн-локаций, не сами слоты.


1. Маршруты

URL Auth Назначение
/online-specialists ROLE_USER Список врачей с онлайн-локациями
/specialists публичный Очный приём (onlineMode=0)
/api/interval публичный Прокси расписания в MIS
/case-history ROLE_USER Записи, оплата, «Онлайн приём», возврат
/refund ROLE_USER Форма возврата

Код: SpecialistController.php, PublicAPIController.php, SecurityController.php.


2. Поток данных

sequenceDiagram
    participant User as Пользователь ЛК
    participant Cab as cabinet
    participant MIS as widget.sovamed.ru
    participant SDK as webSDK браузер

    User->>Cab: GET /online-specialists
    Cab->>Cab: location_view online_mode=1
    User->>Cab: GET /api/interval onlineMode=1
    Cab->>MIS: /api/reservation/schedule + /intervals
    MIS-->>Cab: intervalsData
    User->>SDK: scheduleRecReserve onlineType=1
    User->>Cab: GET /case-history
    Cab->>SDK: records, payment, conference

3. Отличия online vs offline

Offline Online
Список /specialists /online-specialists + login
onlineMode в API 0 1
Анонимная запись да (/api/anonymous-reserve) нет
Согласия PD PD + оферта + ИДС
После записи #doctor-success #online + предупреждение об оплате 5 мин
Оплата / видео /case-history

4. Типичные причины поломки

4.1. Пустой список /online-specialists

  • Нет строк в location_view с online_mode = true (cron upload:doctors 1 + update_location()).
  • Врач не привязан к MIS (dcode, department, filial).

Проверка: SQL SELECT * FROM location_view WHERE online_mode = true;

4.2. Нет слотов на карточке

  • MIS недоступен (MIS env, widget.sovamed.ru).
  • Неверный filial/department для онлайн-режима.
  • GET /api/interval?onlineMode=1 возвращает 5xx.

Проверка: curl "https://widget.sovamed.ru/specialists/departments" и /api/interval с prod.

4.3. Запись создаётся как очная

  • Баг нормализации onlineMode в JS/PHP (исправлено: OnlineMode, onlineMode.js).
  • В scheduleRecReserve уходит onlineType: 0 вместо 1.

4.4. Фильтр на онлайн-странице уводит на /specialists

  • Форма поиска post'ила на specialist_index (исправлено → specialist_online_index).

4.5. Оплата / видео не работает

  • Не загружен SDK (loader.jswidget.sovamed.ru/.../sdk.build.min.js).
  • Запись не оплачена в течение 5 мин (MIS отменяет).
  • webSDK.openConference — вне окна времени приёма.

4.6. Авторизация внутри iframe (#iframeProtocol) — не должна появляться

Симптом: пользователь уже в ЛК, но в модальном окне «Онлайн приём» или «Оплата» внутри iframe просят войти снова.

Причина: две независимые сессии:

Сессия Где хранится За что отвечает
Symfony (ROLE_USER) cookie cabinet.sovamed.ru /case-history, /online-specialists
MIS / webSDK cookie widget.sovamed.ru + скрытый iframe /sdk openConference, loadPaymentView, scheduleRecReserve

Symfony может быть активна, а MIS — нет (истёк timeout, другой браузер, блокировка third-party cookies).

Где iframe:

Действие Метод SDK Элемент
«Онлайн приём» openConference() #iframeProtocol — URL видеоконференции
Вход через Госуслуги loadLoginView() #iframeProtocolожидаемо показывает login
Оплата loadPaymentView() виджет ЮKassa в #popup-body (не login-iframe)

Исправление в коде (cabinet):

  • assets/components/misSession.js — проверка webSDK.data.user.authenticated / isLoggedIn() перед оплатой и конференцией.
  • caseHistory_controller.jsopenConference без container (DOM-элемент ломал SDK eval(container) и пропускал Guest URL); iframe переносится в popup через mountConferenceInPopup().
  • При протухшей MIS-сессии — popup «Войти снова» → /logout, а не форма login внутри iframe.

Проверка в браузере (prod):

// на /case-history, до клика «Онлайн приём»
window.webSDK?.data?.user?.authenticated   // должно быть true
# Symfony-сессия (smoke-скрипт)
curl -b cookies.txt https://cabinet.sovamed.ru/api/userInfo
# → {"data":"<uid>"}  — это НЕ гарантия MIS-сессии

Smoke:

make local-online-smoke
# шаги 9–10: UI-маркеры case-history, /api/userInfo, доступность MIS SDK

4.7. MIS / Infoclinica

Env: MIS=https://widget.sovamed.ru в apps/cabinet/.env.

Публичный DNS: CNAME production.infoclinica.ru217.74.42.159 (не путать с внутренними IP вроде 10.34.23.239).


5. Тесты

Shell smoke (Docker local)

make local-up
make local-online-smoke

Скрипт: scripts/online-consultation-smoke.sh

Pytest e2e

./scripts/run-online-consultation-pytest.sh

Каталог: tests/e2e/online_consultation/

PHPUnit (cabinet)

make cabinet-test
# или
docker exec php82-local php bin/phpunit tests/Unit tests/Controller
  • tests/Unit/Support/OnlineModeTest.php — нормализация 0/1/true/false
  • tests/Controller/OnlineSpecialistsControllerTest.php — auth на /online-specialists

6. Чеклист диагностики на prod

  1. Пользователь залогинен? /online-specialists без login → redirect.
  2. Есть онлайн-локации в БД? location_view.online_mode = true.
  3. docker exec php84 php bin/console upload:doctors 1 — без ошибок?
  4. /api/interval?...&onlineMode=1 — HTTP 200 и intervalsData?
  5. В браузере загружен webSDK? Console → нет 404 на sdk.build.min.js.
  6. /case-history — запись с onlineType, статус оплаты?
  7. До «Онлайн приём»: window.webSDK.data.user.authenticated === true? Если false — MIS-сессия протухла (см. §4.6).
  8. Iframe #iframeProtocol: src — URL конференции, а не /login?

7. Ключевые файлы

Файл Роль
src/Controller/SpecialistController.php /online-specialists
src/Controller/PublicAPIController.php /api/interval
src/Repository/SpecialistViewRepository.php фильтр onlineMode
src/Support/OnlineMode.php нормализация флага
assets/components/record.js запись, onlineType
assets/components/misSession.js проверка MIS-сессии, mount iframe конференции
assets/controllers/caseHistory_controller.js оплата, конференция
assets/components/loader.js загрузка SDK
templates/specialist/_item.html.twig карточка врача