6.3 KiB
title
| title |
|---|
| Расписание врача и кеш слотов (Backend) |
Сценарий 2.2: Расписание и «кеш» слотов
Бизнес-цель
Пациенту показывают свободные интервалы записи к врачу в конкретном филиале и режиме (очный / онлайн). Чтобы не дёргать MIS на каждый запрос, backend хранит недавно полученное расписание и отдаёт его при повторных обращениях с теми же параметрами.
Важно для архитектуры: несмотря на название сервиса, данные кеша живут в PostgreSQL (таблица сущности Schedule), а не в Redis. Redis в этом сценарии не используется (см. ScheduleCacheService).
Точки входа
| Тип | Метод + URL | Класс |
|---|---|---|
| HTTP | GET /specialist/schedule?... |
SpecialistController::specialistSchedule |
| CLI | app:schedule:clear-cache |
ClearScheduleCacheCommand (очистка старых строк) |
Фактический вызов MIS выполняется внутри GetScheduleMessageHandler (см. schedule-messenger.md).
Параметры запроса расписания
Используется App\Dto\ScheduleDto:
st,en— границы времени (целые);dcode— код врача;filial— филиал (в query строка строится какfilialId);onlineMode— признак онлайн-расписания.
ScheduleDto::toQueryString() формирует строку для поиска в кеше и запроса к MIS (HTTP query).
Пошаговый алгоритм HTTP
- Контроллер наполняет DTO из query, валидирует.
SpecialistService::getSchedule($dto)диспатчитGetScheduleMessage(см. отдельную статью).- Хендлер сначала зовёт
ScheduleCacheService::getCachedSchedule($queryString, $isOnlineMode).
Логика ScheduleCacheService
TTL («как долго живёт кеш»)
Константа CACHE_TTL_MINUTES = 5.
getCachedSchedule:
- вычисляет порог
createdAt >= now - 5 minutes; ScheduleRepository::findByQueryModeAndTime($queryString, $isOnlineMode, $createdAfter);- если строк нет —
null(промах кеша).
То есть инвалидация по времени: записи старше 5 минут не считаются валидными для ответа.
Запись и перезапись
saveSchedule перед вставкой новых слотов вызывает removeByQueryStringAndMode: удаляет все записи кеша с тем же queryString и onlineMode. Это жёсткое обновление среза расписания под ключ запроса.
Каждый слот — строка Schedule с полями врача, отделения, даты, интервала, queryString, onlineMode, createdAt и др.
Ошибки чтения из БД
В getCachedSchedule перехват Exception → лог Error reading from cache → возврат null (как промах кеша, дальше пойдут в MIS).
Инвалидация / уборка
| Механизм | Описание |
|---|---|
| По TTL при чтении | старше 5 минут не отдаются |
saveSchedule |
удаление предыдущих строк с тем же ключом перед insert |
app:schedule:clear-cache --hours=N |
массовое удаление по createdAt < now - N hours через clearOldCache |
Опция --stats |
статистика по таблице без удаления |
ScheduleErrorHandlerService
Не часть кеша; вызывается из хендлера при ошибках HTTP-клиента или непойманных исключений: логирование и возврат массива с status_code, телом ответа MIS, длительностью и т.д. (см. schedule-messenger.md).
Mermaid
flowchart TD
A[GET /specialist/schedule] --> B[ScheduleDto + validate]
B --> C[SpecialistService.getSchedule]
C --> H[GetScheduleMessageHandler]
H --> D{Есть свежие Schedule строки?}
D -->|да ≤5 мин| R[reconstructFromDatabase → ответ cached]
D -->|нет| E[HTTP MIS intervals]
E --> S[saveSchedule: delete old + insert Schedule rows]
S --> R2[ответ api + _meta]
Внешние зависимости
| Система | Роль |
|---|---|
| PostgreSQL | хранение «кеша» Schedule |
| Инфоклиника (MIS) | источник расписания при промахе |
| Redis | не используется в этом сценарии по текущему коду |
Обработка ошибок и edge cases
- БД недоступна при чтении кеша — лог, ответ пойдёт в MIS; если и MIS недоступна — ошибка из хендлера.
- Пустой ответ MIS —
normalize/ пустые массивы зависят от клиента (см.InfoclinicaClientService). - Несогласованность
onlineModeв DTO: в контроллере в поле может попадать0|1из query — при строгой типизации возможны проблемы валидации (наблюдение для джуна при отладке).
Ссылки на классы
apps/backend/src/Controller/SpecialistController.php(specialistSchedule)apps/backend/src/Dto/ScheduleDto.phpapps/backend/src/Service/ScheduleCache/ScheduleCacheService.phpapps/backend/src/Repository/ScheduleRepository.phpapps/backend/src/Command/ClearScheduleCacheCommand.phpapps/backend/src/Service/ErrorHandler/ScheduleErrorHandlerService.php
Связанный сценарий Messenger: schedule-messenger.md.