Версия 1.6.0 — 2026-06-05

Версия 1.6.0 — 2026-06-05

Крупный релиз: голосовой ввод журналов, пользовательская документация прямо в админке, проектная документация для ИБ-офицера, фикс «всегда не заполнено» для УФ-журнала в обходе кабинетов.

Добавлено

Голосовой ввод журналов

Новая страница /page/voice-input-page — медсестра нажимает кнопку микрофона, диктует команду свободной речью, система распознаёт её, показывает черновик в виде таблицы и после подтверждения создаёт запись в нужном журнале.

Поддерживаемые журналы (в MVP):

Два движка распознавания речи (STT):

  1. Web Speech API (Google, в браузере) — для Chrome/Edge/Yandex. Бесплатно. Аудио не уходит с устройства.
  2. SaluteSpeech (SBER AI Cloud) — серверный fallback для Safari/iPad и кнопка-переключатель «Использовать серверное распознавание» при ошибке разрешения микрофона.

NLU (понимание текста → JSON):

  • GigaChat-2-Pro (SBER AI Cloud) — преобразует свободную речь в структурированную запись журнала. Системный промпт содержит список реальных кабинетов и справочников.

Защита от галлюцинаций LLM:

  • После парсинга резолвер сверяет cabinet_id с реальной таблицей.
  • Поля валидируются по схеме каждого журнала.
  • Дезсредства резолвятся по справочнику (включая нечёткое сопоставление: «алмадезом» → оба варианта по концентрации).
  • При несовпадении — уверенность снижается, в UI пометка «требует проверки».

Технические компоненты:

  • Сервисы: SaluteSpeechService, GigaChatService, VoiceCommandParser, VoiceCommandResolver, VoiceCommandExecutor.
  • Контроллер VoiceInputController с маршрутами /voice/transcribe, /voice/parse, /voice/commit, /voice/reject.
  • Таблица voice_drafts — буфер черновиков (для возврата, разбора ошибок, истории).
  • Право VoiceInputPage.viewAny — выдано super-admin при миграции.

На странице:

  • Свёрнутая плашка с примерами фраз для всех 3 журналов + подсказками по диктовке (числа, время, кабинеты, дезсредства).
  • Кнопка-микрофон с пульсирующей анимацией.
  • Поле распознанного текста (можно править руками).
  • Карточка черновика с таблицей разобранных полей на человеческом языке (например, «Время включения: 09:00», «Условия: В присутствии людей», «Объект обработки: Воздух»).
  • Сырой JSON оставлен под <details> для разработчика.

Пользовательская документация в админке

Новый пункт меню «Документация» (видят все авторизованные пользователи).

  • Источник — каталог docs/ в репозитории (рендерится на лету через league/commonmark).
  • Слева — навигация: Главное / Журналы / Справочники / Модули / Релизы.
  • Поиск по содержимому всей документации с подсветкой найденных слов, дебаунсом 200 мс, сортировкой по релевантности (топ-20 результатов).
  • Картинки скриншотов админки встроены в статьи — через симлинк public/docs-assets../docs/_assets.

Что в документации:

  • 5 корневых документов (обзор, роли, аудит, общие возможности).
  • 16 статей по каждому журналу (поля, фильтры, печать, ЭЦП, голосовой ввод).
  • 9 описаний справочников с двусторонними ссылками.
  • 7 описаний модулей (обход кабинетов, голосовой ввод, контроль заполнения, объявления MAX и др.).
  • Релизы (releases/) — история изменений.

Каталоги backlog/ и pd/ намеренно исключены — это внутренние материалы.

Скрипты сборки HTML-сайтов документации

  • scripts/build-docs.php — генерирует автономный HTML-сайт пользовательской документации в docs/_html/ (стиль с фирменным градиентом, можно открыть локально без сервера).
  • scripts/build-pd.php — генерирует сайт проектной документации в pd/_html/ (более строгий стиль для ИБ-офицера).
  • scripts/screenshot-admin.py — Playwright-скрипт, делающий скриншоты 20 ключевых экранов админки (логинится автоматически, прячет debugbar).

Проектная документация (ПД) для проработки ИБ/ПДн

Каталог pd/ — техническая база информационной системы в формате ПД (12 разделов: глоссарий, назначение, архитектура, стек, потоки данных, категории ПДн, внешние интеграции, RBAC, хранение, развёртывание, история изменений, открытые вопросы).

Документ предназначен для ИБ-офицера как исходные данные перед разработкой модели угроз и требований по защите ПДн.

Исправлено

Обход кабинетов: «всегда не заполнено» из-за УФ-журнала

В обходе кабинетов плитки кабинетов постоянно показывались как «к заполнению», даже когда фактически все обязательные журналы за день были закрыты.

Причина: метод CabinetJournalDailyStatus::computeUv() для пустого дня (нет сеансов УФ) возвращал статус TODO. На странице обхода TODO интерпретируется как «надо заполнить» → пустая плитка УФ-журнала тянула за собой статус всего кабинета.

Но УФ-обеззараживание — не ежедневная процедура: в большинстве кабинетов сеансы делаются по событию или по графику, не каждый день. Постоянное «не заполнено» дезориентировало пользователей.

Фикс: для дня без сеансов УФ статус теперь EVENT_BASED («Сеансов нет»). На странице обхода EVENT_BASED исключается из подсчёта обязательных журналов, поэтому пустой день УФ больше не тянет статус кабинета. Если же есть начатый и не закрытый сеанс — статус по-прежнему PARTIAL («Не указано время выключения»). Аналогичная логика уже была в slotsUv() (для контроля заполнения главной медсестры) — теперь приведено к консистентности.

Технические детали

  • Версия в config/journals.php: 1.5.1 → 1.6.0.
  • Зависимости: league/commonmark (уже был в vendor/), Playwright (для скриптов скриншотов — устанавливается отдельно через pip в venv).
  • Симлинк public/docs-assets → ../docs/_assets коммитится в репозиторий — на проде нужно убедиться, что симлинк создаётся / используется альтернативный способ.

Миграции

Релиз требует php artisan migrate:

  • 2026_06_02_103013_create_voice_drafts_and_permission — таблица voice_drafts для черновиков голосового ввода + право VoiceInputPage.viewAny.

Что НЕ вошло (отложено на следующий релиз)

  • Голосовой ввод для журнала холодильников, генеральных уборок и других — сложный UX (несколько холодильников на кабинет, выбор «план» vs «факт»).
  • Webhook MAX-бота и приём голосовых сообщений из MAX-чата (этап 2 из backlog/voice-input.md).
  • Привязка max_chat_id к пользователям и личные пинги в MAX (этап 2 из backlog/notifications.md).

Открытые вопросы

См. pd/12-open-questions-for-cybersec.md — 40+ пунктов, требующих решения с ИБ-офицером и юридической службой до промышленного запуска голосового ввода (особенно в части обработки ПДн пациентов через SBER AI Cloud).