diff --git a/MEETING_2026-04-23.md b/MEETING_2026-04-23.md new file mode 100644 index 0000000..9a8e670 --- /dev/null +++ b/MEETING_2026-04-23.md @@ -0,0 +1,285 @@ +# Приоритеты развития мобильного приложения — встреча 23 апр 2026 + +Клиника УГН (ЛОР, сурдология, аллергология, хирургия). Цель встречи — определить порядок развития функций: что закрываем как базу для всех пациентов, какие сегменты углубляем и в каком порядке. + +## 1. Контекст и критерии приоритизации + +**Текущие функции:** список врачей, запись на приём, ближайший приём, чат с оператором, профиль, семейный профиль, контакты. + +### Ключевые факты о потоке + +- **2 из 3 пациентов клиники — повторные.** Значительная доля — **повторные внутри одного лечения**: после первого визита (острое заболевание или обострение хронического) ещё 1–3+ приёма, процедуры, контроль. +- **Бизнес-сегментация (из аналитики клиники)** — 10 сегментов, лидеры по выручке: амбулаторный поток (~120 млн), взрослая хирургия «заблокированный нос» (~30 млн), детская аденоидная хирургия (~20–30 млн), сурдология (~20 млн). + +### Продуктовая логика: что делает приложение + +**Приложение — инструмент удержания и углубления, а не привлечения.** Первичного пациента клиника получает через сайт, SEO, рекламу, сарафан. Приложение устанавливают уже пришедшие — в момент записи или на первом визите. Поэтому приоритет развития — **повторные во всех сегментах**. + +Это совпадает с фактом «2 из 3 — повторные» и означает, что: +- **Первичные сценарии в приложении** закрываются универсальным минимумом (запись + контакты + цены + AI-помощник, который знает услуги). Нет смысла строить специализированные первичные потоки для каждого из 10 сегментов. +- **Повторные сценарии** — специфичны по сегменту и требуют отдельных модулей (бегунок, аудиограмма, АСИТ-дневник и т.п.). +- **Исключения** — сегменты, где «первичный в приложении» ≠ «первый визит»: после первого визита пациент уходит, и вернуть его в клинику может только приложение. + - **Сурдология** — после визита и демо пациент уходит думать 2–3 месяца о покупке аппарата. + - **Хирургия (FESS, детские аденоиды, вазотомия)** — после пред-операционного приёма у хирурга пациент часто уходит **думать, решаться ли на операцию вообще**. Эти «сомневающиеся» — отдельная работа по возврату. Вторая часть — те, кто решился, уходят в 6-недельную подготовку (бегунок). + - **АСИТ** — после назначения впереди 3–5-летний курс, есть сценарии «не начал» и «бросил в первые месяцы». + +### Три слоя работы + +1. **Фаза 1 · Транзакционная база** — детерминированные функции для любого пациента: запись, ближайший приём, чат с оператором, **план лечения, результаты/медкарта, заказ справок**. Без LLM и прямого чата с врачом. Минимум рисков, быстрый запуск. +2. **Фаза 1.5 · Коммуникационная надстройка** — чат с медицинским консьержем (дежурным врачом/фельдшером) и AI-помощник в shadow-mode. Отделено от Фазы 1, чтобы регламенты и безопасность не задерживали релиз базы. +3. **Фаза 2 · Сегментные модули** — углубление по приоритетным группам сегментов (A → C → B → D). + +### Критерии приоритета + +| Критерий | Что меряем | +|---|---| +| **Охват** | Сколько пациентов клиники затронуто (в абсолюте) | +| **Глубина пользы** | Насколько закрывает реальную боль (есть ли альтернатива без нас) | +| **Частота касаний** | Как часто функция возвращает пользователя в приложение | +| **Бизнес-эффект** | Влияние на возвратность, средний чек, удержание, вклад в выручку | +| **Сложность** | Вторичная ось: усилия (вкл. зависимости от МИС и контента) | + +--- + +## 2. Текущие функции — утилита и приоритет + +### 🟢 Высокий приоритет (ядро ценности) + +**Запись на приём** — главный транзакционный поток. Экономит 3–8 минут разговора, 24/7, ближайшие окна. Единственная функция, которая приводит новых пациентов через приложение. Усилить: запись из плана лечения в 1 клик (§3), запись из маршрутной карты пред-опа (§4). + +**Ближайший приём** — «что со мной сейчас». Снимает тревогу «когда, куда, к кому». Перед визитом открывается 3–10 раз. Усилить: чек-лист подготовки, маршрут до кабинета, тригеры 24ч/2ч/15мин. + +### 🟡 Средний приоритет (поддержка) + +**Список врачей / карточка врача** — инструмент выбора при первом визите. Повторный пациент почти не открывает. Усилить: соцдоказательства, фильтр «по моему диагнозу». + +**Чат с оператором** — замена звонка в регистратуру. Ограничен одним собеседником. Основное развитие — в §3. + +**Профиль** — точка идентификации. Редко открывается, но критичен для персонализации. + +### 🔴 Низкий приоритет (ниша) + +**Семейный профиль** — высокая польза для 20–30% (родители с детьми, взрослые с пожилыми), становится критичным для сегмента «дети с аденоидами» и «сложные хроники — ЧБД». + +**Контакты** — функция «галочка», 1–2 открытия за всё время. + +### Вывод + +Ядро «Запись + Ближайший приём» работает. Слабое место — **нет причины открывать приложение между визитами**. Это и закрывает джентльменский набор. + +--- + +## 3. Джентльменский набор — базовые функции для всех пациентов + +Минимум, который должен быть у любого пациента клиники, вне зависимости от диагноза и сегмента. **Приоритет до любых сегментных модулей.** + +Набор сознательно разделён на две подфазы по риску и зависимостям: **транзакционная база** (детерминированные функции с понятным MVP) и **коммуникационная надстройка** (LLM и асинхронные каналы, требующие регламентов и безопасности). Это позволяет выпустить базу быстро и безопасно, а надстройку строить поверх уже стабильного фундамента. + +### Фаза 1 · Транзакционная база + +Функции, где пациент **что-то получает или делает** — без LLM и без диалога. Минимизируют риски, быстрее в запуск, дают те самые «не удалю это приложение»-причины. + +| Функция | Статус | Что в ней | +|---|---|---| +| Запись на приём | ✅ есть | Запись 24/7, ближайшие окна. | +| Ближайший приём | ✅ есть | Что, где, когда — снимает тревогу перед визитом. | +| Чат с оператором | ✅ есть | Справки, переносы, счета, расписание (человеческий канал). | +| Статьи / база знаний | ✅ есть (Спринт 1) | Уже есть. Источник правды для будущего RAG. | +| **План лечения с приёма** | ❌ нет — фундамент | После каждого приёма структурированный чеклист: диагноз, назначения (препарат + доза + курс + календарь), ссылки на процедуры самопомощи (Группа A), контрольный приём, запись на следующий визит в 1 клик. Живой объект с напоминаниями. Источник правды для всех следующих надстроек. | +| **Результаты обследований и медкарта** | ❌ нет | Пациент видит свои анализы, аудиограммы, снимки, заключения **без звонка в клинику**. Статус каждого результата: готов / в работе / годен до [дата]. Критично для Группы C (пред-оп): срок годности анализов виден в одном месте. | +| **Заказ справок и финансовых документов** | ❌ нет | Справка для налогового вычета (13%), справки работодателю, копии заключений, счета. Заказ в 1 клик, готовая в приложении или с самовывозом. Снимает нагрузку с администраторов и даёт сильный retention-якорь даже у разовых пациентов. | + +### Фаза 1.5 · Коммуникационная надстройка + +Функции, где идёт **живой или AI-диалог** по поводу лечения. Строятся поверх уже работающей базы (плана лечения, медкарты, статей) и требуют отдельных регламентов — по ответственности, SLA, проверке качества. + +| Функция | Статус | Что в ней | Ключевой риск | +|---|---|---|---| +| **Чат с медицинским консьержем** | ❌ нет | **Не прямой чат с лечащим врачом.** Дежурный врач / фельдшер / медсестра отвечает по протоколам на 80% рутины («можно ли совмещать с X», «нормально ли, что третий день болит», «когда повторно сдать анализ»), эскалирует клинически значимое лечащему. Асинхронно, SLA — X часов в рабочее время. | Перегрузка врачей и SLA-хаос, если пустить пациентов напрямую к хирургу. Консьерж-слой — основной буфер. Нужен регламент тарификации/компенсации врачам за эскалированные вопросы. | +| **AI-помощник (RAG 24/7)** | ❌ нет | Знает базу знаний клиники, статьи, план лечения пациента, историю приёмов. Объясняет назначение, ищет ответ в статьях, оценивает «норма или срочно» и эскалирует к консьержу/врачу при тревожных признаках. | Галлюцинация LLM в медицинском контексте = юридический и репутационный риск. **Запускаем в shadow-mode**: ответы сначала идут через консьержа для валидации, метрики точности собираются, и только после набора статистики — переход в прямой режим для безопасных категорий вопросов. | + +### Почему это ядро, а не сегмент + +- **Работает на 100% пациентов** — без разделения по сегменту. +- **Усиливает любое сегментное направление**: бегунок, слухопротезирование, АСИТ — всё опирается на план лечения, медкарту и тот же чат-канал. +- **Закрывает главный пробел транзакционной модели** — «что делать между визитами». +- **Частично закрывает самый массовый сегмент** (амбулаторный + хроники). Полностью закрыть их может только отдельный модуль «Процедуры самопомощи» (Группа A, §4.3) — это первый сегментный модуль после Фазы 1.5. + +### Порядок работ внутри набора + +**Фаза 1:** +1. **План лечения с приёма** — фундамент. Без структурированных назначений не работает ничего поверх (ни AI, ни напоминания, ни процедуры самопомощи). +2. **Результаты / медкарта** — следующий retention-якорь. +3. **Заказ справок** — быстрый win для большой части пациентов, снимает нагрузку с администраторов. + +**Фаза 1.5** (после стабилизации Фазы 1): +4. **Чат с медицинским консьержем** — инфраструктура канала + регламент ответов. +5. **AI-помощник на RAG (shadow-mode)** — сначала ответы валидируются консьержем, потом постепенный переход в прямой режим для безопасных категорий. + +### Критическая зависимость от МИС + +«План лечения» — это структурированные данные (препарат, доза, частота, курс, процедура). Два сценария: +- **МИС отдаёт назначения по API структурированно** — план лечения собирается автоматически из данных приёма. Предпочтительно. +- **МИС отдаёт только PDF-заключение** — план лечения MVP стартует с **ручного ввода врачом в виджет** (шаблоны по нозологиям + чеклисты + автоподстановка из предыдущего приёма). Интеграция с МИС — отдельной задачей позже. + +Ответ на этот вопрос определяет сроки и стоимость Фазы 1. Добавлен в §6 как первоочередной. + +--- + +## 4. Сегменты пациентов через призму приложения + +### 4.1. Фундаментальное деление: первичный vs повторный + +| Линза | Первичный в приложении | Повторный в приложении | +|---|---|---| +| **Главный job** | «Куда мне обратиться и как записаться» | «Что мне делать сейчас по моему лечению» | +| **Источник** | Попадает через сайт/рекламу/сарафан | Приложение уже установлено, уведомление/сам открывает | +| **Частота открытия** | 1–3 раза до визита | Ежедневно в активном эпизоде | +| **Что нужно в приложении** | Базовый минимум (запись, цены, контакты, врачи) | Специализированный модуль сегмента | +| **Приоритет развития** | Низкий (веб и реклама работают лучше) | ● Высокий (2/3 потока) | + +**Ключевое следствие.** Специализированных «первичных» модулей под каждый сегмент строить не нужно. Исключения — сегменты, где «после первого визита» начинается длинный путь: сурдология, хирургия, АСИТ. Там «первичный» в терминах клиники ≠ «первичный» в терминах приложения. + +### 4.2. Матрица 10 сегментов × первичный / повторный + +Из 10 сегментов бизнес-аналитики выделяем: объём × чек × что нужно в приложении для первичного × что нужно для повторного × итоговый приоритет приложения. + +| # | Сегмент (из аналитики) | Объём / Вклад | Первичный в приложении | Повторный в приложении (главная работа) | Приоритет в App | +|---|---|---|---|---|:-:| +| 1 | **Взрослые «заблокированный нос»** (полипы, перегородка, FESS) | 300 оп/год · 100т · 30 млн | Джентльменский + материалы о методах (FESS/лазер), кейсы пациентов, калькулятор, **возвратные push для сомневающихся после пред-оп приёма** | Пред-оп бегунок (6 нед) → восстановление → контроль 3/6/12 мес | ● **Высокий** (Группа C) | +| 2 | **Амбулаторный поток** (острые и хроники ЛОР) | Тысячи/мес · 120 млн | Джентльменский | План лечения + эпизод лечения + дневник симптомов (§3) **+ модуль процедур самопомощи: библиотека техник (промывание носа физраствором, полоскание горла, ингаляции), напоминания, трекер комплаенса** | ● **Высший** (Группа A — отдельный модуль) | +| 3 | **Родители детей с аденоидами** | 400–500 оп/год · 60т · 20–30 млн | Джентльменский + семейный профиль + подготовка ребёнка + **материалы «нужна ли операция» и возврат сомневающихся родителей** | Пред-оп бегунок (детская версия) → восстановление. Далее — редко. | ● **Высокий** (Группа C) | +| 4 | **Потеря слуха (сурдология)** | 20 млн/год | **Нестандартный первичный:** аудиограмма в профиле, аудио-демо, каталог моделей, калькулятор, шеринг близкому, возвратные push | Паспорт аппарата, сервисный календарь, расходники, калибровка раз в год, дневник адаптации | ● **Высокий** (Группа B — уникальный модуль) | +| 5 | **Сложные хроники** (иммунология/аллергология, ЧБД) | Высокий, часть 120 млн · длинный LTV | Джентльменский + семейный (ЧБД) + запись на консилиум | Модуль процедур самопомощи (Группа A): промывания, полоскания, ингаляции у ЧБД. Плюс специализация: **АСИТ-трекер** (дневник симптомов + пыльцевой календарь + навигатор побочки) | ● **Высокий** (Группа A + Группа D) | +| 6 | **Зависимость от капель (вазотомия)** | Высокий объём · входной в хирургию | Джентльменский + материалы «как слезть с капель» + **возврат сомневающихся после пред-оп приёма** | Пред-оп бегунок (компактная версия) → восстановление | ● **Высокий** (Группа C) | +| 7 | **Пульмонология** (кашель/астма) | Средний · сезонный | Джентльменский | Дневник астмы, напоминания об ингаляторах, контроль триггеров (пересекается с АСИТ) | ◐ **Средний** (частично Группа D) | +| 8 | **Социально активные храпуны** | Низкий · высокая платёжеспособность | Джентльменский + образовательный контент о сомнологии | Сомнологический чек-up, СИПАП-трекер (если назначен) | ○ **Низкий** | +| 9 | **Фониатрия** (голос) | Очень низкий · срочный | Джентльменский + срочная запись | Короткое окно, низкая повторность | ○ **Низкий** | +| 10 | **Check-up и Второе мнение** | Единичный · высокая маржа | Джентльменский + позиционирование бренда Оленевой | Разовая услуга, минимальная повторность | ○ **Низкий** | + +### 4.3. Четыре группы сегментов для повторных + +**Группа A. Амбулаторный поток + хроники — процедуры самопомощи** — сегменты 2 + 5 (повторная часть). Самый массовый сегмент × ежедневная повторность. + +Джентльменский набор (план лечения + чат с врачом + AI) закрывает коммуникацию и напоминания, **но не закрывает саму регулярную работу пациента между приёмами**: +- Промывание носа физраствором (при хр. рините, синусите, после операций) +- Полоскание горла (при хр. тонзиллите) +- Ингаляции +- Гимнастика слуховой трубы (при евстахиите) +- Голосовые упражнения (фониатрия) +- Туалет уха (при хр. отите) + +**Что нужно в модуле:** +- **Библиотека техник** — короткие видео и пошаговые инструкции «как правильно». Ошибки в технике (сильный напор при промывании, не тот раствор) — частая причина, почему «не помогает». +- **Напоминания** — утро/вечер по схеме, привязаны к плану лечения. +- **Трекер комплаенса** — ежедневные отметки, стрики, сводка «сколько дней подряд». +- **Дневник симптомов в связке** — «промываю 5 дней, насморк уменьшился с 4 до 2» — главный мотиватор продолжать. +- **Сводка для врача** — перед контрольным приёмом врач видит, что пациент делал, как часто, с какой динамикой симптомов. + +**Это отдельный модуль, не продолжение Фазы 1.** Он опирается на план лечения как на источник назначений, но требует собственного контента (библиотека техник) и UX (трекер). + +**Группа B. Сурдология** — сегмент 4. Уникальный набор функций (аудиограмма, аудио-демо, каталог, паспорт аппарата). Пожизненная повторность. Высокий чек. **Отдельный модуль, не пересекается с другими.** + +**Группа C. Пред-операционная подготовка + восстановление** — сегменты 1 + 3 + 6 (одна механика для трёх сегментов). **Две фазы, как у Группы B:** +- **Кандидаты на операцию** — после пред-оп приёма ушли «думать». Возврат через материалы, кейсы пациентов, чат с хирургом, возвратные push-триггеры (3/7/21 день), прозрачность по цене/рассрочке. +- **Решившиеся** — бегунок → чек-лист дня операции → операция → восстановление. Окно 6–12 недель. + +**Один модуль закрывает три сегмента бизнес-аналитики** (FESS, детские аденоиды, вазотомия). + +**Группа D. АСИТ + контроль астмы** — часть сегмента 5 + сегмент 7. Ежедневный трекер, дневник симптомов, навигатор побочки. **Самый сложный, требует верификации врачом.** + +### 4.4. Что остаётся за кадром + +Сегменты 8 (храпуны), 9 (фониатрия), 10 (check-up) — низкая повторность и/или низкий охват. Закрываются базовым джентльменским набором, специализированных модулей в ближайшем горизонте не требуют. + +--- + +## 5. Порядок внедрения + +### Фаза 1. Транзакционная база (§3) + +План лечения → Результаты / медкарта → Заказ справок. + +**Эффект:** пациент видит свои назначения, результаты и может получить документы без звонка в клинику. Это и есть базовые retention-якоря: «не удалю это приложение». Массовый амбулаторный + хроники покрыты в части информирования и документов. + +**Критический параметр сроков** — структурированность назначений в МИС (см. §6 вопрос 1). От этого зависит, собирается ли план лечения автоматически или врач заполняет его вручную в виджете. + +### Фаза 1.5. Коммуникационная надстройка (§3) + +Чат с медицинским консьержем → AI-помощник (shadow-mode). + +**Зачем отдельная подфаза:** эти функции несут организационные и юридические риски (SLA, выгорание врачей, галлюцинации LLM) и могут надолго задержать релиз, если класть в Фазу 1. Выделение в 1.5 позволяет: собрать транзакционную базу быстро и безопасно, отработать регламент консьержа отдельно, запустить AI сначала под валидацией человека. + +### Фаза 2. Сегментные модули — порядок + +Рекомендуемая последовательность: + +**1. Группа A (Процедуры самопомощи хроников) — первым** +- **Самый массовый охват** — тысячи пациентов в месяц (сегмент 2 + 5). +- Напрямую опирается на план лечения из Фазы 1 — продолжение той же инфраструктуры. +- Средняя сложность: контент (видео-инструкции, 10–15 техник) + простой трекер + дневник симптомов. +- Бизнес-эффект: рост комплаенса → меньше обострений → меньше экстренных приёмов и операций, на которые хроники срываются, когда дома не помогает. +- Эффект заметен пациенту сразу — ежедневная польза. + +**2. Группа C (Пред-операционная подготовка) — вторым** +- Закрывает 3 сегмента (1, 3, 6) одним модулем. +- Быстрый MVP — маршрутная карта с чекбоксами, сроки годности, автозапись. Восстановление уже есть в прототипе. +- Прямой измеримый бизнес-эффект: снижение переносов операций из-за просроченных анализов + возврат сомневающихся кандидатов на операцию. +- Вклад сегментов в выручку: ~50–60 млн (хирургия), плюс косвенно вазотомия как конвертер в большую хирургию. + +**3. Группа B (Сурдология) — третьим** +- Изолированный сегмент с уникальными функциями. +- Пожизненное удержание × высокий чек × растущий рынок (старение). +- Две половины: возврат кандидатов после демо (высокая конверсия в деньги) + обслуживание после покупки (лояльность и LTV). +- Можно запускать параллельно с C после Фазы 1, если есть ресурс. + +**4. Группа D (АСИТ + астма) — четвёртым** +- Самая высокая глубина пользы (влияет на медисход), но самая высокая ответственность. +- Требует верификации контента аллергологом/пульмонологом клиники. +- Можно начать готовить контент и интеграции параллельно с A/C/B, выпустить позже. + +### Что не берём в план сейчас + +- Храпуны (8), фониатрия (9), check-up (10) — специализированных модулей в горизонте планирования не делаем. +- Отдельные «первичные» модули под сегменты — не делаем. Первичный путь = джентльменский набор + базовые функции (запись, врачи, цены, контакты), которые уже есть. + +### Что нужно сделать вне Фаз, уже сейчас + +- **Добавить аллерголога-иммунолога в список врачей** (есть специализация, нет конкретного врача в данных). Предусловие для Группы D. + +--- + +## 6. Вопросы к обсуждению на встрече + +**Первоочередной (определяет сроки Фазы 1):** + +1. **МИС и структурированные назначения.** Отдаёт ли МИС по API назначения структурированно (препарат, доза, частота, курс) или только PDF-заключением? От этого зависит: план лечения собирается автоматически или врач заполняет вручную в виджете. Там же: API для результатов анализов, сроков годности, расписания. + +**По процессам клиники:** + +2. **Медицинский консьерж — кто в роли?** Дежурный врач / фельдшер / медсестра? Кто держит SLA? Как компенсируется эскалация вопроса лечащему врачу? +3. **SLA чата** — целевое время ответа в рабочее время (1ч / 4ч / день)? +4. **Справки и финдокументы** — текущий процесс заказа через администратора; что готовы автоматизировать в первую очередь (ФНС-справка, выписки, счета)? + +**По метрикам (для оценки эффекта):** + +5. Подтвердить **«2 из 3 — повторные»** — уникальные пациенты в год или визиты? Меняет оценку охвата Группы A. +6. **Процент повторных, не доходящих до контроля** — метрика успеха Фазы 1. +7. **Сурдология** — кандидатов/мес, % возврата за аппаратом. От этого зависит приоритет Группы B. +8. **Переносы операций** — частая причина просроченные анализы? Усиливает Группу C. + +**По ресурсам Фазы 1.5 и 2:** + +9. Готов ли **аллерголог** верифицировать контент для АСИТ-трекера? Без этого D не запускаем. +10. База знаний / статьи — достаточно ли материала для RAG или формировать отдельно? +11. Политика по **AI shadow-mode**: кто утверждает категории вопросов для постепенного перевода в прямой режим? + +--- + +## Приложение. Короткая сводка для слайда + +**Что предлагаем:** +1. **Фаза 1** — транзакционная база для всех: план лечения, результаты/медкарта, заказ справок + уже существующие запись, ближайший приём, чат с оператором, статьи. Быстрый MVP, минимум рисков. +2. **Фаза 1.5** — коммуникационная надстройка: чат с медицинским консьержем (не прямой с врачом) и AI-помощник в shadow-mode. Запускается после стабилизации базы. +3. **Фаза 2** — четыре сегментных модуля в порядке: A (процедуры самопомощи хроников — массовый) → C (пред-оп подготовка — 3 сегмента разом) → B (сурдология — высокий чек) → D (АСИТ + астма — с верификацией врачом). +4. **Первичные в приложении** = базовый минимум, который уже есть. Новых первичных модулей не строим — они приходят через веб. Исключения — сегменты, где после первого визита пациент «уходит думать»: сурдология, хирургия, АСИТ. diff --git a/MEETING_2026-04-23.pptx b/MEETING_2026-04-23.pptx new file mode 100644 index 0000000..bdd1e55 Binary files /dev/null and b/MEETING_2026-04-23.pptx differ diff --git a/README.md b/README.md index 831ba85..f3824e4 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,29 @@ npm run dev npm run build npm run preview ``` + +## Дизайн-система + +Токены в `src/tokens.css`. + +Основные цвета: + +- `#2BB4A8` — primary (teal), бренд и основные CTA +- `#E04E44` — accent (красный), выделенные действия +- `#F5EDDF` — warm hero, тёплые приветственные блоки +- `#2E9B6B` — success, `#E8A13C` — warning, `#D94141` — danger + +Шрифты: **PT Sans** (основной), **PT Sans Narrow** (display/заголовки). + +## Экраны + +Описания всех экранов — в `src/docs.js`. Ключевые группы и цели пользователя: + +- **Главная** (`home:*`) — варианты стартового экрана: Карточки, Лента, Таймлайн, Таймлайн X, Светлая плитка. Цель: быстрый старт — запись или ближайший приём. +- **Запись** (`booking-*`) — 4-шаговый флоу: специализация → врач → дата/время → подтверждение → успех. +- **Врачи** (`doctors`, `doctor`) — список и карточка врача для решения «записаться». +- **Приёмы и медкарта** (`appts`, `appt`, `medcard`, `results`, `result*`) — контроль визитов, заключения, анализы, амбулаторная карта. +- **Восстановление и тесты** (`recovery`, `audiotest`) — трекер после операции и скрининг слуха. +- **Чаты** (`chat`, `chat:ai`, `chat:doctor-*`, `chat:operator`) — AI-помощник, врач, администратор. +- **Сервис** (`profile`, `qr`, `telemed`, `notifications`, `search`, `contacts`, `prices`, `articles`, `article`) — профиль, идентификация, видеозвонок, уведомления, поиск, контент. +- **DEV/Docs** (`dev-colors`, `dev-examples`, `docs`) — палитра, примеры компонентов и гайд по экранам. diff --git a/build_deck.py b/build_deck.py new file mode 100644 index 0000000..c033732 --- /dev/null +++ b/build_deck.py @@ -0,0 +1,913 @@ +"""Собирает MEETING_2026-04-23.pptx из содержания MEETING_2026-04-23.md. + +Запуск: python3 build_deck.py +Выход: MEETING_2026-04-23.pptx в корне проекта +""" + +from pptx import Presentation +from pptx.util import Inches, Pt, Emu +from pptx.dml.color import RGBColor +from pptx.enum.shapes import MSO_SHAPE +from pptx.enum.text import PP_ALIGN, MSO_ANCHOR +from pptx.oxml.ns import qn +from copy import deepcopy + +# ---------- Бренд клиники ---------- +PRIMARY = RGBColor(0x2B, 0xB4, 0xA8) +PRIMARY_DARK = RGBColor(0x1C, 0x8A, 0x80) +PRIMARY_50 = RGBColor(0xE8, 0xF7, 0xF5) +ACCENT = RGBColor(0xE0, 0x4E, 0x44) +WARM = RGBColor(0xF5, 0xED, 0xDF) +SUCCESS = RGBColor(0x2E, 0x9B, 0x6B) +WARNING = RGBColor(0xE8, 0xA1, 0x3C) +DANGER = RGBColor(0xD9, 0x41, 0x41) +FG = RGBColor(0x1F, 0x29, 0x37) +FG2 = RGBColor(0x4B, 0x55, 0x63) +FG3 = RGBColor(0x9C, 0xA3, 0xAF) +BG = RGBColor(0xFF, 0xFF, 0xFF) +SOFT = RGBColor(0xF3, 0xF4, 0xF6) + +FONT_SANS = "PT Sans" +FONT_DISPLAY = "PT Sans Narrow" + +# ---------- Геометрия 16:9 ---------- +prs = Presentation() +prs.slide_width = Inches(13.333) +prs.slide_height = Inches(7.5) +SW = prs.slide_width +SH = prs.slide_height + +BLANK_LAYOUT = prs.slide_layouts[6] # Blank + +MARGIN_L = Inches(0.6) +MARGIN_R = Inches(0.6) +MARGIN_T = Inches(0.45) +CONTENT_W = SW - MARGIN_L - MARGIN_R + +FOOTER_TXT = "Клиника УГН · Приложение · 23 апр 2026" + +# ---------- Примитивы ---------- +def add_rect(slide, x, y, w, h, fill=None, line=None, line_w=None): + shp = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, x, y, w, h) + shp.shadow.inherit = False + if fill is None: + shp.fill.background() + else: + shp.fill.solid() + shp.fill.fore_color.rgb = fill + if line is None: + shp.line.fill.background() + else: + shp.line.color.rgb = line + if line_w is not None: + shp.line.width = line_w + return shp + +def add_text(slide, x, y, w, h, text, *, size=16, bold=False, color=FG, + font=FONT_SANS, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP, + line_spacing=None): + tb = slide.shapes.add_textbox(x, y, w, h) + tf = tb.text_frame + tf.word_wrap = True + tf.margin_left = tf.margin_right = Emu(0) + tf.margin_top = tf.margin_bottom = Emu(0) + tf.vertical_anchor = anchor + lines = text.split("\n") + for i, ln in enumerate(lines): + p = tf.paragraphs[0] if i == 0 else tf.add_paragraph() + p.alignment = align + if line_spacing is not None: + p.line_spacing = line_spacing + r = p.add_run() + r.text = ln + r.font.name = font + r.font.size = Pt(size) + r.font.bold = bold + r.font.color.rgb = color + return tb + +def add_rich(slide, x, y, w, h, runs, *, align=PP_ALIGN.LEFT, + anchor=MSO_ANCHOR.TOP, size=14, line_spacing=1.15): + """runs = [(text, {'bold':bool,'color':RGB,'size':int,'font':str}), ...]""" + tb = slide.shapes.add_textbox(x, y, w, h) + tf = tb.text_frame + tf.word_wrap = True + tf.margin_left = tf.margin_right = Emu(0) + tf.margin_top = tf.margin_bottom = Emu(0) + tf.vertical_anchor = anchor + paragraphs = [[]] + for text, style in runs: + if text == "\n": + paragraphs.append([]) + else: + paragraphs[-1].append((text, style)) + for i, para in enumerate(paragraphs): + p = tf.paragraphs[0] if i == 0 else tf.add_paragraph() + p.alignment = align + p.line_spacing = line_spacing + for text, style in para: + r = p.add_run() + r.text = text + r.font.name = style.get("font", FONT_SANS) + r.font.size = Pt(style.get("size", size)) + r.font.bold = style.get("bold", False) + r.font.color.rgb = style.get("color", FG) + return tb + +def footer(slide, idx, total): + add_rect(slide, 0, SH - Inches(0.32), SW, Inches(0.32), fill=PRIMARY_50) + add_text(slide, MARGIN_L, SH - Inches(0.3), Inches(8), Inches(0.25), + FOOTER_TXT, size=10, color=FG2) + add_text(slide, SW - Inches(1.2), SH - Inches(0.3), Inches(0.6), Inches(0.25), + f"{idx} / {total}", size=10, color=FG2, align=PP_ALIGN.RIGHT) + +def title_bar(slide, title, eyebrow=None): + """Верхняя полоска: маленькая подпись категории + крупный заголовок.""" + y = MARGIN_T + if eyebrow: + add_text(slide, MARGIN_L, y, CONTENT_W, Inches(0.3), + eyebrow.upper(), size=11, bold=True, color=PRIMARY, + font=FONT_SANS) + y += Inches(0.34) + add_text(slide, MARGIN_L, y, CONTENT_W, Inches(0.6), + title, size=28, bold=True, color=FG, font=FONT_DISPLAY) + y += Inches(0.7) + # Тонкая линия + add_rect(slide, MARGIN_L, y, Inches(1.2), Inches(0.04), fill=PRIMARY) + return y + Inches(0.25) + +def new_slide(): + return prs.slides.add_slide(BLANK_LAYOUT) + +# ---------- Стилизованная таблица ---------- +def add_table(slide, x, y, w, h, data, *, + header=True, col_widths=None, row_heights=None, + header_fill=PRIMARY, header_fg=BG, body_fg=FG, + alt_fill=PRIMARY_50, size=11, header_size=11): + rows, cols = len(data), len(data[0]) + tbl_shp = slide.shapes.add_table(rows, cols, x, y, w, h).table + if col_widths: + for i, cw in enumerate(col_widths): + tbl_shp.columns[i].width = cw + if row_heights: + for i, rh in enumerate(row_heights): + tbl_shp.rows[i].height = rh + for ri, row in enumerate(data): + for ci, cell_val in enumerate(row): + cell = tbl_shp.cell(ri, ci) + cell.margin_left = cell.margin_right = Inches(0.08) + cell.margin_top = cell.margin_bottom = Inches(0.05) + # Fill + if header and ri == 0: + cell.fill.solid(); cell.fill.fore_color.rgb = header_fill + elif alt_fill and ri % 2 == 0 and not (header and ri == 0): + cell.fill.solid(); cell.fill.fore_color.rgb = alt_fill + else: + cell.fill.solid(); cell.fill.fore_color.rgb = BG + # Text + tf = cell.text_frame + tf.word_wrap = True + tf.clear() + lines = str(cell_val).split("\n") + for i, ln in enumerate(lines): + p = tf.paragraphs[0] if i == 0 else tf.add_paragraph() + p.alignment = PP_ALIGN.LEFT + r = p.add_run() + r.text = ln + r.font.name = FONT_SANS + if header and ri == 0: + r.font.size = Pt(header_size) + r.font.bold = True + r.font.color.rgb = header_fg + else: + r.font.size = Pt(size) + r.font.color.rgb = body_fg + return tbl_shp + +# ============================================================ +# СЛАЙДЫ +# ============================================================ + +def slide_title(): + s = new_slide() + # Фоновая тёплая полоса слева + add_rect(s, 0, 0, Inches(4.5), SH, fill=WARM) + # Teal-акцент + add_rect(s, Inches(4.5), 0, Inches(0.12), SH, fill=PRIMARY) + # Левый блок — мета + add_text(s, Inches(0.7), Inches(0.7), Inches(3.5), Inches(0.3), + "КЛИНИКА УГН", size=12, bold=True, color=PRIMARY_DARK) + add_text(s, Inches(0.7), Inches(1.1), Inches(3.5), Inches(0.3), + "Мобильное приложение", size=13, color=FG2) + add_text(s, Inches(0.7), SH - Inches(1.2), Inches(3.5), Inches(0.3), + "Встреча", size=12, color=FG3) + add_text(s, Inches(0.7), SH - Inches(0.9), Inches(3.5), Inches(0.4), + "23 апреля 2026", size=18, bold=True, color=FG, font=FONT_DISPLAY) + # Правый блок — заголовок + add_text(s, Inches(5.1), Inches(2.2), Inches(7.6), Inches(1.0), + "Приоритеты развития", size=48, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, Inches(5.1), Inches(3.2), Inches(7.6), Inches(0.8), + "мобильного приложения", size=36, color=FG2, font=FONT_DISPLAY) + # Подзаголовок + add_rect(s, Inches(5.1), Inches(4.5), Inches(0.8), Inches(0.04), fill=PRIMARY) + add_text(s, Inches(5.1), Inches(4.7), Inches(7.6), Inches(1.5), + "Джентльменский набор для всех\nи четыре группы сегментов повторных", + size=20, color=FG2, font=FONT_DISPLAY) + return s + +def slide_agenda(): + s = new_slide() + y = title_bar(s, "Повестка", "Что обсуждаем") + items = [ + ("1", "Контекст и критерии приоритизации", + "Факты о потоке пациентов, 10 бизнес-сегментов, рамка оценки"), + ("2", "Текущие функции — что есть", + "Приоритеты использования и точки усиления"), + ("3", "Джентльменский набор для всех пациентов", + "Транзакционная база (Фаза 1) + коммуникационная надстройка (Фаза 1.5)"), + ("4", "10 сегментов × первичный/повторный в приложении", + "Матрица и 4 группы сегментных модулей"), + ("5", "Порядок внедрения и решение", + "Фаза 1 → Фаза 1.5 → Фаза 2 (A → C → B → D). Что выбираем сегодня"), + ] + row_h = Inches(0.95) + for i, (num, title, sub) in enumerate(items): + yy = y + row_h * i + # кружок-номер + circle = s.shapes.add_shape(MSO_SHAPE.OVAL, MARGIN_L, yy, + Inches(0.6), Inches(0.6)) + circle.shadow.inherit = False + circle.fill.solid(); circle.fill.fore_color.rgb = PRIMARY + circle.line.fill.background() + tf = circle.text_frame + tf.margin_left = tf.margin_right = Emu(0) + tf.margin_top = tf.margin_bottom = Emu(0) + p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER + r = p.add_run(); r.text = num + r.font.name = FONT_DISPLAY; r.font.size = Pt(20); r.font.bold = True + r.font.color.rgb = BG + add_text(s, MARGIN_L + Inches(0.9), yy + Inches(0.02), + Inches(11), Inches(0.4), title, size=18, bold=True, + color=FG, font=FONT_DISPLAY) + add_text(s, MARGIN_L + Inches(0.9), yy + Inches(0.45), + Inches(11), Inches(0.4), sub, size=13, color=FG2) + return s + +def slide_facts(): + s = new_slide() + y = title_bar(s, "Ключевые факты о потоке", "Контекст") + # Большая статистика слева + add_text(s, MARGIN_L, y + Inches(0.2), Inches(5), Inches(1.6), + "2 из 3", size=88, bold=True, color=PRIMARY, font=FONT_DISPLAY) + add_text(s, MARGIN_L, y + Inches(1.8), Inches(5.5), Inches(0.7), + "пациентов клиники — повторные", + size=18, color=FG, font=FONT_DISPLAY) + add_text(s, MARGIN_L, y + Inches(2.4), Inches(5.5), Inches(1.4), + "Значительная доля — повторные внутри одного эпизода лечения: " + "после первого визита ещё 1–3+ приёма, процедуры, контроль.", + size=13, color=FG2) + # Правый блок — выручка + bx = Inches(7.0); bw = Inches(5.7) + add_rect(s, bx, y + Inches(0.1), bw, Inches(4.8), + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(0.5)) + add_text(s, bx + Inches(0.3), y + Inches(0.3), bw - Inches(0.6), Inches(0.4), + "ВЫРУЧКА ~200 МЛН / ГОД · 10 СЕГМЕНТОВ", size=11, bold=True, + color=PRIMARY_DARK) + lead_rows = [ + ("Амбулаторный поток", "тысячи/мес", "~120 млн"), + ("Взрослая хирургия (FESS, полипы, перегородка)", "300 оп/год", "~30 млн"), + ("Детская аденоидная хирургия", "400–500 оп/год", "~20–30 млн"), + ("Сурдология (слуховые аппараты)", "высокая конверсия", "~20 млн"), + ("Хроники, ЧБД, вазотомия, пульмо, храпуны, фониатрия, check-up", "6 сегментов", "остальное"), + ] + ty = y + Inches(0.8) + for name, vol, rev in lead_rows: + add_text(s, bx + Inches(0.3), ty, Inches(3.5), Inches(0.3), + name, size=12, bold=True, color=FG) + add_text(s, bx + Inches(0.3), ty + Inches(0.28), Inches(3.5), Inches(0.24), + vol, size=10, color=FG3) + add_text(s, bx + bw - Inches(1.8), ty, Inches(1.5), Inches(0.4), + rev, size=14, bold=True, color=ACCENT, align=PP_ALIGN.RIGHT, + font=FONT_DISPLAY) + ty += Inches(0.76) + return s + +def slide_frame(): + s = new_slide() + y = title_bar(s, "Приложение = удержание, не привлечение", "Продуктовая рамка") + # Две колонки + colw = Inches(6.15) + gap = Inches(0.23) + # Левая + lx = MARGIN_L + add_rect(s, lx, y + Inches(0.1), colw, Inches(4.7), + fill=SOFT, line=None) + add_text(s, lx + Inches(0.3), y + Inches(0.25), colw - Inches(0.6), Inches(0.4), + "ПЕРВИЧНЫЕ", size=12, bold=True, color=FG3) + add_text(s, lx + Inches(0.3), y + Inches(0.6), colw - Inches(0.6), Inches(0.6), + "Приходят через веб", size=22, bold=True, color=FG, font=FONT_DISPLAY) + add_rich(s, lx + Inches(0.3), y + Inches(1.3), colw - Inches(0.6), Inches(3.4), [ + ("Главный job: ", {"bold": True, "color": FG}), + ("«куда мне обратиться, как записаться»", {}), + ("\n", {}), + ("Источник: ", {"bold": True, "color": FG}), + ("сайт, SEO, реклама, сарафан", {}), + ("\n", {}), + ("В приложении: ", {"bold": True, "color": FG}), + ("базовый минимум, который уже есть", {}), + ("\n", {}), + ("Приоритет развития: ", {"bold": True, "color": FG}), + ("низкий — веб работает лучше", {}), + ], size=13, line_spacing=1.3) + # Правая (основная) + rx = lx + colw + gap + add_rect(s, rx, y + Inches(0.1), colw, Inches(4.7), + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(1)) + add_text(s, rx + Inches(0.3), y + Inches(0.25), colw - Inches(0.6), Inches(0.4), + "ПОВТОРНЫЕ · 2 ИЗ 3", size=12, bold=True, color=PRIMARY_DARK) + add_text(s, rx + Inches(0.3), y + Inches(0.6), colw - Inches(0.6), Inches(0.6), + "Приоритет приложения", size=22, bold=True, color=FG, font=FONT_DISPLAY) + add_rich(s, rx + Inches(0.3), y + Inches(1.3), colw - Inches(0.6), Inches(3.4), [ + ("Главный job: ", {"bold": True, "color": FG}), + ("«что делать сейчас по моему лечению»", {}), + ("\n", {}), + ("Источник: ", {"bold": True, "color": FG}), + ("приложение уже установлено, push / сам открывает", {}), + ("\n", {}), + ("В приложении: ", {"bold": True, "color": FG}), + ("специализированный модуль сегмента", {}), + ("\n", {}), + ("Приоритет развития: ", {"bold": True, "color": FG}), + ("высокий — закрывает 2/3 потока", {}), + ], size=13, line_spacing=1.3) + # Сноска-исключения + add_text(s, MARGIN_L, y + Inches(5.1), CONTENT_W, Inches(0.4), + "Исключения: сурдология, хирургия, АСИТ — после первого визита пациент «уходит думать», и вернуть его может только приложение.", + size=11, color=FG2) + return s + +def slide_current_functions(): + s = new_slide() + y = title_bar(s, "Текущие функции — утилита и приоритет", "Что есть сегодня") + # Три колонки: зелёная, жёлтая, красная + groups = [ + ("ЯДРО ЦЕННОСТИ", SUCCESS, [ + ("Запись на приём", "Единственная функция, приводящая новых."), + ("Ближайший приём", "3–10 открытий перед визитом. Самый частый экран."), + ]), + ("ПОДДЕРЖКА", WARNING, [ + ("Список врачей", "Помогает при первом визите, повторный не открывает."), + ("Чат с оператором", "Ограничен одним собеседником — основное развитие в §3."), + ("Профиль", "Редко открывается, но критичен для персонализации."), + ]), + ("НИША", DANGER, [ + ("Семейный профиль", "Критичен для 20–30% (дети, пожилые)."), + ("Контакты", "1–2 открытия за всё время. Функция «галочка»."), + ]), + ] + cw = (CONTENT_W - Inches(0.5)) / 3 + for i, (label, col, items) in enumerate(groups): + cx = MARGIN_L + (cw + Inches(0.25)) * i + add_rect(s, cx, y, cw, Inches(0.5), fill=col) + add_text(s, cx + Inches(0.3), y + Inches(0.1), cw - Inches(0.6), Inches(0.3), + label, size=12, bold=True, color=BG) + yy = y + Inches(0.7) + for title, desc in items: + add_text(s, cx, yy, cw, Inches(0.35), title, + size=15, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, cx, yy + Inches(0.38), cw, Inches(0.9), desc, + size=11, color=FG2) + yy += Inches(1.15) + # Подвал — вывод + add_rect(s, MARGIN_L, Inches(6.55), CONTENT_W, Inches(0.55), + fill=WARM) + add_text(s, MARGIN_L + Inches(0.3), Inches(6.66), CONTENT_W - Inches(0.6), Inches(0.4), + "Слабое место: нет причины открывать приложение между визитами. Это и закрывает джентльменский набор.", + size=13, bold=True, color=FG, font=FONT_DISPLAY) + return s + +def slide_three_layers(): + s = new_slide() + y = title_bar(s, "Три слоя работы", "План") + box_h = Inches(1.75) + gap = Inches(0.15) + # Слой 1 + y1 = y + Inches(0.1) + add_rect(s, MARGIN_L, y1, CONTENT_W, box_h, + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(1)) + add_text(s, MARGIN_L + Inches(0.3), y1 + Inches(0.2), Inches(3), Inches(0.3), + "ФАЗА 1 · ТРАНЗАКЦИОННАЯ БАЗА", size=11, bold=True, color=PRIMARY_DARK) + add_text(s, MARGIN_L + Inches(0.3), y1 + Inches(0.5), Inches(11), Inches(0.5), + "Всем пациентам · быстрый MVP · минимум рисков", + size=18, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, MARGIN_L + Inches(0.3), y1 + Inches(1.0), CONTENT_W - Inches(0.6), Inches(0.7), + "План лечения · Результаты и медкарта · Заказ справок · " + "(+ уже есть: запись, ближайший приём, чат с оператором, статьи)", + size=13, color=FG2) + # Слой 1.5 + y15 = y1 + box_h + gap + add_rect(s, MARGIN_L, y15, CONTENT_W, box_h, + fill=WARM, line=WARNING, line_w=Pt(1)) + add_text(s, MARGIN_L + Inches(0.3), y15 + Inches(0.2), Inches(4), Inches(0.3), + "ФАЗА 1.5 · КОММУНИКАЦИОННАЯ НАДСТРОЙКА", size=11, bold=True, color=WARNING) + add_text(s, MARGIN_L + Inches(0.3), y15 + Inches(0.5), Inches(11), Inches(0.5), + "Поверх стабильной базы · отдельный регламент и безопасность", + size=18, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, MARGIN_L + Inches(0.3), y15 + Inches(1.0), CONTENT_W - Inches(0.6), Inches(0.7), + "Чат с медицинским консьержем (не прямой с лечащим) · AI-помощник на RAG в shadow-mode", + size=13, color=FG2) + # Слой 2 + y2 = y15 + box_h + gap + add_rect(s, MARGIN_L, y2, CONTENT_W, box_h, + fill=SOFT, line=FG3, line_w=Pt(0.5)) + add_text(s, MARGIN_L + Inches(0.3), y2 + Inches(0.2), Inches(3), Inches(0.3), + "ФАЗА 2 · СЕГМЕНТНЫЕ МОДУЛИ", size=11, bold=True, color=FG3) + add_text(s, MARGIN_L + Inches(0.3), y2 + Inches(0.5), Inches(11), Inches(0.5), + "Углубление по группам сегментов", + size=18, bold=True, color=FG, font=FONT_DISPLAY) + # 4 мини-плитки + tiles = [("A", "Самопомощь"), ("C", "Пред-оп"), ("B", "Сурдология"), ("D", "АСИТ + астма")] + tw = (CONTENT_W - Inches(0.6) - Inches(0.15) * 3) / 4 + for i, (code, name) in enumerate(tiles): + tx = MARGIN_L + Inches(0.3) + (tw + Inches(0.15)) * i + ty = y2 + Inches(1.05) + add_rect(s, tx, ty, tw, Inches(0.55), fill=BG, line=PRIMARY, line_w=Pt(0.75)) + add_text(s, tx + Inches(0.15), ty + Inches(0.08), Inches(0.4), Inches(0.4), + code, size=18, bold=True, color=PRIMARY, font=FONT_DISPLAY) + add_text(s, tx + Inches(0.55), ty + Inches(0.13), tw - Inches(0.6), Inches(0.4), + name, size=11, bold=True, color=FG, font=FONT_DISPLAY) + return s + +def slide_phase1_base(): + s = new_slide() + y = title_bar(s, "Фаза 1 · Транзакционная база", "Джентльменский набор, часть 1") + add_text(s, MARGIN_L, y + Inches(0.0), CONTENT_W, Inches(0.4), + "Детерминированные функции без LLM и прямого врачебного диалога. Быстрый MVP, минимум рисков.", + size=13, color=FG2) + data = [ + ["Функция", "Статус", "Суть"], + ["Запись на приём", "Есть", "Запись 24/7, ближайшие окна."], + ["Ближайший приём", "Есть", "Что, где, когда — снимает тревогу перед визитом."], + ["Чат с оператором", "Есть", "Справки, переносы, счета, расписание (человеческий канал)."], + ["Статьи / база знаний", "Есть", "Источник правды для будущего RAG."], + ["План лечения с приёма", "Нет — фундамент", "Структурированные назначения, календарь, напоминания, ссылки на процедуры."], + ["Результаты и медкарта", "Нет — новое", "Анализы, аудиограммы, снимки, заключения. Срок годности виден — критично для пред-опа."], + ["Заказ справок и финдокументов", "Нет — новое", "ФНС-вычет 13%, справки работодателю, счета. Снимает нагрузку с администраторов."], + ] + add_table(s, MARGIN_L, y + Inches(0.55), + CONTENT_W, Inches(4.6), + data, + col_widths=[Inches(3.3), Inches(2.3), CONTENT_W - Inches(5.6)], + size=12, header_size=12) + # Порядок работ + add_rect(s, MARGIN_L, Inches(6.25), CONTENT_W, Inches(0.85), + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(0.5)) + add_rich(s, MARGIN_L + Inches(0.3), Inches(6.35), CONTENT_W - Inches(0.6), Inches(0.7), [ + ("Порядок внутри Фазы 1: ", {"bold": True, "color": PRIMARY_DARK}), + ("1) План лечения — фундамент · ", {}), + ("2) Результаты / медкарта · ", {}), + ("3) Заказ справок. ", {}), + ("Критическая зависимость — МИС: ", {"bold": True, "color": FG}), + ("отдаёт ли API структурированные назначения или план заполняет врач в виджете (см. вопрос №1).", {}), + ], size=12, line_spacing=1.3) + return s + +def slide_phase1_5_overlay(): + s = new_slide() + y = title_bar(s, "Фаза 1.5 · Коммуникационная надстройка", "Джентльменский набор, часть 2") + add_text(s, MARGIN_L, y + Inches(0.0), CONTENT_W, Inches(0.6), + "Живой диалог по поводу лечения. Строится поверх стабильной Фазы 1, требует отдельных регламентов.", + size=13, color=FG2) + # Две большие карточки + cw = (CONTENT_W - Inches(0.3)) / 2 + cy = y + Inches(0.7) + ch = Inches(4.5) + # Консьерж + lx = MARGIN_L + add_rect(s, lx, cy, cw, ch, fill=BG, line=PRIMARY, line_w=Pt(1)) + add_rect(s, lx, cy, cw, Inches(0.55), fill=PRIMARY) + add_text(s, lx + Inches(0.3), cy + Inches(0.12), cw - Inches(0.6), Inches(0.4), + "ЧАТ С МЕДИЦИНСКИМ КОНСЬЕРЖЕМ", size=12, bold=True, color=BG) + add_text(s, lx + Inches(0.3), cy + Inches(0.75), cw - Inches(0.6), Inches(0.5), + "Не прямой с лечащим врачом", + size=18, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, lx + Inches(0.3), cy + Inches(1.3), cw - Inches(0.6), Inches(2.4), + "Дежурный врач / фельдшер / медсестра отвечает по протоколам " + "на 80% рутины: «можно ли совмещать с X», «нормально ли, что третий день болит», " + "«когда повторно сдать анализ».\n\n" + "Эскалация лечащему — только клинически значимое.\n\n" + "Буфер SLA и защита от выгорания врачей.", + size=12, color=FG2) + add_rect(s, lx + Inches(0.3), cy + ch - Inches(0.85), cw - Inches(0.6), Inches(0.7), + fill=WARM) + add_rich(s, lx + Inches(0.45), cy + ch - Inches(0.75), cw - Inches(0.9), Inches(0.55), [ + ("Риск: ", {"bold": True, "color": DANGER}), + ("перегрузка врачей. ", {}), + ("Митигация: ", {"bold": True, "color": SUCCESS}), + ("консьерж-слой + тарификация эскалаций.", {}), + ], size=11, line_spacing=1.3) + # AI + rx = lx + cw + Inches(0.3) + add_rect(s, rx, cy, cw, ch, fill=BG, line=WARNING, line_w=Pt(1)) + add_rect(s, rx, cy, cw, Inches(0.55), fill=WARNING) + add_text(s, rx + Inches(0.3), cy + Inches(0.12), cw - Inches(0.6), Inches(0.4), + "AI-ПОМОЩНИК (RAG, 24/7)", size=12, bold=True, color=BG) + add_text(s, rx + Inches(0.3), cy + Inches(0.75), cw - Inches(0.6), Inches(0.5), + "Запуск в shadow-mode", + size=18, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, rx + Inches(0.3), cy + Inches(1.3), cw - Inches(0.6), Inches(2.4), + "Знает: базу знаний клиники, статьи, план лечения пациента, медкарту, историю приёмов.\n\n" + "Объясняет назначения, ищет ответ в статьях, оценивает «норма или срочно», " + "эскалирует консьержу/врачу.\n\n" + "Отвечает ночью, когда человеческие каналы недоступны.", + size=12, color=FG2) + add_rect(s, rx + Inches(0.3), cy + ch - Inches(0.85), cw - Inches(0.6), Inches(0.7), + fill=WARM) + add_rich(s, rx + Inches(0.45), cy + ch - Inches(0.75), cw - Inches(0.9), Inches(0.55), [ + ("Риск: ", {"bold": True, "color": DANGER}), + ("галлюцинация LLM = юр./репутация. ", {}), + ("Митигация: ", {"bold": True, "color": SUCCESS}), + ("shadow-mode, валидация через консьержа, метрики точности перед прямым режимом.", {}), + ], size=11, line_spacing=1.3) + return s + +def slide_primary_vs_returning(): + s = new_slide() + y = title_bar(s, "Первичный vs повторный в приложении", "Фундаментальное деление") + data = [ + ["Линза", "Первичный в приложении", "Повторный в приложении"], + ["Главный job", + "«Куда обратиться и как записаться»", + "«Что делать сейчас по моему лечению»"], + ["Источник", + "Сайт, SEO, реклама, сарафан", + "Уведомление, пациент сам открывает"], + ["Частота открытия", + "1–3 раза до визита", + "Ежедневно в активном эпизоде"], + ["Что нужно в приложении", + "Базовый минимум (есть)", + "Специализированный модуль сегмента"], + ["Приоритет развития", + "Низкий — веб работает лучше", + "Высокий — 2/3 потока"], + ] + add_table(s, MARGIN_L, y + Inches(0.2), + CONTENT_W, Inches(4.4), + data, + col_widths=[Inches(3.0), Inches(4.55), Inches(4.55)], + size=13, header_size=12, + header_fill=FG) + add_rect(s, MARGIN_L, Inches(6.1), CONTENT_W, Inches(1.0), + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(0.5)) + add_rich(s, MARGIN_L + Inches(0.3), Inches(6.2), CONTENT_W - Inches(0.6), Inches(0.85), [ + ("Исключения: ", {"bold": True, "color": PRIMARY_DARK}), + ("сегменты, где «первичный в приложении» ≠ «первый визит» — сурдология, хирургия, АСИТ. " + "После первого визита пациент уходит, и вернуть его может только приложение. " + "Эти сегменты требуют отдельных «первичных» сценариев удержания.", {}), + ], size=13, line_spacing=1.3) + return s + +def slide_segment_matrix(): + s = new_slide() + y = title_bar(s, "10 сегментов × первичный / повторный", "Матрица") + header = ["#", "Сегмент", "Объём · вклад", "Повторный — что нужно", "Группа"] + rows = [ + ["1", "Заблокированный нос (FESS, полипы)", "300 оп · 30 млн", + "Пред-оп бегунок → восстановление → контроль 3/6/12 мес", "C"], + ["2", "Амбулаторный поток (острые + хроники)", "тысячи/мес · 120 млн", + "План лечения + эпизод + процедуры самопомощи", "A"], + ["3", "Дети с аденоидами", "400–500 оп · 20–30 млн", + "Детский бегунок → восстановление (семейный профиль)", "C"], + ["4", "Потеря слуха (сурдология)", "20 млн", + "Паспорт аппарата, сервисный календарь, расходники, калибровка", "B"], + ["5", "Сложные хроники, ЧБД, аллергия", "часть 120 млн · LTV", + "Процедуры самопомощи + АСИТ-трекер + пыльцевой календарь", "A+D"], + ["6", "Зависимость от капель (вазотомия)", "высокий объём", + "Пред-оп бегунок (компактный) → восстановление", "C"], + ["7", "Пульмонология (кашель/астма)", "средний · сезонный", + "Дневник астмы, напоминания об ингаляторах", "D"], + ["8", "Социально активные храпуны", "низкий · высокий чек", + "Сомнологический чек-up, СИПАП-трекер", "—"], + ["9", "Фониатрия (голос)", "очень низкий", + "Короткое окно, низкая повторность", "—"], + ["10", "Check-up и второе мнение", "единичный", + "Разовая услуга, минимальная повторность", "—"], + ] + data = [header] + rows + # раскраска групп через цвет текста в последней колонке делается потом + tbl = add_table(s, MARGIN_L, y + Inches(0.1), + CONTENT_W, Inches(5.6), + data, + col_widths=[Inches(0.4), Inches(3.4), Inches(2.2), Inches(5.5), Inches(0.8)], + size=10, header_size=11) + # Подкрасить колонку «Группа» + group_colors = {"A": PRIMARY_DARK, "B": PRIMARY_DARK, "C": PRIMARY_DARK, + "D": PRIMARY_DARK, "A+D": PRIMARY_DARK, "—": FG3} + for ri, row in enumerate(rows, start=1): + cell = tbl.cell(ri, 4) + tf = cell.text_frame + for p in tf.paragraphs: + for r in p.runs: + r.font.bold = True + r.font.color.rgb = group_colors.get(row[4], FG) + r.font.size = Pt(12) + return s + +def slide_groups_overview(): + s = new_slide() + y = title_bar(s, "Четыре группы сегментов для повторных", "Укрупнение") + # 4 плитки 2×2 + tiles = [ + ("A", "Процедуры самопомощи", + "Амбулаторный + хроники (2, 5ч)", + "Библиотека техник, напоминания, трекер, дневник.\nСамый массовый охват."), + ("C", "Пред-оп подготовка", + "FESS + аденоиды + вазотомия (1, 3, 6)", + "Две фазы: возврат сомневающихся; бегунок → восстановление.\nОдин модуль — три сегмента."), + ("B", "Сурдология", + "Потеря слуха (4)", + "Две фазы: возврат после демо-аппарата; обслуживание аппарата.\nИзолированный модуль, высокий чек."), + ("D", "АСИТ + астма", + "Часть аллергии + пульмо (5ч, 7)", + "Ежедневный трекер, пыльцевой календарь, навигатор побочки.\nВысокая ответственность."), + ] + tw = (CONTENT_W - Inches(0.3)) / 2 + th = (Inches(5.0) - Inches(0.3)) / 2 + for i, (code, name, segments, desc) in enumerate(tiles): + col = i % 2 + row = i // 2 + tx = MARGIN_L + (tw + Inches(0.3)) * col + ty = y + Inches(0.1) + (th + Inches(0.3)) * row + add_rect(s, tx, ty, tw, th, fill=BG, line=PRIMARY, line_w=Pt(1)) + # Круг с буквой + circ = s.shapes.add_shape(MSO_SHAPE.OVAL, tx + Inches(0.3), ty + Inches(0.3), + Inches(0.8), Inches(0.8)) + circ.shadow.inherit = False + circ.fill.solid(); circ.fill.fore_color.rgb = PRIMARY + circ.line.fill.background() + tf = circ.text_frame + tf.margin_left = tf.margin_right = Emu(0); tf.margin_top = tf.margin_bottom = Emu(0) + p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER + r = p.add_run(); r.text = code + r.font.name = FONT_DISPLAY; r.font.size = Pt(28); r.font.bold = True + r.font.color.rgb = BG + # Название + add_text(s, tx + Inches(1.3), ty + Inches(0.3), tw - Inches(1.5), Inches(0.5), + name, size=20, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, tx + Inches(1.3), ty + Inches(0.8), tw - Inches(1.5), Inches(0.3), + segments, size=11, color=FG3) + # Описание + add_text(s, tx + Inches(0.3), ty + Inches(1.5), tw - Inches(0.6), + th - Inches(1.7), desc, size=12, color=FG2) + return s + +def slide_group_detail(code, color, title, caption, what_it_does, why_priority): + s = new_slide() + y = title_bar(s, title, f"Группа {code}") + # Крупный код слева + add_rect(s, MARGIN_L, y, Inches(1.4), Inches(5.0), fill=PRIMARY_50) + add_text(s, MARGIN_L, y + Inches(1.5), Inches(1.4), Inches(2.0), + code, size=120, bold=True, color=PRIMARY, font=FONT_DISPLAY, + align=PP_ALIGN.CENTER) + # Правый контент + rx = MARGIN_L + Inches(1.6) + rw = CONTENT_W - Inches(1.6) + add_text(s, rx, y + Inches(0.0), rw, Inches(0.4), + caption, size=13, color=FG3) + # Что делает + add_text(s, rx, y + Inches(0.45), rw, Inches(0.35), + "ЧТО В МОДУЛЕ", size=11, bold=True, color=PRIMARY_DARK) + add_text(s, rx, y + Inches(0.8), rw, Inches(2.8), + what_it_does, size=13, color=FG) + # Почему приоритет + add_rect(s, rx, y + Inches(3.7), rw, Inches(1.3), + fill=WARM) + add_text(s, rx + Inches(0.3), y + Inches(3.8), Inches(5), Inches(0.3), + "ПОЧЕМУ В ЭТОМ ПОРЯДКЕ", size=11, bold=True, color=FG2) + add_text(s, rx + Inches(0.3), y + Inches(4.1), rw - Inches(0.6), Inches(1.1), + why_priority, size=13, color=FG) + return s + +def slide_group_A(): + return slide_group_detail( + "A", PRIMARY, + "Процедуры самопомощи для хроников", + "Амбулаторный поток + сложные хроники · сегменты 2 и 5", + "• Библиотека техник (видео + шаги): промывание носа физраствором, полоскание горла, " + "ингаляции, гимнастика слуховой трубы, голосовые упражнения, туалет уха.\n" + "• Напоминания утром/вечером, привязка к плану лечения.\n" + "• Трекер комплаенса: ежедневные отметки, стрики, сводка.\n" + "• Дневник симптомов в связке: «промываю 5 дней, насморк 4 → 2».\n" + "• Сводка для врача перед контрольным приёмом.", + "Самый массовый охват (тысячи/мес) × ежедневная повторность. " + "Напрямую опирается на план лечения из Фазы 1. " + "Контент-ориентированный MVP (видео + простой трекер). " + "Эффект заметен пациенту сразу." + ) + +def slide_group_C(): + return slide_group_detail( + "C", PRIMARY, + "Пред-операционная подготовка + восстановление", + "FESS + дети-аденоиды + вазотомия · сегменты 1, 3, 6", + "Две фазы:\n" + "1) Кандидаты на операцию — ушли «думать» после пред-оп приёма. Возврат через материалы, " + "кейсы пациентов, чат с хирургом, возвратные push (3/7/21 день), прозрачность цены/рассрочки.\n" + "2) Решившиеся — маршрутная карта («бегунок») с чекбоксами, сроки годности анализов, " + "автозапись из пункта, загрузка сторонних результатов, чек-лист дня операции, " + "договор и оплата в приложении → передача в «Восстановление».", + "Один модуль закрывает 3 сегмента. Быстрый MVP (маршрутная карта — простой список с состояниями). " + "Прямой бизнес-эффект: меньше переносов операций + возврат сомневающихся кандидатов. " + "Вклад сегментов: ~50–60 млн." + ) + +def slide_group_B(): + return slide_group_detail( + "B", PRIMARY, + "Сурдология — слухопротезирование", + "Потеря слуха · сегмент 4", + "Две фазы, зеркально Группе C:\n" + "1) Кандидаты — после первого визита и демо уходят думать 2–3 месяца. " + "Аудиограмма в профиле, аудио-демо «до/после» в любых наушниках, каталог моделей с фильтром " + "по аудиограмме, калькулятор стоимости (ФСС, рассрочка, трейд-ин), шеринг близкому, " + "истории пациентов, возвратные push 3/7/21 день.\n" + "2) Пользователи аппарата — паспорт аппарата, календарь обслуживания, расходники, " + "навигатор неполадок, ежегодная калибровка.", + "Пожизненный LTV × высокий чек (60–180 тыс.) × растущий рынок (старение). " + "Изолированный модуль — не пересекается с другими. " + "Можно запускать параллельно с C после Фазы 1." + ) + +def slide_group_D(): + return slide_group_detail( + "D", PRIMARY, + "АСИТ + контроль астмы", + "Часть аллергии + пульмонология · сегменты 5ч и 7", + "• Календарь курса (3–5 лет) с маркером «вы здесь».\n" + "• Ежедневный приём СЛИТ с push, стрики.\n" + "• Журнал инъекций ПКИТ.\n" + "• Дневник симптомов + пыльцевой календарь региона.\n" + "• Навигатор побочки с эскалацией к врачу / скорой.\n" + "• Экстренная связь, аптечка дома.\n" + "• Автошеринг дневника врачу перед плановым визитом.", + "Самая высокая глубина пользы — прямое влияние на медицинский исход (удержание = успех лечения). " + "Но самая высокая ответственность: требует верификации контента аллергологом/пульмонологом. " + "Запускаем последним; контент можно готовить параллельно." + ) + +def slide_roadmap(): + s = new_slide() + y = title_bar(s, "Порядок внедрения", "Дорожная карта") + # Фаза 1 бокс + p1_h = Inches(0.9) + add_rect(s, MARGIN_L, y + Inches(0.05), CONTENT_W, p1_h, + fill=PRIMARY_50, line=PRIMARY, line_w=Pt(1)) + add_text(s, MARGIN_L + Inches(0.3), y + Inches(0.15), Inches(3), Inches(0.3), + "ФАЗА 1 · ТРАНЗАКЦИОННАЯ БАЗА", size=11, bold=True, color=PRIMARY_DARK) + add_text(s, MARGIN_L + Inches(0.3), y + Inches(0.48), CONTENT_W - Inches(0.6), Inches(0.4), + "План лечения → Результаты и медкарта → Заказ справок", + size=14, bold=True, color=FG, font=FONT_DISPLAY) + # Фаза 1.5 бокс + y15 = y + Inches(0.05) + p1_h + Inches(0.15) + add_rect(s, MARGIN_L, y15, CONTENT_W, p1_h, + fill=WARM, line=WARNING, line_w=Pt(1)) + add_text(s, MARGIN_L + Inches(0.3), y15 + Inches(0.1), Inches(4), Inches(0.3), + "ФАЗА 1.5 · КОММУНИКАЦИОННАЯ НАДСТРОЙКА", size=11, bold=True, color=WARNING) + add_text(s, MARGIN_L + Inches(0.3), y15 + Inches(0.43), CONTENT_W - Inches(0.6), Inches(0.4), + "Чат с медицинским консьержем → AI-помощник (shadow-mode)", + size=14, bold=True, color=FG, font=FONT_DISPLAY) + # Фаза 2 — 4 шага + y2 = y15 + p1_h + Inches(0.25) + add_text(s, MARGIN_L, y2, Inches(6), Inches(0.3), + "ФАЗА 2 · СЕГМЕНТНЫЕ МОДУЛИ", size=11, bold=True, color=FG2) + # 4 карточки горизонтально со стрелками + steps = [ + ("1", "A", "Процедуры самопомощи", "Массовый охват · продолжение плана лечения"), + ("2", "C", "Пред-оп подготовка", "3 сегмента одним модулем · быстрый эффект"), + ("3", "B", "Сурдология", "Высокий чек · пожизненное удержание"), + ("4", "D", "АСИТ + астма", "Верификация врачом · высокая польза"), + ] + step_y = y2 + Inches(0.35) + step_h = Inches(2.0) + step_w = (CONTENT_W - Inches(0.4) * 3) / 4 + for i, (num, code, name, sub) in enumerate(steps): + sx = MARGIN_L + (step_w + Inches(0.4)) * i + add_rect(s, sx, step_y, step_w, step_h, fill=BG, line=PRIMARY, line_w=Pt(1)) + # Номер и код группы + add_text(s, sx + Inches(0.2), step_y + Inches(0.2), Inches(0.8), Inches(0.4), + f"Шаг {num}", size=11, color=FG3) + add_text(s, sx + Inches(0.2), step_y + Inches(0.45), step_w - Inches(0.4), Inches(0.6), + code, size=36, bold=True, color=PRIMARY, font=FONT_DISPLAY) + add_text(s, sx + Inches(0.2), step_y + Inches(1.0), step_w - Inches(0.4), Inches(0.4), + name, size=13, bold=True, color=FG, font=FONT_DISPLAY) + add_text(s, sx + Inches(0.2), step_y + Inches(1.4), step_w - Inches(0.4), Inches(0.55), + sub, size=10, color=FG2) + # Стрелка + if i < 3: + arr_x = sx + step_w + Inches(0.05) + arr = s.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW, arr_x, + step_y + step_h / 2 - Inches(0.15), + Inches(0.3), Inches(0.3)) + arr.shadow.inherit = False + arr.fill.solid(); arr.fill.fore_color.rgb = PRIMARY + arr.line.fill.background() + return s + +def slide_questions(): + s = new_slide() + y = title_bar(s, "Вопросы к обсуждению", "Что уточнить у клиники") + questions = [ + ("Поток", "«2 из 3 повторных» — уникальные пациенты в год или визиты?"), + ("Метрики", "Процент повторных, не доходящих до контрольного приёма?"), + ("Врачи", "Готовность врачей к SLA по асинхронному чату и в каком окне?"), + ("МИС", "API: структурированные назначения, сроки годности анализов, расписание?"), + ("Сурдо", "Сколько кандидатов/мес, % возврата за аппаратом?"), + ("Хирургия", "Частая причина переноса операций — просроченные анализы?"), + ("Аллерго", "Готов ли аллерголог верифицировать контент АСИТ-трекера?"), + ("Контент", "Достаточно ли материалов для RAG-базы?"), + ] + col_h = Inches(0.6) + for i, (tag, q) in enumerate(questions): + col = i % 2 + row = i // 2 + qx = MARGIN_L + (CONTENT_W / 2 + Inches(0.15)) * col + qy = y + Inches(0.2) + (col_h + Inches(0.4)) * row + qw = CONTENT_W / 2 - Inches(0.15) + add_rect(s, qx, qy, Inches(1.0), col_h, fill=PRIMARY) + add_text(s, qx, qy, Inches(1.0), col_h, tag, + size=12, bold=True, color=BG, font=FONT_DISPLAY, + align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE) + add_rect(s, qx + Inches(1.0), qy, qw - Inches(1.0), col_h, + fill=PRIMARY_50) + add_text(s, qx + Inches(1.2), qy, qw - Inches(1.2), col_h, q, + size=12, color=FG, anchor=MSO_ANCHOR.MIDDLE) + return s + +def slide_final(): + s = new_slide() + # Большой финал: что решить сегодня + add_rect(s, 0, 0, SW, SH, fill=PRIMARY) + add_text(s, MARGIN_L, Inches(0.8), CONTENT_W, Inches(0.5), + "ЧТО РЕШАЕМ СЕГОДНЯ", size=14, bold=True, color=PRIMARY_50) + add_text(s, MARGIN_L, Inches(1.4), CONTENT_W, Inches(1.2), + "Подтвердить порядок:", size=36, bold=True, color=BG, font=FONT_DISPLAY) + add_text(s, MARGIN_L, Inches(2.4), CONTENT_W, Inches(1.8), + "Фаза 1 · транзакционная база\n→ Фаза 1.5 · консьерж + AI\n→ Фаза 2: A → C → B → D", + size=26, bold=True, color=BG, font=FONT_DISPLAY, line_spacing=1.3) + # Три пункта + items = [ + ("1", "С чего начинаем Фазу 1?", "План лечения — фундамент. Зависит от МИС-API."), + ("2", "Когда стартует Фаза 1.5?", "После стабилизации базы. AI в shadow-mode."), + ("3", "Параллельно", "Контент для D, добавить аллерголога в справочники."), + ] + y = Inches(4.8) + for i, (num, q, a) in enumerate(items): + ix = MARGIN_L + (CONTENT_W / 3) * i + iw = CONTENT_W / 3 - Inches(0.3) + add_text(s, ix, y, Inches(0.5), Inches(0.5), + num, size=36, bold=True, color=WARM, font=FONT_DISPLAY) + add_text(s, ix + Inches(0.6), y + Inches(0.05), iw - Inches(0.6), Inches(0.5), + q, size=14, bold=True, color=BG, font=FONT_DISPLAY) + add_text(s, ix + Inches(0.6), y + Inches(0.6), iw - Inches(0.6), Inches(1.2), + a, size=12, color=PRIMARY_50) + # Подпись + add_text(s, MARGIN_L, SH - Inches(0.7), CONTENT_W, Inches(0.4), + "Клиника УГН · мобильное приложение · 23 апр 2026", + size=11, color=PRIMARY_50) + return s + +# ============================================================ +# СБОРКА +# ============================================================ +slides = [ + slide_title(), + slide_agenda(), + slide_facts(), + slide_frame(), + slide_current_functions(), + slide_three_layers(), + slide_phase1_base(), + slide_phase1_5_overlay(), + slide_primary_vs_returning(), + slide_segment_matrix(), + slide_groups_overview(), + slide_group_A(), + slide_group_C(), + slide_group_B(), + slide_group_D(), + slide_roadmap(), + slide_questions(), + slide_final(), +] + +# Футер на всех слайдах, кроме титульного и финального (у них свой фон) +total = len(slides) +for idx, s in enumerate(slides, start=1): + if idx == 1 or idx == total: + continue + footer(s, idx, total) + +out = "MEETING_2026-04-23.pptx" +prs.save(out) +print(f"OK {out} ({total} slides)") diff --git a/package-lock.json b/package-lock.json index 25bd1f3..83f7d94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,11 @@ "name": "pcs-pt-mobile", "version": "0.1.0", "dependencies": { + "leaflet": "^1.9.4", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-leaflet": "^4.2.1", + "react-router-dom": "^6.30.3" }, "devDependencies": { "@vitejs/plugin-react": "^4.3.4", @@ -739,6 +742,26 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@react-leaflet/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", + "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", + "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -1375,6 +1398,12 @@ "node": ">=6" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1491,6 +1520,20 @@ "react": "^18.3.1" } }, + "node_modules/react-leaflet": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", + "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^2.1.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -1501,6 +1544,38 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", + "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", + "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2", + "react-router": "6.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/rollup": { "version": "4.60.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", diff --git a/package.json b/package.json index e3fe231..b13260a 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,11 @@ "preview": "vite preview" }, "dependencies": { + "leaflet": "^1.9.4", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-leaflet": "^4.2.1", + "react-router-dom": "^6.30.3" }, "devDependencies": { "@vitejs/plugin-react": "^4.3.4", diff --git a/public/roadmap.html b/public/roadmap.html new file mode 100644 index 0000000..f46e8c6 --- /dev/null +++ b/public/roadmap.html @@ -0,0 +1,1479 @@ + + +
+ + +16 экранов: транзакционное ядро (запись + ближайший приём + врачи) и базовая идентификация. Точка отсчёта.
+Запись CTA, специализации, ближайший приём. Витрина услуг.
+ +Каталог, фильтры, рейтинги, расписание, отзывы.
+ +4-шаговый флоу: специализация → врач → время → подтверждение.
+ +Предстоящие и прошедшие. Деталь приёма с заключением.
+ +Один универсальный чат — справки, переносы, расписание.
+ +Идентификация, QR пациента, члены семьи, бонусы.
+ +Тест слуха + просмотр готового результата.
+ +Прототип бегунка после операции — таймлайн, лекарства.
+ +Ради чего пациент не удалит приложение между визитами. Детерминированные функции — без LLM, без живого диалога с врачом. Минимум юридических и регламентных рисков.
+Главный новый объект. Диагноз, препараты с расписанием, процедуры, контрольный приём, запись в 1 клик.
+ +Детали назначения: дозировка, дни, что осталось, инструкция, побочки.
+ +Анализы, аудиограммы, снимки + статус «годен до». Критично для пред-опа.
+ +Справка ФНС, выписки, счета. 1 клик. Готовая в приложении.
+ +Альтернативная главная для повторных. Активный диагноз, день курса, что делать сегодня.
+ +Не забыть карту/анализы, маршрут до кабинета, тригеры 24ч/2ч/15мин.
+ +Сводка: первичный → процедуры → контроль. Видна траектория.
+ +Переключение между профилями ребёнка/пожилого. Критично для аденоидов и ЧБД.
+ +Живой и AI-диалог по поводу лечения. Поверх стабильной Фазы 1. Требует регламентов SLA, безопасности и отдельной выкладки — поэтому отделено от Фазы 1.
+Дежурный врач/фельдшер по протоколам. 80% рутины, эскалация лечащему. Не прямой чат с врачом.
+ +Знает базу знаний клиники, план лечения. Сначала shadow-mode под валидацией консьержа.
+ +Куда писать: оператор, консьерж или AI. Без когнитивной нагрузки на пациента.
+ +«Норма / срочно / неотложно» — AI оценивает и эскалирует к консьержу или 112.
+ +Углубление по приоритетным группам сегментов. Порядок запуска: A → C → B → D. Каждый модуль опирается на план лечения и медкарту из Фазы 1.
++ Промывания, полоскания, ингаляции. Видео-библиотека техник + ежедневный трекер + дневник симптомов в связке. Главный мотиватор — «промываю 5 дней, насморк уменьшился с 4 до 2». +
+10–15 видео-инструкций: промывание, полоскание, ингаляция.
+ +Ежедневные отметки, стрики, сводка для врача.
+ +Видна динамика — главный мотиватор продолжать.
+ +Утро/день/вечер из плана. Уведомления.
+ ++ Закрывает FESS, аденоиды, вазотомию. Две половины: сомневающиеся после пред-оп приёма и решившиеся в 6-недельной подготовке. У нас уже есть прототип «Восстановление» — это вторая половина. +
+Кейсы, метод (FESS/лазер), цена/рассрочка, чат с хирургом.
+ +Чек-листы, анализы (срок годности!), запись на операцию.
+ +Что взять, во сколько, голод, маршрут, контакт.
+ +Уже в прототипе — основа второй половины Группы C.
+ ++ Возврат после демо (2–3 мес «уходят думать») + обслуживание после покупки. Каталог как маркетплейс, аудио-демо, паспорт аппарата, шеринг с близким, сервисный календарь. +
+Маркетплейс моделей с калькулятором, рассрочкой, шерингом.
+ +Сравнение «без аппарата / с аппаратом» в наушниках. На любом устройстве.
+ +Сервисный календарь, расходники, калибровка раз в год.
+ +Первые 90 дней с аппаратом — сложности, успехи, советы.
+ ++ Курс 3–5 лет: «не начал», «бросил в первые месяцы». Ежедневный дневник симптомов, пыльцевой календарь, навигатор побочки. Без верификации аллерголога не запускаем. +
+Прогноз концентрации аллергена на неделю вперёд.
+ +Чихание, заложенность, глаза. Видит аллерголог перед визитом.
+ +Зуд, отёк — норма / осторожно / срочно. Удерживает на курсе.
+ +Видеть длинный путь — главный мотив не бросить.
+ +Бизнес-сегментация клиники наложена на фазы. Видно, какой модуль закрывает какие сегменты и где у нас «не делаем».
+| Сегмент | +Главная работа в App (повторный) | +Группа | +Выручка / год | +Приоритет | +
|---|---|---|---|---|
| 1Заблокированный нос (FESS) | +Пред-оп бегунок · восстановление · контроль 3/6/12 мес | +C | +~30 млн | +● высокий | +
| 2Амбулаторный поток | +План лечения · процедуры самопомощи · дневник | +1 A | +~120 млн | +● высший | +
| 3Дети + аденоиды | +Семейный профиль · подготовка ребёнка · детский бегунок | +C | +~25 млн | +● высокий | +
| 4Сурдология | +Каталог · аудио-демо · паспорт аппарата · сервис | +B | +~20 млн | +● высокий | +
| 5Сложные хроники + ЧБД | +Самопомощь · АСИТ-трекер · семейный профиль | +A D | +часть 120 млн | +● высокий | +
| 6Зависимость от капель | +Возврат сомневающихся · компактный бегунок · восстановление | +C | +часть хирургии | +● высокий | +
| 7Пульмонология | +Дневник астмы · ингаляторы · триггеры | +D | +средний | +◐ средний | +
| 8Социальные храпуны | +Образовательный контент · СИПАП-трекер | +— | +низкий | +○ низкий | +
| 9Фониатрия | +Срочная запись (короткое окно) | +— | +очень низкий | +○ низкий | +
| 10Check-up + Второе мнение | +Разовая услуга · бренд Оленевой | +— | +единичный | +○ низкий | +
Клиника УГН — ЛОР, сурдология, аллергология, хирургия. Цель встречи — определить порядок развития функций: что закрываем как базу для всех пациентов, какие сегменты углубляем и в каком порядке.
+Ключевые факты о потоке пациентов и продуктовая логика
+Это совпадает с фактом «2 из 3 — повторные» и означает, что:
+Оценка существующих функций по трём уровням приоритета
+Базовые функции для всех пациентов — приоритет до любых сегментных модулей
+Набор сознательно разделён на две подфазы по риску и зависимостям: транзакционная база (детерминированные функции с понятным MVP) и коммуникационная надстройка (LLM и асинхронные каналы, требующие регламентов и безопасности). Это позволяет выпустить базу быстро и безопасно, а надстройку строить поверх уже стабильного фундамента.
+ +Функции, где пациент что-то получает или делает — без LLM и без диалога. Минимизируют риски, быстрее в запуск, дают те самые «не удалю это приложение»-причины.
+| Функция | +Статус | +Что в ней | +
|---|---|---|
| Запись на приём | +✅ есть | +Запись 24/7, ближайшие окна. | +
| Ближайший приём | +✅ есть | +Что, где, когда — снимает тревогу перед визитом. | +
| Чат с оператором | +✅ есть | +Справки, переносы, счета, расписание (человеческий канал). | +
| Статьи / база знаний | +✅ есть | +Уже есть. Источник правды для будущего RAG. | +
| План лечения с приёма | +❌ нет — фундамент | +После каждого приёма структурированный чеклист: диагноз, назначения (препарат + доза + курс + календарь), ссылки на процедуры самопомощи, контрольный приём, запись на следующий визит в 1 клик. Живой объект с напоминаниями. Источник правды для всех следующих надстроек. | +
| Результаты обследований и медкарта | +❌ нет | +Пациент видит свои анализы, аудиограммы, снимки, заключения без звонка в клинику. Статус каждого результата: готов / в работе / годен до [дата]. Критично для Группы C: срок годности анализов виден в одном месте. | +
| Заказ справок и финансовых документов | +❌ нет | +Справка для налогового вычета (13%), справки работодателю, копии заключений, счета. Заказ в 1 клик, готовая в приложении или с самовывозом. Снимает нагрузку с администраторов и даёт сильный retention-якорь. | +
Функции, где идёт живой или AI-диалог по поводу лечения. Строятся поверх уже работающей базы и требуют отдельных регламентов — по ответственности, SLA, проверке качества.
+| Функция | +Статус | +Что в ней | +Ключевой риск | +
|---|---|---|---|
| Чат с медицинским консьержем | +❌ нет | +Не прямой чат с лечащим врачом. Дежурный врач / фельдшер / медсестра отвечает по протоколам на 80% рутины, эскалирует клинически значимое лечащему. Асинхронно, SLA — X часов в рабочее время. | +Перегрузка врачей и SLA-хаос, если пустить пациентов напрямую к хирургу. Нужен регламент тарификации/компенсации врачам за эскалированные вопросы. | +
| AI-помощник (RAG 24/7) | +❌ нет | +Знает базу знаний клиники, статьи, план лечения пациента. Объясняет назначение, ищет ответ в статьях, оценивает «норма или срочно» и эскалирует к консьержу/врачу при тревожных признаках. | +Галлюцинация LLM в медицинском контексте = юридический и репутационный риск. Запускаем в shadow-mode: ответы сначала идут через консьержа для валидации. | +
Фаза 1:
+Фаза 1.5 (после стабилизации Фазы 1):
+Первичный vs повторный · матрица 10 сегментов · четыре группы
+| Линза | Первичный в приложении | Повторный в приложении |
|---|---|---|
| Главный job | «Куда мне обратиться и как записаться» | «Что мне делать сейчас по моему лечению» |
| Источник | Попадает через сайт/рекламу/сарафан | Приложение уже установлено |
| Частота открытия | 1–3 раза до визита | Ежедневно в активном эпизоде |
| Что нужно | Базовый минимум (запись, цены, контакты, врачи) | Специализированный модуль сегмента |
| Приоритет развития | ○ Низкий | ● Высокий (2/3 потока) |
| # | Сегмент | Объём | Повторный в App | Группа | Приоритет |
|---|---|---|---|---|---|
| 1 | +Взрослые «заблокированный нос» (полипы, FESS) | +300 оп/год · 30 млн | +Пред-оп бегунок (6 нед) → восстановление → контроль 3/6/12 мес | +C | +● Высокий | +
| 2 | +Амбулаторный поток (острые и хроники ЛОР) | +Тысячи/мес · 120 млн | +План лечения + процедуры самопомощи: промывания, полоскания, ингаляции | +1 A | +● Высший | +
| 3 | +Родители детей с аденоидами | +400–500 оп/год · 20–30 млн | +Пред-оп бегунок (детская версия) → восстановление | +C | +● Высокий | +
| 4 | +Потеря слуха (сурдология) | +20 млн/год | +Паспорт аппарата, сервисный календарь, расходники, дневник адаптации | +B | +● Высокий | +
| 5 | +Сложные хроники (иммунология, ЧБД) | +Высокий · длинный LTV | +Процедуры самопомощи (Группа A) + АСИТ-трекер | +A D | +● Высокий | +
| 6 | +Зависимость от капель (вазотомия) | +Высокий объём · входной в хирургию | +Пред-оп бегунок (компактная версия) → восстановление | +C | +● Высокий | +
| 7 | +Пульмонология (кашель/астма) | +Средний · сезонный | +Дневник астмы, напоминания об ингаляторах, контроль триггеров | +D | +◐ Средний | +
| 8 | +Социально активные храпуны | +Низкий | +Образовательный контент, СИПАП-трекер | +— | +○ Низкий | +
| 9 | +Фониатрия (голос) | +Очень низкий · срочный | +Короткое окно, низкая повторность | +— | +○ Низкий | +
| 10 | +Check-up и Второе мнение | +Единичный · высокая маржа | +Разовая услуга, минимальная повторность | +— | +○ Низкий | +
Рекомендуемая последовательность фаз и групп
+План лечения → Результаты / медкарта → Заказ справок.
+Эффект: пациент видит свои назначения, результаты и может получить документы без звонка в клинику. Базовые retention-якоря: «не удалю это приложение». Массовый амбулаторный + хроники покрыты в части информирования и документов.
+Чат с медицинским консьержем → AI-помощник (shadow-mode).
+Выделение в 1.5 позволяет: собрать транзакционную базу быстро и безопасно, отработать регламент консьержа отдельно, запустить AI сначала под валидацией человека.
+Открытые вопросы, требующие ответа от клиники
+Итог встречи в четырёх пунктах
+