Aura. Техническое задание Предложение Макеты ТЗ Спецификация

Aura — Техническое задание

Версия 1.0 · 10 августа 2026 · направление «лечебный массаж»


1. Обзор и цели

1.1. Что это

Aura — система управления клиникой лечебного массажа: внутренняя CRM с медицинской картой пациента, ИИ-ассистент записи в мессенджерах, подсистема маркетинговой аналитики с расчётом ROI и клиентское приложение (PWA).

Система состоит из четырёх кабинетов — пациента, сотрудника, маркетолога и администратора — работающих поверх общего ядра.

1.2. Контекст внедрения

1.3. Цели

  1. Убрать ручную работу администратора на записи: ИИ обрабатывает входящий поток в мессенджерах круглосуточно и сам создаёт записи в расписании.
  2. Дать массажисту полноценную медицинскую карту: анкета здоровья, противопоказания, карта тела, план курса, протокол каждого сеанса.
  3. Считать честный ROI по рекламным кампаниям, а не только количество лидов.
  4. Повысить завершаемость курсов через напоминания, бонусы и абонементы.

1.4. Метрики успеха MVP

Метрика Целевое значение
Доля записей, созданных ИИ без участия человека ≥ 60 %
Доля эскалаций ИИ на человека ≤ 25 % диалогов
No-show снижение на 30 % относительно текущего
Завершаемость назначенных курсов ≥ 70 %
Время закрытия визита сотрудником ≤ 60 сек

1.5. Не цели


2. Роли и матрица прав

Действие Пациент Сотрудник Маркетолог Администратор
Своя анкета здоровья
Медкарта любого пациента
Протокол сеанса ○ (публичная часть)
Красные флаги
Расписание ○ свободные слоты
Своя запись: создать / перенести / отменить
Список пациентов
Специалисты, смены, услуги, прайс
Платежи и бонусы ○ свои ○ агрегаты без ФИО
Кампании, таргеты, воронка, ROI
Персональный путь клиента в маркетинге ○ псевдонимно
Модели ИИ, база знаний, промпты
Ключи каналов, Meta Ads ○ статус
Сотрудники и роли
Аудит доступа к медданным ○ свои действия
Настройки клиники

✎ — запись и чтение, ○ — только чтение, ✗ — доступ явно запрещён, — — нерелевантно.

Принцип разделения: маркетолог никогда не получает медицинские данные. В его кабинете пациент представлен идентификатором, датами визитов и суммами. Экран «путь клиента» показывает касания и записи, но не диагнозы, не жалобы и не ФИО — только ID 004821.


3. Глоссарий и ключевые сущности

Термин Определение
Пациент Физическое лицо с картой в системе. Имеет ID клиента (6 цифр).
Карта пациента Совокупность идентификации, анкеты здоровья, красных флагов, согласий, курсов, протоколов, коммерции и поведения.
Красный флаг Противопоказание с классом (абсолютное / относительное / локальное), сроком действия и автором.
Услуга Тип массажа с длительностью, ценой и требованиями к специалисту.
Специалист Массажист. Имеет перечень услуг, график смен и отпуска.
Кабинет Физический ресурс. Занятость кабинета — ограничение при подборе слота.
Смена Интервал доступности специалиста в конкретный день.
Слот Вычисляемый на лету свободный интервал: специалист свободен, кабинет свободен, интервал внутри смены, влезает длительность услуги плюс буфер.
Запись (appointment) Забронированный слот: пациент, услуга, специалист, кабинет, время, статус, канал создания.
Визит Состоявшаяся запись. Имеет протокол сеанса и платёж.
Курс План из N сеансов одной услуги с периодичностью и целью.
Протокол сеанса Запись массажиста по формату SOAP за один визит.
Абонемент Предоплаченный пакет сеансов с остатком и сроком действия.
Баллы Кэшбэк-валюта. Начисляется процентом от чека, списывается частью оплаты.
Уровень лояльности Статус по накопленной сумме визитов, даёт постоянную скидку.
Диалог Переписка пациента с ИИ в одном канале. Имеет статус и историю.
Эскалация Перевод диалога на сотрудника. ИИ прекращает отвечать.
Кампания Рекламная активность: название, meta_campaign_id, набор UTM, период, расход.
Таргет Именованное условие достижения: URL-паттерн, экран PWA или событие.
Касание (touchpoint) Факт контакта: визит на таргет, клик по объявлению, старт диалога.
anonymous_id Идентификатор неавторизованного посетителя в localStorage. Сшивается с patient_id при первой записи.

4. Сквозные сценарии

4.1. Первичный пациент из рекламы

Экраны разделаЧат с ассистентомоткрыть ↗Путь клиентаоткрыть ↗Расписание дняоткрыть ↗

Пациент видит объявление в Instagram → переходит на сайт клиники (сниппет создаёт anonymous_id, пишет касание с UTM) → читает страницу услуги (попадание в таргет «Страница услуги») → пишет в WhatsApp → ИИ здоровается на языке обращения, не находит пациента по номеру, задаёт короткий скрининг (жалоба, острая боль или нет, был ли у врача) → предлагает три ближайших слота на первичную консультацию → создаёт запись и карту пациента → присылает подтверждение и ссылку на анкету здоровья в PWA → anonymous_id сшивается с новым patient_id, все касания привязываются к пациенту ретроактивно.

4.2. Первый визит

Экраны разделаПротокол сеансаоткрыть ↗Закрытие визитаоткрыть ↗Детали визитаоткрыть ↗

Пациент приходит → сотрудник открывает запись, видит заполненную анкету и предупреждение «не заполнено информированное согласие» → даёт подписать ИДС → массажист проводит сеанс, отмечает на карте тела гипертонус и триггерные точки, заполняет протокол SOAP, назначает курс из 10 сеансов с периодичностью 2 раза в неделю → сотрудник закрывает визит: сумма, способ оплаты, начисление баллов → пациент получает в WhatsApp благодарность, публичную часть рекомендаций и предложение записаться на следующий сеанс курса.

4.3. Пациент в курсе записывается повторно

Экраны разделаЧат с ассистентомоткрыть ↗Выбор времениоткрыть ↗План курсаоткрыть ↗

Пациент пишет «когда можно на следующий?» в Telegram → ИИ узнаёт по номеру, видит активный курс 4/10 и прикреплённого специалиста → предлагает слоты именно у него с шагом, соответствующим периодичности курса → создаёт запись → счётчик курса не меняется до факта визита.

4.4. Красный флаг блокирует ИИ

Экраны разделаЭскалации ассистентаоткрыть ↗Карта · здоровьеоткрыть ↗

Пациент пишет «хочу записаться» → ИИ узнаёт пациента, видит активный абсолютный красный флаг «тромбофлебит, установлен 03.08» → не создаёт запись, отвечает нейтрально («нужно уточнить у специалиста»), создаёт эскалацию с пометкой «абсолютное противопоказание» → сотрудник видит диалог в ai-inbox с красной плашкой и разбирается вручную.

4.5. Маркетолог считает ROI

Экраны разделаДашборд ROIоткрыть ↗Сквозная воронкаоткрыть ↗

Маркетолог заводит кампанию: название, meta_campaign_id, UTM-набор через конструктор → система тянет spend из Meta Ads API раз в сутки → на дашборде видит две цифры: ROI сделки (по last_touch) и ROI LTV (по first_touch) → в воронке видит, что провал между «попадание в таргет» и «старт диалога», а не между «диалог» и «запись» → делает вывод, что проблема в посадочной странице.

4.6. Возвратная кампания

Экраны разделаКампанииоткрыть ↗Настройкиоткрыть ↗

Планировщик раз в сутки находит пациентов, у которых курс завершён 60+ дней назад и нет будущих записей → создаёт задание на рассылку в предпочитаемый канал → пациент получает сообщение → переход в PWA помечается специальным UTM → запись атрибуцируется возвратной кампании.


5. Функциональные требования по модулям

Обозначения: [E1] — этап 1 (MVP), [E2] — этап 2, [E3] — этап 3.

5.1. Аутентификация и аккаунты

Экраны разделаВходоткрыть ↗Вход сотрудникаоткрыть ↗Вход администратораоткрыть ↗

5.2. Карта пациента

Экраны разделаКарта · здоровьеоткрыть ↗Карта · профильоткрыть ↗Моя карта здоровьяоткрыть ↗

Карта состоит из восьми блоков. Блоки ① и ② доступны пациенту на редактирование, ③–⑥ — только сотруднику.

① Идентификация [E1]

Поле Тип Обязательное Примечание
client_id строка 6 цифр авто «полис», уникален, не переиспользуется
last_name, first_name, patronymic строка ✓ (первые два) кириллица
name_latin строка латиница для документов
birth_date дата считаем возраст
sex enum m/f влияет на карту тела и рекомендации
phone_primary E.164 ключ узнавания в мессенджерах, уникален
phone_secondary E.164
email email обязателен для email-уведомлений
language enum ru/en/hy язык всех коммуникаций
preferred_channel enum whatsapp / telegram / instagram / push / email
city, district строка
tags массив строк VIP, спортсмен, беременность, льгота
acquisition_source строка авто из first_touch, с ручным переопределением
first_visit_at, last_visit_at дата авто
created_by enum авто ai / staff / self

② Анкета здоровья [E1]

Заполняется пациентом в PWA или сотрудником со слов. Требует актуализации раз в 6 месяцев — по истечении срока карта показывает плашку «анкета устарела».

③ Красные флаги (противопоказания) [E1]

Отдельная сущность, не поле анкеты. Всегда отображается баннером в верхней части карты и в карточке записи.

Классы и справочник:

Поля каждого флага: class, code или свободный текст, body_zone (для локальных), set_by (кто), set_at, expires_at (для временных, пусто = постоянный), comment, status (активен / снят), resolved_at, resolved_by.

Правила системы:

④ Согласия и документы [E1]

⑤ План курса [E1]

Поля: услуга, назначено сеансов (N), периодичность (раз в N дней), зоны воздействия (по карте тела), цель курса (снять боль / восстановление после травмы / профилактика / коррекция осанки), дата начала, плановая дата окончания, прикреплённый специалист, домашние рекомендации (текст и/или файл), статус (активен / завершён / прерван), причина прерывания.

Прогресс выполнено/назначено считается по состоявшимся визитам, привязанным к курсу. Курс автоматически помечается «под угрозой», если между визитами прошло больше двойной периодичности.

⑥ Протокол сеанса [E1]

Один протокол на один визит, формат SOAP:

Протокол можно редактировать 24 часа после визита; далее правки создают новую версию с сохранением исходной и записью в аудит.

⑦ Коммерция [E1]

Баланс баллов и история операций, активные абонементы с остатком и сроком, уровень лояльности с прогрессом до следующего, история платежей, средний чек, суммарный LTV, текущая задолженность.

⑧ Поведение [E1]

first_touch (кампания, UTM, дата, посадочная страница), last_touch, лента всех касаний, число no-show, число отмен позже чем за 12 часов, процент завершённых курсов.

5.3. Расписание и запись

Экраны разделаРасписание дняоткрыть ↗Создание записиоткрыть ↗Выбор времениоткрыть ↗Подтверждениеоткрыть ↗

5.4. Визиты, протоколы, курсы

Экраны разделаПротокол сеансаоткрыть ↗План курсаоткрыть ↗Журнал визитовоткрыть ↗

5.5. Услуги, оплата, бонусы

Экраны разделаЗакрытие визитаоткрыть ↗Услуги и прайсоткрыть ↗Бонусыоткрыть ↗

5.6. ИИ-запись

Экраны разделаЧат с ассистентомоткрыть ↗Эскалации ассистентаоткрыть ↗Модели и подключенияоткрыть ↗База знанийоткрыть ↗Промпты и эскалацияоткрыть ↗

Каналы

Узнавание пациента

  1. Веб-виджет в PWA — пациент авторизован, patient_id известен.
  2. WhatsApp и Telegram — номер телефона приходит из канала, ищем по phone_primary и phone_secondary.
  3. Instagram — номера нет; ИИ спрашивает номер или ID клиента.
  4. Не найден — работаем как с новым, создаём карту после подтверждения записи.

Контекст диалога

При узнавании ИИ подгружает: имя и язык, активный курс с прогрессом и прикреплённого специалиста, дату последнего визита и услугу, активные красные флаги (только факт наличия и класс — не диагнозы), баланс баллов и абонементов, будущие записи.

Правила персонализации [E1]

Триггеры эскалации [E1]

Обязательная эскалация при: активном абсолютном красном флаге; медицинском вопросе («можно ли мне массаж при…», «что у меня болит»); жалобе или конфликте; просьбе о скидке или нестандартной цене; трёх подряд нераспознанных намерениях; явной просьбе позвать человека; сообщении с признаками экстренной ситуации.

При эскалации: диалог помечается статусом escalated, ИИ перестаёт отвечать, создаётся элемент очереди в ai-inbox, дежурный сотрудник получает уведомление. Возврат диалога к ИИ — вручную сотрудником.

Настройки ИИ (кабинет администратора) [E1]

По образцу проекта ragreply:

5.7. Маркетинг [E2]

Экраны разделаДашборд ROIоткрыть ↗Создание кампанииоткрыть ↗Таргетыоткрыть ↗Сквозная воронкаоткрыть ↗

Кампании

Поля: название, канал (Meta / Яндекс / офлайн / рассылка / прочее), external_campaign_id (для Meta — meta_campaign_id), набор UTM (utm_source, utm_medium, utm_campaign, utm_content, utm_term), период, плановый бюджет, статус.

UTM-конструктор генерирует готовую ссылку и QR-код. Все ссылки кампании отслеживаются по совпадению utm_campaign.

Расход: автоматически из Meta Ads API раз в сутки по meta_campaign_id (insights: spend, impressions, clicks) + ручной ввод расхода за период для каналов без API. Ручной ввод обязателен как механизм — не все каналы имеют API.

Таргеты

Таргет — именованное условие достижения одного из трёх типов:

  1. URL-паттерн внешнего сайта, например /services/back-massage*.
  2. Экран PWA, например booking-confirm.
  3. Событие, например chat_started, booking_created, visit_completed.

У таргета есть название, тип, условие, позиция в воронке и опциональная денежная ценность. Считаются: уникальные достижения, конверсия в следующий шаг воронки, среднее время до достижения.

Трекинг и сшивка личности

JS-сниппет ставится на внешний сайт. При первом визите создаёт anonymous_id в localStorage, при каждом заходе пишет касание: время, URL, referrer, UTM, устройство. PWA использует тот же механизм внутри приложения.

В момент авторизации или создания записи anonymous_id склеивается с patient_id; все прошлые касания этого anonymous_id привязываются к пациенту ретроактивно. Один пациент может иметь несколько anonymous_id (разные устройства) — все они привязываются к нему.

Воронка

Показы → клики → сессии → достижения таргетов (по позициям) → старт диалога → запись → состоявшийся визит → оплата → повторный визит. На каждом переходе: абсолютное число, конверсия, среднее время.

Атрибуция и ROI

Хранятся оба касания: first_touch — навсегда закрепляется за пациентом при первом контакте; last_touch — фиксируется на момент создания каждой записи.

ROI сделки = (выручка визитов с last_touch кампании − spend) / spend
ROI LTV    = (вся выручка пациентов с first_touch кампании − spend) / spend

Дополнительные метрики: CAC (spend / новые пациенты), стоимость записи, стоимость состоявшегося визита, доля no-show по кампании, средний чек первого визита, доля пациентов, дошедших до курса.

Окно атрибуции для last_touch — 30 дней, настраивается.

Возвратные кампании [E2]

Сегменты по правилам: курс завершён N дней назад и нет будущих записей; не был более N дней; купил абонемент и не использует; день рождения. Отправка в предпочитаемый канал, ссылка со служебным UTM, учёт в общей воронке. Пациенты с отозванным маркетинговым согласием исключаются автоматически.

5.8. Уведомления [E1]

Экраны разделаКаналыоткрыть ↗Настройкиоткрыть ↗
Событие Канал Тайминг
Запись создана канал записи + push сразу
Напоминание канал записи + push за 24 часа
Напоминание канал записи + push, SMS как fallback [E2] за 2 часа
Запись перенесена или отменена клиникой канал записи + push сразу
Визит завершён: публичные рекомендации канал записи + email через 1 час
Абонемент заканчивается (остался 1 сеанс) канал записи сразу
Баллы сгорают через 30 дней канал записи раз
Возвратная кампания предпочитаемый канал по расписанию сегмента

Правило одного канала: транзакционные уведомления идут в тот канал, где пациент записался, плюс Web Push, если он разрешён. Дублирование в email — только для длинных материалов (рекомендации после курса).

Тихие часы: с 21:00 до 09:00 по Asia/Yerevan нетранзакционные сообщения не отправляются, откладываются на утро.

5.9. Настройки клиники [E1]

Экраны разделаНастройки клиникиоткрыть ↗Сотрудники и ролиоткрыть ↗

Кабинеты (название, назначение, доступные услуги), часы работы по дням недели, праздничные и сокращённые дни, буферы по умолчанию, min_lead_time, окно свободной отмены, языки, валюта и формат сумм, параметры бонусной программы, пороги уровней лояльности, тексты согласий с версионированием.


6. Карта экранов

45 экранов. Пациентский кабинет — mobile-first, фрейм 420 px. Рабочие кабинеты — desktop, минимум 1280 px.

6.1. Кабинет пациента (PWA) — 13

Экраны разделаВходоткрыть ↗Анкета здоровьяоткрыть ↗Главнаяоткрыть ↗Выбор услугиоткрыть ↗Выбор времениоткрыть ↗Подтверждениеоткрыть ↗Чат с ассистентомоткрыть ↗Голосовой звонокоткрыть ↗Журнал визитовоткрыть ↗Детали визитаоткрыть ↗Моя карта здоровьяоткрыть ↗Бонусыоткрыть ↗Настройкиоткрыть ↗
# Файл Экран Этап
01 patient/auth.html Вход по телефону и коду E1
02 patient/onboarding.html Анкета здоровья и согласия, шаги E1
03 patient/home.html Ближайший визит, прогресс курса, баллы, CTA E1
04 patient/booking-service.html Выбор услуги и длительности E1
05 patient/booking-slot.html Выбор специалиста и слота E1
06 patient/booking-confirm.html Подтверждение и оплата E1
07 patient/ai-chat.html Диалог с ИИ, карточки слотов E1
08 patient/ai-call.html Голосовой звонок с ИИ E3
09 patient/visits.html Журнал визитов E1
10 patient/visit-detail.html Детали визита и рекомендации E1
11 patient/health-card.html Моя карта здоровья, карта тела E1
12 patient/bonuses.html Баллы, абонементы, уровень E1
13 patient/settings.html Язык, уведомления, согласия, установка PWA E1

6.2. Кабинет сотрудника — 14

Экраны разделаВход сотрудникаоткрыть ↗Расписание дняоткрыть ↗Неделя специалистаоткрыть ↗Создание записиоткрыть ↗Карточка записиоткрыть ↗Пациентыоткрыть ↗Карта · профильоткрыть ↗Карта · здоровьеоткрыть ↗Протокол сеансаоткрыть ↗План курсаоткрыть ↗Специалистыоткрыть ↗Услуги и прайсоткрыть ↗Закрытие визитаоткрыть ↗Эскалации ассистентаоткрыть ↗
# Файл Экран Этап
14 staff/login.html Вход сотрудника E1
15 staff/schedule-day.html Расписание дня, кабинеты колонками E1
16 staff/schedule-week.html Неделя по специалисту E1
17 staff/appointment-new.html Создание записи E1
18 staff/appointment-detail.html Карточка записи, статусы E1
19 staff/patients.html Список и поиск пациентов E1
20 staff/patient-card.html Карта пациента, вкладки E1
21 staff/patient-health.html Анкета, красные флаги, карта тела E1
22 staff/visit-protocol.html Протокол сеанса SOAP E1
23 staff/course-plan.html План курса и прогресс E1
24 staff/specialists.html Специалисты, смены, отпуска E1
25 staff/services.html Услуги и прайс E1
26 staff/checkout.html Закрытие визита и оплата E1
27 staff/ai-inbox.html Очередь эскалаций от ИИ E1

6.3. Кабинет маркетолога — 8

Экраны разделаДашборд ROIоткрыть ↗Кампанииоткрыть ↗Создание кампанииоткрыть ↗Детали кампанииоткрыть ↗Таргетыоткрыть ↗Сквозная воронкаоткрыть ↗Путь клиентаоткрыть ↗Отчётыоткрыть ↗
# Файл Экран Этап
28 marketing/dashboard.html ROI, spend, выручка, тренды E2
29 marketing/campaigns.html Список кампаний E2
30 marketing/campaign-edit.html Создание кампании, UTM-конструктор E2
31 marketing/campaign-detail.html Воронка и когорты кампании E2
32 marketing/targets.html Таргеты и код сниппета E2
33 marketing/funnel.html Сквозная воронка E2
34 marketing/customer-path.html Путь клиента по касаниям E2
35 marketing/reports.html Отчёты и экспорт E2

6.4. Кабинет администратора — 10

Экраны разделаВход администратораоткрыть ↗Обзор системыоткрыть ↗Модели и подключенияоткрыть ↗База знанийоткрыть ↗Промпты и эскалацияоткрыть ↗Каналыоткрыть ↗Meta Ads и платежиоткрыть ↗Сотрудники и ролиоткрыть ↗Аудит доступаоткрыть ↗Настройки клиникиоткрыть ↗
# Файл Экран Этап
36 admin/login.html Вход администратора с 2FA E1
37 admin/overview.html Статус интеграций и системы E1
38 admin/ai-models.html Connections и назначение моделей E1
39 admin/ai-knowledge.html Документы, чанки, эмбеддинги E1
40 admin/ai-prompts.html Промпты и правила эскалации E1
41 admin/channels.html Ключи каналов E1
42 admin/integrations.html Meta Ads, платежи, синхронизация E2
43 admin/users.html Сотрудники и роли E1
44 admin/audit-log.html Аудит доступа к медданным E1
45 admin/clinic.html Кабинеты, часы, праздники, языки E1

7. Приватность медицинских данных

Экраны разделаАудит доступаоткрыть ↗Сотрудники и ролиоткрыть ↗Путь клиентаоткрыть ↗

8. Архитектура

8.1. Общая схема

┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│  PWA пациент │  │  Кабинет     │  │  Кабинет     │  │  Кабинет     │
│  (mobile)    │  │  сотрудника  │  │  маркетолога │  │  админа      │
└──────┬───────┘  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘
       └─────────────────┴─────────┬────────┴─────────────────┘
                                   │ HTTPS / JSON
                          ┌────────▼─────────┐
                          │   API (Next.js)  │
                          │  авторизация,    │
                          │  RBAC, аудит     │
                          └────────┬─────────┘
        ┌──────────┬───────────────┼───────────────┬──────────────┐
   ┌────▼────┐ ┌───▼──────┐ ┌──────▼─────┐ ┌───────▼────┐ ┌───────▼────┐
   │Core CRM │ │Scheduling│ │ AI Booking │ │ Marketing  │ │  Channels  │
   └────┬────┘ └───┬──────┘ └──────┬─────┘ └───────┬────┘ └───────┬────┘
        └──────────┴───────┬───────┴───────────────┘              │
                    ┌──────▼───────┐                     ┌────────▼────────┐
                    │ PostgreSQL   │                     │ WhatsApp · TG   │
                    │ + pgvector   │                     │ Instagram · Push│
                    └──────┬───────┘                     │ Email · SMS     │
                           │                             └─────────────────┘
              ┌────────────┼────────────┐
        ┌─────▼─────┐ ┌────▼────┐ ┌─────▼──────┐
        │  Redis    │ │   S3    │ │  Worker    │
        │ очереди   │ │ файлы   │ │ напоминания│
        └───────────┘ └─────────┘ │ синк Meta  │
                                  │ сгорание   │
                                  └────────────┘

8.2. Стек

Обоснование: стек совпадает с ragreply, что позволяет переиспользовать готовую подсистему подключений, назначения моделей и работы с документами.

8.3. Границы и контракты

Модуль Публичный интерфейс
Scheduling GET /slots, POST /appointments, PATCH /appointments/:id, GET /schedule/day
Core CRM GET /patients/:id, PATCH /patients/:id/health, POST /visits/:id/protocol, POST /visits/:id/checkout
AI Booking POST /ai/message (вход из Channels), POST /ai/escalate
Marketing POST /track (сниппет), GET /campaigns/:id/funnel, GET /roi
Channels POST /notify (кому, что, каким каналом)

Модули общаются только через эти интерфейсы. AI Booking не пишет в таблицу записей напрямую — он вызывает POST /appointments с флагом source=ai.


9. Модель данных

Основные таблицы:

patients             id, client_id, фио, birth_date, sex, phones, email,
                     language, preferred_channel, tags[], acquisition_source,
                     first_visit_at, last_visit_at, created_by, deleted_at

health_profiles      patient_id, height, weight, complaint, complaint_age,
                     pain_level, pain_zones[], pain_character, diagnoses[],
                     injuries[], chronic[], medications[], anticoagulants,
                     allergies[], pregnancy, pregnancy_weeks, blood_pressure,
                     lifestyle{}, massage_experience{}, updated_at, updated_by

red_flags            id, patient_id, class, code, text, body_zone, set_by,
                     set_at, expires_at, status, comment, resolved_at

consents             id, patient_id, type, version, granted_at, revoked_at,
                     method, file_id

patient_files        id, patient_id, type, file_key, uploaded_by, uploaded_at,
                     visible_to_patient

specialists          id, user_id, фио, services[], bio, photo, active
shifts               id, specialist_id, weekday | date, time_from, time_to
time_off             id, specialist_id, date_from, date_to, reason
rooms                id, name, services[], active

services             id, name_ru/en/hy, duration_min, buffer_min, price_amd,
                     category, rooms[], active, description

appointments         id, patient_id, specialist_id, room_id, service_id,
                     starts_at, ends_at, status, source, course_id,
                     created_by, notes, attention_flag,
                     last_touch_campaign_id

visits               id, appointment_id, actual_duration, completed_at
protocols            id, visit_id, version, s{}, o{}, a{}, p{}, materials,
                     public_part, author_id, created_at

courses              id, patient_id, service_id, specialist_id, sessions_total,
                     sessions_done, periodicity_days, zones[], goal,
                     started_at, planned_end, status, home_recommendations

payments             id, visit_id, patient_id, amount_amd, method, discount,
                     discount_reason, points_spent, pass_id, staff_id, paid_at

loyalty_points       id, patient_id, delta, reason, visit_id, expires_at
passes               id, patient_id, service_id, sessions_total,
                     sessions_left, price_amd, valid_until, status, frozen_at
loyalty_levels       id, name, threshold_amd, discount_pct, cashback_pct

dialogs              id, patient_id, anonymous_id, channel, external_id,
                     status, language, started_at, escalated_at, escalation_reason
messages             id, dialog_id, role, text, used_chunks[], created_at

ai_connections       id, name, base_url, api_key_enc, active
ai_task_models       task, connection_id, model
knowledge_documents  id, title, file_key, lang, uploaded_at, status
knowledge_chunks     id, document_id, text, embedding vector(1536)
ai_prompts           id, key, lang, text, version

campaigns            id, name, channel, external_campaign_id, utm{}, period,
                     planned_budget, status
campaign_spend       id, campaign_id, date, amount_amd, source (api | manual)
targets              id, name, type, condition, funnel_position, value_amd
touchpoints          id, anonymous_id, patient_id, campaign_id, target_id,
                     type, url, referrer, utm{}, device, created_at
identity_links       anonymous_id, patient_id, linked_at

users                id, email, password_hash, role, totp_secret, active
audit_log            id, actor_id, action, entity, entity_id, patient_id,
                     ip, created_at
notifications        id, patient_id, channel, template, payload, scheduled_at,
                     sent_at, status
waitlist             id, patient_id, specialist_id, date, service_id, created_at

Индексы, критичные для производительности: appointments (specialist_id, starts_at), appointments (room_id, starts_at), touchpoints (anonymous_id), touchpoints (patient_id, created_at), knowledge_chunks — HNSW по embedding.


10. Нефункциональные требования

Категория Требование
Производительность Расчёт свободных слотов на 14 дней вперёд — до 300 мс. Открытие карты пациента — до 500 мс.
Отклик ИИ Первый токен ответа — до 3 с, полный ответ — до 8 с. Дольше — сообщение «секунду, проверяю расписание».
Доступность 99,5 % в часы работы клиники. Отказ ИИ не блокирует запись через PWA и сотрудника.
Целостность Двойная бронь слота невозможна на уровне БД, а не только приложения.
Безопасность HTTPS, шифрование медданных в покое, ключи API — в отдельном хранилище секретов, не в БД в открытом виде.
Аудит Неизменяемый лог доступа к медданным, хранение 3 года.
Локализация Все пользовательские строки — через файлы переводов ru/en/hy. Даты, суммы и телефоны форматируются по локали.
Мобильность PWA: офлайн-доступ к журналу визитов и ближайшей записи, установка на домашний экран, Web Push.
Доступность интерфейса Контраст не ниже WCAG AA, все действия достижимы с клавиатуры, карта тела дублируется списком зон.
Резервные копии Ежедневный бэкап БД, хранение 30 дней, ежемесячная проверка восстановления.

11. Этапы

Этап 1 — MVP

Core CRM (карта пациента целиком, визиты, протоколы, курсы), Scheduling, кабинет сотрудника, PWA пациента, кабинет администратора, ИИ-чат в веб-виджете и WhatsApp, баллы, абонементы, уровни, уведомления, оплата вручную.

Этап 2 — Маркетинг и платежи

Подсистема маркетинга целиком, JS-сниппет и сшивка личности, Meta Ads API, Telegram и Instagram, онлайн-предоплата, возвратные кампании, SMS-fallback, фотофиксация осанки.

Этап 3 — Голос и мобильное приложение

Голосовые звонки ИИ (входящие и исходящие), обёртка Capacitor, ИИ-рекомендации по содержимому карты, аналитика эффективности специалистов.

Вне скоупа

Мульти-филиальность, страховые компании и ДМС, бухгалтерия и фискализация, складской учёт, телемедицина, интеграция с госреестрами, мобильные приложения для сотрудников.


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

  1. Провайдер онлайн-платежей для этапа 2 (Idram, Telcell, ArCa, Stripe) — выбирается перед началом этапа 2.
  2. Юридическая формулировка информированного согласия — предоставляет клиника, система хранит версионированный текст.
  3. Нужна ли выгрузка в 1С или иную учётную систему — уточнить у бухгалтерии клиники.
  4. Провайдер SMS для Армении на этапе 2.