Как вести сеть филиалов, точек или юрлиц в одной системе и не смешать данные объектов: три способа разделения (отдельные базы, RLS в СУБД, фильтры в коде), роли управляющего и администратора объекта, сводная отчётность по сети.
Тема: Автоматизация отраслей →Сеть филиалов ведут в одной системе через мультиарендность (мультитенантность) — архитектуру, где данные каждого объекта отделены друг от друга, а сотрудник видит только свой филиал и только свою роль. Надёжнее всего изоляцию обеспечивает сама база данных, а не условия WHERE в коде приложения: в собственной МИС DigitalOffice24 разделение клиник сделано через PostgreSQL row-level security, то есть правило доступа проверяет СУБД при каждом запросе, поэтому даже ошибка разработчика не покажет одной клинике данные другой. Продукт пока на стадии MVP, и мы говорим это прямо. Та же логика работает в проде в AI-консьерже для отельного бизнеса: сеть ведётся в одном кабинете с разделением по объектам, у каждого отеля своя база знаний и своя воронка обращений. Поверх разделённых данных строится сводная отчётность: управляющий сети видит все объекты, администратор объекта — только свой. Стоимость называем после бесплатного экспресс-аудита.
Сеть филиалов ведут в одной системе через мультиарендность: данные каждого объекта отделены на уровне архитектуры, а сотрудник видит только свой филиал и только то, что положено его роли. DigitalOffice24 закладывает такое разделение на уровне базы данных, а не фильтрами в коде приложения. Тогда одна ошибка разработчика не превращается в утечку данных соседнего объекта.
Слово «мультиарендность» (или «мультитенантность», от английского multi-tenancy) описывает простую идею: в одном здании живут несколько арендаторов, у каждого свой ключ и своя квартира, а лифт, крыша и коммуникации общие. В системе роль арендатора играет объект — филиал, точка, клиника, отель или отдельное юридическое лицо. Код, обновления и инфраструктура общие для всех, а данные — нет.
Практическая разница видна на второй месяц эксплуатации. Без мультиарендности сеть заводит по отдельной системе на объект, и дальше каждое обновление делается несколько раз, а сводный отчёт собирается вручную в таблице. С мультиарендностью система одна: новый филиал подключается как ещё один объект, а не как ещё один проект внедрения.
Технически задача звучит так: одна система, много объектов, данные не должны пересекаться. Способов ровно три, и отличаются они тем, где живёт правило «этот пользователь видит только свой филиал». От места, где записано это правило, зависит, что произойдёт при обычной ошибке в коде — а ошибки бывают у всех.
Первый способ — отдельная база данных на каждый объект. Изоляция максимальная: физически разные базы не пересекаются никак. Платить за это приходится эксплуатацией — обновление структуры данных надо накатить на каждую базу, а сводный отчёт по сети приходится собирать из нескольких источников. Для сети из десятков точек это заметная постоянная работа.
Второй способ — row-level security (RLS), построчная защита на уровне самой СУБД. В таблицах остаются данные всех объектов, но база данных сама проверяет при каждом запросе, какие строки разрешено вернуть этому пользователю. Запрос без нужного контекста просто не получит чужие строки — не потому, что программист добавил условие, а потому, что так устроена база. Проговорим это явно, потому что это ключевая деталь: изоляция делается через row-level security на уровне СУБД, а не через WHERE в коде приложения.
Третий способ — фильтры в коде приложения: к каждому запросу вручную дописывается условие «где филиал = такой-то». Это самый дешёвый и самый распространённый вариант, и он работает ровно до первой забытой строчки. Один новый отчёт, одна выгрузка, один рефакторинг — и данные одного объекта показываются другому, причём тихо, без ошибки в логе. Именно поэтому в системах с чувствительными данными мы этот способ как основной не используем.
| Критерий | Отдельная база на объект | RLS на уровне СУБД | Фильтры в коде приложения |
|---|---|---|---|
| Где живёт правило доступа | В инфраструктуре: у каждого объекта своя база и своё подключение. | В самой базе данных: политика доступа применяется к каждому запросу автоматически. | В коде: условие дописывается разработчиком в каждом запросе и отчёте. |
| Что будет при ошибке разработчика | Чужие данные недоступны физически — подключение ведёт только к своей базе. | Строки чужого объекта не вернутся: их отсекает СУБД, даже если в коде забыли условие. | Данные одного объекта могут показаться другому без всякой ошибки в логе. |
| Сводная отчётность по сети | Сложнее всего: данные собираются из нескольких баз и сводятся отдельно. | Строится штатно: роль с правом видеть все объекты получает срез по сети из тех же таблиц. | Строится легко, но правильность цифр держится на аккуратности кода отчёта. |
| Подключение нового филиала | Создание и настройка ещё одной базы, отдельный контур обновлений. | Заведение объекта в системе: структура данных и код общие для всех. | Заведение объекта в системе, но каждый новый запрос — снова ручная ответственность. |
| Эксплуатация и обновления | Каждое изменение структуры накатывается на все базы отдельно. | Одно обновление на всю сеть: база одна, политики доступа общие. | Одно обновление на всю сеть, но объём ручных проверок растёт с числом отчётов. |
| Когда это оправдано | Жёсткие требования обособить данные клиента или юрлица, единичные крупные арендаторы. | Сеть объектов с чувствительными данными и общей отчётностью — медицина, услуги, несколько юрлиц. | Внутренние некритичные системы, где цена случайной утечки между объектами невысока. |
Разделение данных отвечает на вопрос «чьи это записи», роли — на вопрос «что с ними можно делать». Это два разных механизма, и подменять один другим нельзя: без разделения по объектам роль администратора откроет всю сеть, а без ролей сотрудник увидит внутри своего филиала лишнее — зарплаты, себестоимость, персональные данные коллег. В отраслевых системах мы делаем ролевые рабочие места: каждый сотрудник видит свой маршрут и свои функции, а не общий экран с половиной отключённых кнопок.
Базовая схема для сети — три уровня. Управляющий сети видит все объекты и сводные показатели, но обычно не работает в операционке конкретной точки. Администратор объекта видит свой филиал целиком: расписание, сотрудников, выручку, клиентскую базу — и не видит соседний. Линейный сотрудник видит свой участок работы внутри объекта: свои записи, свои задачи, своих клиентов. Отдельно стоит роль поддержки со стороны подрядчика — её объём доступа стоит ограничивать и журналировать.
Отдельный вопрос — несколько юрлиц. Сеть часто устроена так, что объекты оформлены на разные компании: свои договоры, свои документы, свой расчётный счёт. Арендатором в системе тогда становится юрлицо, а филиалы живут внутри него. Это тот же механизм разделения, просто на другом уровне иерархии, и закладывать его лучше сразу: перевести систему с плоской структуры на двухуровневую после запуска — это переделка, а не настройка.
Про матрицу доступа полезно договориться до разработки, а не после. Мы просим клиента выписать роли строками, а объекты и разделы системы — столбцами, и заполнить клетки словами «видит», «редактирует», «не видит». Такая таблица на одну страницу снимает больше споров, чем десять созвонов, и сразу показывает спорные места: например, видит ли администратор одного филиала клиентов другого, если клиент ходит в оба.
Сводный отчёт по сети — главная причина, по которой изоляцию данных ломают собственными руками. Логика обычно такая: раз отчёту нужны все объекты, дадим ему доступ ко всему. Появляется сервис или пользователь с полными правами, который читает данные мимо всех правил — и вместе с ним появляется дыра, через которую можно достать что угодно, если ошибиться в фильтре отчёта или в правах на сам отчёт.
Рабочий подход другой: сводная отчётность — это тоже роль, а не обход правил. Управляющему сети выдаётся право видеть все объекты, и агрегаты считаются по тем же изолированным данным, что видит операционка. Разница принципиальная: в первом случае разделение обходится, во втором — расширяется до нужного набора объектов. Если завтра управляющему оставили только пять точек из восьми, отчёт автоматически сузится, а не покажет лишнее.
Вторая ловушка — справочники. Услуги, категории, статусы сделок и причины отказов должны быть общими для сети, иначе сравнивать объекты нечем: в одном филиале услуга называется так, в другом иначе, и сводная цифра складывается из разного. Поэтому мы разделяем данные операций и общие справочники: первые принадлежат объекту, вторые — сети. Локальные отклонения при этом остаются возможны, но заводятся как исключение к общему справочнику, а не как отдельный список.
Третье — методика расчёта. Показатель «выручка объекта» должен считаться одинаково во всех филиалах, включая одни и те же типы платежей и одни и те же правила возвратов. Иначе сравнение точек превращается в спор о цифрах, и система в этом споре бесполезна. Дальше сверху удобно ставить BI-аналитику на естественном языке: управляющий спрашивает словами «сравни выручку филиалов за июль», а не собирает выгрузку в Excel — при этом запросы идут по тем таблицам, что разрешены источниками данных, лишнего система не покажет.
Разговор об изоляции полезно вести списком конкретных вопросов, а не общим «у вас данные разделены?». На общий вопрос любой подрядчик ответит «да», потому что формально фильтр в коде — это тоже разделение. Ответы на конкретные вопросы проверяемы: механизм видно в архитектуре, журнал доступа — в интерфейсе, поведение при ошибке — на тестовом стенде за десять минут.
Самая показательная проверка — попросить продемонстрировать разделение, а не рассказать о нём. Заведите на демо-стенде два объекта, дайте сотруднику первого объекта максимальные права внутри его филиала и попробуйте достать данные второго через поиск, отчёты и выгрузки. Если система устроена правильно, чужих записей не будет ни в одном из этих мест, включая экспорт в файл — именно там разделение чаще всего забывают.
Начните с описания структуры, а не с выбора системы. Выпишите объекты и юрлица, отметьте, где данные общие для сети, а где строго свои, и составьте матрицу ролей. Этот документ на две страницы определяет архитектуру и стоимость сильнее, чем название платформы: одна и та же сеть из пяти точек может собираться и как настройка коробочной CRM, и как отраслевая система с разделением на уровне базы данных.
Дальше развилка по типу данных. Если данные не особо чувствительные, а объекты живут в одном юрлице и работают по общим процессам, часто хватает коробочной CRM с настройкой прав и структурой компании. Так устроена цифровизация сети банных комплексов, которую мы ведём: 5 объектов в Санкт-Петербурге на Битрикс24, бронирование, кафе и лояльность в одном контуре. Это пример сети из нескольких физических точек, а не пример архитектурной изоляции уровня СУБД — их не стоит путать.
Если же в системе персональные и медицинские данные, несколько юрлиц или требования 152-ФЗ, разделение переходит в архитектуру. Так сделана наша МИС: мультитенантность через PostgreSQL row-level security на уровне базы, а не через WHERE в коде приложения. Масштаб задачи виден по подготовке: при разборе аналога мы описали 1613 таблиц базы данных и 1029 роботов, а техническое задание собрали из 1619 требований — это цифры про разобранный аналог и объём ТЗ, а не про готовый продукт. Сама МИС находится на стадии MVP, и мы называем этот статус честно.
Третий вариант — когда сеть работает с клиентами через мессенджеры. AI-консьерж для отельного бизнеса, продукт hotelconcierge.ru, работает в проде и умеет вести сеть в одном кабинете с разделением по объектам: у каждого отеля своя база знаний и своя воронка в инбоксе с SLA-таймерами, тегами и заметками, а гость пишет в любой из 7 боевых каналов связи. Сложный вопрос AI передаёт живому менеджеру — человек остаётся в контуре, а не заменяется ботом.
Под задачу сети филиалов у нас три формата работы. Отраслевые системы — когда нужна своя система под процессы отрасли с мультиарендностью и требованиями 152-ФЗ в архитектуре. Заказная разработка — когда сеть нужно достроить вокруг существующего контура: личный кабинет, портал объекта, интеграции между точками. BI-аналитика — когда данные уже разделены правильно, а не хватает управленческого среза по сети. Начинается любой из них одинаково: бесплатный экспресс-аудит на 30 минут, где мы разбираем структуру сети и честно говорим, хватит ли настройки коробки или нужна архитектура. Стоимость называем после аудита, когда понятны число объектов, требования к данным и объём интеграций.
Тем, что установка одна на всю сеть, а не своя копия на каждый филиал. Одна система обслуживает несколько объектов — филиалов, точек или юрлиц, — а данные каждого отделены от остальных. Аналогия с домом: инфраструктура, лифт и крыша общие, но у каждого арендатора свой ключ и своя квартира. Разница видна в эксплуатации: обновления и доработки делаются один раз на всю сеть, а не повторяются в каждой копии, при этом сотрудник филиала видит только свой объект.
Тем, что правило доступа проверяет сама база данных, а не программист в каждом запросе. При подходе «фильтр в коде» достаточно одной забытой строчки в новом отчёте или выгрузке, чтобы данные одного объекта показались другому — и это не вызовет ошибки, просто покажет лишнее. В нашей МИС мультитенантность сделана через PostgreSQL row-level security на уровне СУБД, а не через условия WHERE в коде: даже ошибка разработчика не даст одной клинике увидеть данные другой.
Да, это тот же механизм разделения, только на другом уровне иерархии: арендатором становится юрлицо, а филиалы живут внутри него. Важно заложить двухуровневую структуру сразу — перевод плоской системы «один объект = один арендатор» на схему «юрлицо → филиалы» после запуска обычно оказывается переделкой, а не настройкой. На аудите мы спрашиваем про юрлица в первую очередь именно поэтому.
Часто да — если объекты работают по общим процессам, а данные не требуют архитектурной изоляции. Разделение видимости там строится правами доступа и структурой компании, и для сети точек одного бизнеса этого обычно достаточно. Пример из нашей практики — сеть из 5 банных комплексов в Санкт-Петербурге на Битрикс24, где в одном контуре живут бронирование, кафе и программа лояльности. Когда в системе появляются медицинские или иные чувствительные данные и несколько юрлиц, разделение стоит переносить на уровень базы данных.
Через роль, которой разрешено видеть нужный набор объектов, а не через служебный доступ в обход разделения. Тогда сводные цифры считаются по тем же данным, что видит операционка, а сужение прав автоматически сужает отчёт. Ещё два условия — общие справочники услуг и статусов для всей сети и единая методика расчёта показателей: без них сравнение объектов превращается в спор о том, что именно посчитали.
Попросите показать, а не рассказать. На демо-стенде заводятся два объекта, сотруднику первого выдаются максимальные права внутри его филиала, и вы пробуете достать данные второго через поиск, отчёты и выгрузку в файл. Экспорт проверяйте обязательно — именно там разделение забывают чаще всего. Параллельно уточните механизм: отдельные базы, row-level security в СУБД или условия в коде — и есть ли журнал доступа к карточкам и отчётам.