amorson.me

Мультиклиника: 40 клиник · 4 страны

Ночь 16→17.07.2026 · анализ кода трёх репо + ресёрч (методички колл-центров, multi-location продукты, регуляторика ЕС). Материал для обсуждения — здесь развилки с вариантами, а не решения. Пометки: код = проверено по коду, вывод = моя оценка, [источник] = внешний ресёрч.

Как читать за 30 секунд:карта модулей — из чего состоит задача и что на что влияет → ② по каждому модулю: как сейчас / что нужно → ③ три развилки с вариантами и плюсами/минусами → ④ подводные камни → ⑤ вопросы, без ответов на которые проектировать рано.
2боевые клиники сегодня (trent, soyuz)
0понятий «сеть / город / филиал» в коде
40×4клиник × страны в постановке
3+2развилки: 3 здесь + 2 на /onpremis

Звонок сегодня vs звонок в целевой картине

Сейчас — весь SIP-трафик идёт в одну клинику:

📞 Пациент звонит на единственный номер
АТС: любой набранный номер (DID) сливается в одну точку — номер, на который звонили, теряется
Воркер голоса: клиника прибита переменной окружения (…CLINIC=trent)
Ядро: identity, слоты, запись — всё в рамках одной клиники, чужая клиника = 403

Надо — номер страны, выбор клиники в диалоге:

📞 Номер страны → язык, транк, правовой контур
DID сохраняем и передаём дальше
Узнали пациента → его «домашняя» клиника; не узнали → город → район → дефолтная клиника города
Слоты: сначала время в выбранной клинике, потом соседняя клиника города, потом лист ожидания
Бронь в целевой клинике / перевод звонка на её локальный номер (механизм перевода уже готов)

Карта модулей и связей

Девять модулей. Синие — рантайм звонка, жёлтые — данные/справочники, нижний ряд — опорные слои. Пунктирная рамка — M9 (комплаенс): ограничивает всё.

M9 Комплаенс — рамка для всех модулей: AI Act (бот представляется), GDPR, запись звонков M1 Телефония номера стран, DID, транки M2 Каскад выбора клиники в диалоге M5 Слоты и бронь cross-clinic предложение M3 Реестр сети страна→город→клиника, дефолты M4 Пациент сети identity, домашняя клиника M6 CRM / PMS адаптеры, расписания врачей M7 Языки и голос STT/TTS/нормализация ×4 M8 Операционка hub: роли, деплой 40, метрики

Стрелки: M1→M2 (телефония даёт вход каскаду), M2→M5 (каскад ведёт к слотам), M3→M2 и M4→M2 (реестр и пациент кормят каскад), M3→M5 (реестр говорит слотам, какие клиники в городе), M6→M5 (слоты живут в CRM). Нижний ряд — опоры: языковой стек нужен диалогу, hub ведёт реестр, роли и метрики.

Модули

M1

Телефония: номера стран, DID, перевод

СейчасОдин RU-номер (Telfin, донабор). АТС теряет DID на первом шаге — «какой номер набрали» до агента не доходит. Перевод звонка: blind (без возврата, не взяли трубку — звонок потерян), исходящие только через RU-транк.
НадоНомер на страну (Испания: 902 запрещён для услуг здоровья → 900/географический; DID требуют местный юрадрес). DID доносится до агента → страна/язык. Перевод: warm-handoff на локальный номер клиники, транк per страна, failover на живую линию.
Камни
  • Испания: Ley 11/2022 запрещает 902 как канал обслуживания для «protección de la salud»; CNMC штрафует. Geo-DID → proof of address зоны номера; провайдер зарегистрирован в CNMC. Германия: geo-номер только с адресом в городе, иначе 032.
  • Гео по caller ID — лишь подсказка: мобильные не привязаны к городу; анонимные звонки.
  • Наш transfer — SIP REFER без возврата: «не дозвонились в клинику» = потерянный пациент. Нужен warm transfer + очередь + callback-обещание.
  • Если агент лёг — маршрут failover на прямые номера клиник должен жить у телеком-оператора, не у нас.
  • Портирование существующих номеров клиник в ЕС — процедура на недели–месяцы (страна-зависимо), закладывать в план пилота.
  • Конфиг транка/dispatch-правил сейчас не в репо (руками через CLI) — для 4 стран обязателен IaC.
M2

Каскад выбора клиники в диалоге

СейчасВыбора нет: клиника фиксирована до начала разговора (env). Адрес клиники в ответах о записи не звучит.
НадоКаскад: ① DID/линия → страна и, если номер клиники, сразу клиника ② узнали пациента → «как обычно, в …?» ③ новый → город → дефолтная клиника города ④ район/«ближе к дому или работе» — только если пациенту важно.
1️⃣ Время в выбранной клинике — правило двух слотов: «среда 18:00 или четверг 10:00?»
не подошло
2️⃣ Соседняя клиника города — с адресом и выгодой: «в X ближайшее через 2 недели, в Y — завтра, это 15 минут дальше»
не подошло
3️⃣ Лист ожидания + callback при освобождении. Никогда не заканчивать «записи нет».
Камни
  • Дефолт ≠ навязывание: право пациента выбирать клинику/врача — закон (РФ 323-ФЗ ст.21; Испания Ley 41/2002). Формулировки через выгоду, на «а какие ещё есть?» — честный список.
  • Перед оффером соседней клиники проверить: там есть услуга, врач, страховка/цены сопоставимы. «Есть слот» ≠ «есть услуга».
  • Смена филиала при переносе — только с явным подтверждением вслух (грабля «приехал не туда» задокументирована у всех PMS).
  • Повторный пациент привязан к врачу сильнее, чем к клинике: «вам важнее ваш врач или время?» Врач ездит по филиалам по дням — искать его слоты по всем его локациям.
  • Пациент с планом лечения (орто/импланты) не переливается автоматом.
  • Минимум вопросов до брони; вопрос локации — последний fallback, не первый шаг.
  • Острая боль: фикс-скрипт red-flags, без триажа; в какой клинике города сегодня принимают острых — таких данных у нас нет вообще.
M3

Реестр сети: страна → город → клиника

СейчасHub: плоский список клиник без города/страны/языка/таймзоны/групп. Ядро: гео = одна строка адреса в YAML, 26 копипаст-файлов без схемы и валидатора; отсутствующий файл молча даёт пустую клинику.
НадоИерархия: страна (номер, языки, транк, праздники) → город (клиники, дефолтная, TZ) → клиника (адрес+район+гео, часы, врачи с днями, услуги, страховые, языки персонала, валюта, локальный номер). Центральные дефолты + локальные оверрайды + валидация схемы.
Камни
  • «Дефолтная клиника города» — чьё правило? Загрузка/маржа/своя-франчайзи/территория — бизнес-политика, из кода не выводится. Главный вопрос созвона.
  • Конфиг-дрейф: уже сегодня 26 YAML руками; на 40 — умрёт без валидатора и наследования конфигов.
  • Праздники: в Испании календарь на уровне автономий; TZ: Канары ≠ материк.
  • Таймзона Москвы захардкожена в 5+ местах ядра (4 модуля + api + SQL напоминаний) — поле timezone клиники по факту не применяется к слотам и напоминаниям.
M4

Пациент уровня сети

СейчасПациент = (клиника, телефон), у каждой клиники своя БД. Один человек в 2 клиниках = 2 несвязанные записи. Телефоны нормализуются только как RU (+7) — испанский номер identity не пройдёт.
НадоОдин пациент на сеть (или федерация), «домашняя клиника» как атрибут, консент на видимость карты между юрлицами, E.164 для 4 стран.
Камни
  • GDPR: клиники — разные юрлица (тем более франчайзи) → «карта видна во всех клиниках» = передача special-category данных; нужен joint-controller/консент. Может юридически урезать фичу.
  • Миграция: дубли телефонов, «unassigned» пациенты (яма Open Dental при включении мультилокации на живой базе), конфликты ФИО из разных CRM.
  • Secondary-gate/история визитов клиник-соседей: «постоянный в X» = «новый в Y» — правила надо определить.
  • Снимки: переиспользовать свежие рентгены (не переоблучать), при разных PMS — задача на передачу, а не обещание «видно везде».
M5

Слоты и cross-clinic бронирование

СейчасСлот = врач×дата×кресло одной CRM; в типе слота нет поля «клиника»; чужой инстанс недоступен (403); кэши слотов в памяти без TTL, id слота нестабилен.
НадоАгрегатор доступности по клиникам города (услуга+страховка+врач-фильтры), clinic_id в слоте/брони, бронь в целевой клинике из одного диалога, защита от гонок с локальной регистратурой.
Камни
  • Floating providers: врач в двух клиниках по дням; «свободное» окно = дорога между площадками; расписание врача — per клиника + блок drive-time.
  • Гонки: слот увели, пока пациент думал; бронь только живым чтением/записью PMS, не кэшем.
  • Опрос «всех клиник города» = N×M запросов к CRM (у нас уже N+1 по врачам) — без агрегированного кэша с инвалидацией CRM ляжет.
  • Перелив звонков «в соседний офис» не работает (там тоже занято) — правильный паттерн: агент отвечает параллельно везде, cross-clinic — это слоты, не звонки.
M6

CRM / PMS-интеграции

СейчасАдаптеры: IDENT (чтение, MSSQL) + MedFlex (запись, RU-SaaS) + Google Sheets/mock. Для ЕС оба нерелевантны. Протокол-шов есть (интерфейс CRM), реализаций под ЕС — ноль. Понятия «филиал» внутри адаптеров нет.
НадоАдаптер(ы) под PMS заказчика (какая у них — вопрос №1), маппинг «клиника→подключение», расписания врачей per клиника, цены/валюты/страховые per клиника.
Камни
  • Неизвестная PMS = самый большой неоценённый объём работ. Если зоопарк систем (норма после M&A) — нужен middleware-слой с трансляцией типов приёмов.
  • «Поверхностная» интеграция (читать календарь без правил провайдеров/операторных) — задокументированный источник ошибочных броней.
  • Квоты/лимиты API их PMS при 40 клиниках × агрегатор доступности.
M7

Языки и голосовой стек

СейчасВсё прошито русским: STT ru-RU (облако Yandex, локальной альтернативы нет), TTS language=ru, нормализация текста/произношение/диктовка цифр — RU-логика, WAV-приветствия «Трент». EN есть как отдельная демо-клиника с лейблами промптов *_en.
НадоЯзык — параметр клиники/линии: STT/TTS/нормализация/диктовка per язык (es/en/de/…), приветствия per страна-клиника, произношение имён улиц и районов, детектор номеров E.164.
Камни
  • Качество STT на телефонном 8kHz с акцентами — лабораторный WER не переносится; пилотный замер на реальном трафике обязателен.
  • Испания: кастильский vs каталанский — уточнить требование.
  • Языки персонала клиники — атрибут реестра: предупреждать, если в выбранной клинике не говорят на языке пациента.
  • Определение конца реплики (turn-detector) уже мультиязычное и работает локально; а вот диктовка номеров и нормализация текста — переписывать per язык.
M8

Операционка: hub, роли, деплой, метрики

СейчасАдмин = ровно одна клиника, ролей «сеть/страна» нет; деплой клиник по одной SSH-ем без пиновки версии (~5–6 ручных шагов на клинику); промпты общие на флот; мониторинг есть (health/алерты).
НадоРоли: оператор сети, супервайзер страны, админ клиники. Bulk-деплой волнами с пиновкой версий и rollback. Метрики per клиника + acceptance-rate предложенной альтернативы (главная метрика фичи). Волновой rollout: пилот 2–3 клиники → шаблоны → волны по 5–8.
Камни
  • Саботаж регистратур — причина №1 провала AI-ресепшенов в сетях [ainora]: вовлекать в пилот, позиционировать «забирает звонки, которые вы ненавидите».
  • Единая таксономия типов звонков на 4 страны, иначе аналитика рассыпается.
  • KPI-рамка рынка: answer rate 95%+, конверсия новых 70–80%, no-show <5%; ~30–35% эскалаций на живого оператора — норма, а не провал.
M9

Комплаенс (накрывает всё)

СейчасПод RU-практику; записи звонков в облачный S3; PII-маскинг в трейсах есть.
НадоEU AI Act Art.50 (действует с 02.08.2026 — через 2 недели!): бот обязан представляться ботом в начале звонка. Испания: locución-уведомление о записи, DPIA до запуска, DPO у клиник, retention аудио ≤6 мес (практика), данные — special category (art.9). Country-by-country чек 4 стран.
Камни
  • Расползание функций в сторону медицинского триажа (оценка симптомов/срочности) = medical device (MDR) + high-risk по AI Act. Держать агента в административной рамке жёстко промптом и тестами.
  • Передача карт между юрлицами сети — см. M4.
  • Пилот юридически не может стартовать до DPIA заказчика — влияет на сроки продажи.

Развилки — что реально обсуждать

Развилка №1 · Как получить cross-clinic: сравнение за 30 секунд

Сегодня «1 клиника = 1 контейнер + своя БД» — это и сила (изоляция, простые инциденты), и потолок (никакого «посмотри слоты соседа»). Сначала матрица, ниже — детали вариантов.

КритерийA роутерB multi-tenantC федерацияD через PMS
Скорость до пилота быстро долго средне быстро, если PMS одна
Риск для текущего прода минимальный высокий средний минимальный
Cross-clinic слоты живой опрос + кэш нативно через кэш нативно в PMS
Identity сети отдельная задача нативно сетевой индекс если есть в PMS
Зависимость от ответа «какая PMS» средняя средняя средняя полная
Радиус инцидента роутер = страна страна+ клиника PMS = сеть
AРоутер-клиника страны поверх текущих инстансов меньше всего ломает

Отдельный инстанс «hotline-ES»: знает реестр (M3), ведёт диалог, ходит в клиники по новому read-API слотов (+бронь в целевой), переводит звонок на локальный номер. Обычные клиники не меняются.

Плюсы
  • Изоляция клиник сохраняется (и как продукт-фича для он-премиса)
  • Не трогаем синглтоны каналов/кэши ядра
  • Можно катить по стране за раз; откат тривиален
  • Ложится на готовый transfer-механизм
Минусы
  • Новый межсервисный API + авторизация между инстансами
  • Latency: опрос N клиник в реальном времени → нужен кэш доступности
  • Identity пациента всё ещё врозь (решается в развилке №2)
  • Роутер — новая точка отказа на всю страну

Затрагивает: новый сервис + read-API в ядре + M3-реестр. Ядро почти не трогаем.

BMulti-tenant ядро: один инстанс на страну/город со всеми клиниками самая большая переделка

Ядро уже умеет грузить все клиники циклом и держит per-clinic реестры графов/CRM — но каналы (Telegram и др.) — глобальные синглтоны, кэши и контекст-переменные местами без clinic_id, «одна БД на клинику» становится «одна на всех».

Плюсы
  • Cross-clinic запросы = обычные запросы в одну БД
  • Единая identity сети «бесплатно»
  • Меньше контейнеров/инфраструктуры на 40 клиник
  • Проще он-премис поставка (один стек)
Минусы
  • Чинить синглтоны каналов, глобальные кэши, fallback-граф, contextvars — ровно тот класс багов, что уже кусал (протечки между ходами)
  • Радиус поражения инцидента — вся страна, не одна клиника
  • Миграция данных 40 баз → одну
  • Дольше и рискованнее всего

Затрагивает: ядро глубоко (identity, каналы, кэши, БД), hub-деплой, миграции.

CФедерация: инстансы как есть + общий «сетевой слой» данных середина

Клиники не меняются; рядом появляется общий сервис сети: реестр клиник + сетевой индекс пациентов + агрегированный кэш доступности (клиники периодически публикуют слоты). Диалог остаётся в клинике-инстансе, который спрашивает сетевой слой.

Плюсы
  • Кэш доступности решает latency и щадит PMS
  • Сетевой индекс пациентов = аккуратная зона для GDPR-контроля (консент в одном месте)
  • Инстансы можно апгрейдить постепенно
Минусы
  • Свежесть кэша слотов ↔ гонки броней (нужна финальная проверка перед бронью)
  • Два источника правды (клиника vs сетевой слой) — дисциплина синхронизации
  • Больше движущихся частей, чем в A

Затрагивает: новый сервис данных + лёгкие правки ядра (публикация слотов, бронь по clinic_id).

DЧерез центральную PMS заказчика может схлопнуть развилку

Если у сети одна PMS на все 40 клиник с локациями внутри (как у Denticon/Ascend/Curve: единая БД, локация — атрибут) — cross-clinic слоты и единый пациент уже существуют у заказчика. Тогда наш «агрегатор» = один CRM-адаптер с фильтром по локации, и мотивация роутера/федерации сильно ослабевает.

Плюсы
  • Не строим то, что уже есть у заказчика
  • Единый пациент и слоты — из коробки PMS
  • Меньше всего нового кода
Минусы
  • Работает только если PMS действительно одна и с API
  • Полная зависимость от возможностей/лимитов чужой системы
  • Наша архитектура «инстанс на клинику» всё равно требует решения (чей контейнер ведёт диалог линии страны)

Проверяется одним вопросом заказчику — потому вопрос «какая PMS» стоит первым в списке.

Вопрос на созвон: что важнее в горизонте полугода — скорость пилота с сетью (→A/C/D) или стратегическая консолидация ядра (→B)?
Моя гипотеза (спорьте): сначала ответ про PMS (может выбрать D), иначе — эволюция A→C: роутер сначала, кэш доступности вторым шагом, консолидация ядра — только если припрёт.

Развилка №2 · Identity пациента сети

AОставить per-clinic + запрос по клиникам на звонке
Плюсы
  • Ноль миграций; карты остаются в клиниках
  • Для пилота достаточно: роутер спрашивает клиники по телефону звонящего
Минусы
  • GDPR-вопрос не исчезает: номер звонящего уходит во все клиники, факт «пациент клиники X» раскрывается — объём передачи минимальный, но юр. основание всё равно нужно
  • Нет единой истории/семейных связок между клиниками
BСетевой индекс пациентов (телефон → список клиник, домашняя клиника)
Плюсы
  • Мгновенный «домашний» лукап на звонке; карта остаётся в клинике
  • Одно место для консента и правил видимости
Минусы
  • Новый критичный сервис (PII), нужна синхронизация при регистрации пациента
  • Всё ещё нет слияния карт — только указатели
CЕдиный patient record сети (как cloud-PMS: Denticon/Ascend/Curve)
Плюсы
  • Опыт «карта доступна везде» — сильный продукт
  • Фундамент под всю аналитику сети
Минусы
  • Требует юр. основания между юрлицами (joint controller / консент) — может быть невозможно для франчайзи
  • Миграция/мердж карт — самый тяжёлый проект из всех
  • По сути дублирует PMS заказчика — а «источник правды» о пациенте обычно PMS, не мы
Вопрос на созвон: кто источник правды о пациенте — их PMS или наша платформа? И готова ли юр. структура сети к обмену данными между клиниками?
Моя гипотеза (спорьте): если PMS одна — identity сети уже существует у них, нам хватит варианта B поверх неё.

Развилка №3 · Топология телефонии

AСтрого «1 номер на страну» (постановка)
Плюсы
  • Один маркетинговый номер, простая аналитика
  • Агент один на страну — ровно наш сценарий каскада
Минусы
  • Все звонки, включая «перенесите мне на завтра» постоянных, идут через каскад выбора города
  • Локальный номер вызывает больше доверия (местные привыкли к geo-номерам)
  • Единая точка отказа страны
BГибрид: центральный номер для новых, локальные номера клиник для своих паттерн Aspen Dental
Плюсы
  • Постоянные попадают сразу в свою клинику (без каскада) — короче звонки
  • DID клиники = автоматический контекст (паттерн Weave/Mango)
  • Маркетинг всё равно получает единый номер
Минусы
  • Портирование/сохранение 40 локальных номеров — недели–месяцы, страна-зависимо
  • Сложнее объяснить сети, где чей номер публикуется
CНомера клиник + центральный overflow (агент подхватывает пропущенное везде)
Плюсы
  • Минимальное вмешательство в привычки пациентов
  • Агент продаётся как «ни один звонок не потерян» — легко мерить ценность
Минусы
  • «Один номер на страну» из постановки не выполняется буквально
  • Маршруты overflow на стороне их операторов — зависимость от телекома заказчика
Вопрос на созвон: «один номер на страну» — требование заказчика дословно или наша интерпретация? Что происходит с существующими номерами клиник?
Моя гипотеза (спорьте): гибрид B закрывает и маркетинг, и постоянных пациентов — но проверить, что заказчик вообще готов держать локальные номера.

Сводный каталог подводных камней

Полные списки — внутри модулей выше. Здесь — топ-12 по способности сорвать проект.

  1. Неизвестная PMS заказчика — до ответа на это оценивать сроки нельзя (M6, развилка №1-D).
  2. AI Act Art.50 с 02.08.2026 — бот обязан представляться; это про прод уже сейчас (M9).
  3. Передача карт между юрлицами — может юридически запретить «единого пациента сети» (M4).
  4. Правило дефолтной клиники — политика, а не техника; без владельца правила фича заглохнет (M3).
  5. Запись звонков в Испании — locución + retention + special category (M9).
  6. «Есть слот» ≠ «есть услуга/страховка/врач» — главный источник ошибочных cross-clinic предложений (M2/M5).
  7. Гонки слотов и floating providers — брони мимо реальности (M5).
  8. Телефонные номера: 902 запрещён, DID требуют юрадрес — выбор номера = регуляторный риск (M1).
  9. STT на телефонном звуке 4 языков — качество проверять пилотом; готовой локальной замены нет (M7 / onpremis).
  10. Саботаж регистратур — главный нетехнический риск внедрения (M8).
  11. Конфиг-дрейф 40 клиник — без схемы/наследования утонем (M3/M8).
  12. Blind transfer без возврата — потерянные звонки на самом ценном шаге (M1).

Шпаргалка: как это делают другие

ПаттернКтоБерём?
Единая БД сети; локация — атрибут записиDenticon, Dentrix Ascend, Curve, Open Dental как ориентир модели
Default clinic per patient (домашняя)Open Dental да
DID = контекст локации; вопрос — последний fallbackWeave, Mango, Arini (zip-вопрос), Viva да
Cross-location offer «остаёмся в сети»Viva, CareStack ядро фичи
Подтверждение при смене локацииDentrix Ascend да, вслух
Новые → центральный 24/7; свои → локальныйAspen Dental (сеть 1000+ офисов) развилка №3-B
Missed call → SMS со ссылкой на записьDoctoralia Phone (Испания), Weave запасной канал
Провайдер привязан к локациям расписанием + дниAscend, Open Dental в модель врача
Один workflow на сеть + scorecard per клиникаArini, Dental Intelligence да
AI отвечает параллельно во всех локациях (не перелив)Viva архитектурно

Вопросы, без которых не проектировать (на созвон)

Первые три — критичные: их ответы выбирают варианты в развилках.

  1. топ PMS: какая система расписаний у 40 клиник (одна? зоопарк?), есть ли API и кто даст доступ? → размер M6, может схлопнуть развилку №1 в вариант D.
  2. топ Юрструктура: собственные клиники или франчайзи, одно юрлицо на страну? → M4 identity, балансировка, «чей пациент».
  3. топ «1 номер на страну» — дословно? Что с существующими номерами клиник? → развилка №3.
  4. Правило дефолтной клиники: кто владелец, какой критерий (загрузка/маржа/территория)? → M3.
  5. Языки по странам: Испания — кастильский/каталанский/английский? Какие остальные 3 страны? → M7.
  6. Единая карта пациента — требование или nice-to-have? Готовы ли юристы к joint-controller? → развилка №2.
  7. Врачи ездят между клиниками? → модель расписаний M5.
  8. Fallback: есть ли живой колл-центр (часы?), куда падаем при отказе агента? → M1/M8.
  9. Запись звонков: писать ли аудио, сроки, где хранить? → M9 + onpremis.
  10. Пилот: какие 2–3 клиники, какие метрики успеха, кто со стороны сети отвечает? → M8.

Грубая оценка объёмов (для калибровки ожиданий)

БлокA роутерB multi-tenantC федерация
M3 реестр сетинужен во всех вариантах — средне
M2 каскад в диалоге (промпты+тулы)одинаково — средне
M5 слоты cross-clinicсредне (read-API+кэш)крупно (ядро+БД)средне+ (кэш-сервис)
M4 identityмини (обзвон) / отдельнокрупно (миграции)средне (индекс)
M1 телефония (DID, транки, warm transfer)одинаково — средне, но с внешними зависимостями (номера, операторы, порт — недели–месяцы)
M7 языкиодинаково — средне→крупно (STT/TTS — см. /onpremis)
M6 PMS-адаптеробъём не оценить до ответа на вопрос №1
Вариант D (через PMS)объём ≈ PMS-адаптер M6 + каскад M2 — целиком зависит от ответа на вопрос №1
Разблокирующие мелочиE.164-телефоны, таймзона вместо MSK-хардкода (5+ мест), i18n es, валидатор YAML — мелко, делать в любом случае

вывод Самая тяжёлая пара — identity/изоляция БД и канальные синглтоны; LangGraph-граф и промпт-слой почти не пострадают. Куда идти — см. развилку №1 и её вопрос.


См. также: /onpremis — как это продать в контуре заказчика; /adjustment — улучшения, многие из которых — пререквизиты отсюда. Источники: код трёх репо, Open Dental / Dentrix Ascend docs, ainora.lt, Viva AI, Arini, intavia.ai, mybcat, flexbone.ai, BOE (Ley 11/2022, Ley 41/2002, RD 8/1996), artificialintelligenceact.eu, практика AEPD (Conversia/Adaptalia), методрекомендации ЦНИИОИЗ N 12-22.