Доменные границы и ответственность команд

Целевая архитектура, платформа и эксплуатация доменов

11 октября 2026

Полевая заметка

Этот документ дополнял инженерную стратегию. В стратегии мы согласовали приоритеты и направления изменений. Здесь нужно было описать, как они отражаются в устройстве системы и ответственности команд: кому принадлежит домен, как с ним взаимодействуют другие команды, что предоставляет платформа и кто отвечает за работу в production.

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

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

Общие приоритеты и направления изменений описаны в инженерной стратегии.

Принципы

Основная цель - движение полезных изменений до production. Структура команд должна отражать задачи бизнеса. Команды строятся вокруг потоков ценности и бизнес-результатов.

Организационный дизайн рассматривается как часть архитектуры:

Устройство команд

Команды объединяются в кластеры, обычно по две-четыре команды. Кластер отвечает за один или несколько доменов. Общая ответственность разных кластеров за один домен не допускается.

Внутри кластера отдельная команда может быть закреплена за конкретным доменом. При этом ожидается, что команды знают достаточно, чтобы поддерживать любой домен своего кластера. Исключения возможны для специализированных направлений: мобильных приложений, desktop или отдельных CMS, где нужны специфичные навыки.

Выделяются три типа доменов:

Целевая модель: продуктовые кластеры владеют доменами, платформа предоставляет общие ресурсы, правила и помощь
Обобщенная схема целевой модели команд и доменов.

Ответственность и границы

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

Модульный монолит

Основу системы составляет модульный монолит на Ruby on Rails. В нем реализована большая часть бизнес-доменов. Их разделение обеспечивается непосредственно в коде.

Продуктовые домены

Продуктовые команды, выстроенные вокруг потоков ценности, отвечают за изолированные домены: Ruby namespaces с бизнес-сервисами, доменными моделями ActiveRecord, библиотеками, фоновыми задачами и интеграциями.

Модели принадлежат своим доменам. У них не должно быть прямых зависимостей и ассоциаций с моделями других доменов.

Междоменное взаимодействие допускается на сервисном уровне через явные интерфейсы:

Платформенный домен

Платформа отвечает за системные сервисы и модели, которые используются всем продуктом и не принадлежат отдельному бизнес-домену. Например, базовые механизмы аутентификации и идентификации, управление файлами и их хранение.

Одна из ключевых обязанностей платформы - защита приложения от исчерпания ресурсов одним доменом. Платформа определяет бюджеты ресурсов, предоставляет средства контроля потребления и обеспечивает изоляцию общих ресурсов.

Основные уровни защиты:

При превышении критичных порогов включается защитная деградация:

Если домен создает системный риск, деградировать должен этот домен. Остальная система должна продолжать работать.

Общие ресурсы: Redis, OpenSearch, S3

Для инфраструктурных ресурсов предусмотрены две модели ответственности.

Ресурс принадлежит домену. Продуктовая команда полностью отвечает за ресурс и его эксплуатацию, а другим командам предоставляет интерфейс. Емкость, надежность и стоимость находятся в ее ответственности. Исчерпание ресурса затрагивает только этот домен.

Примеры: отдельные Redis для очередей Sidekiq, распределенных по доменам; OpenSearch как основное хранилище отдельного домена истории действий.

Ресурс принадлежит платформе. Если его используют несколько доменов, ответственность находится у платформы. Она предоставляет API, ограничения и защиту, обеспечивает квоты, изоляцию и контролируемую деградацию.

Примеры: основная реляционная база, Redis как общий кеш, S3, системная отправка email и общий поисковый индекс OpenSearch.

Основная реляционная база

На Q1 2026 основной базой был PostgreSQL. Используется Active Record: каждой бизнес-модели соответствует таблица.

По умолчанию внешние ключи применяются только внутри домена. Междоменных внешних ключей избегаем. Исключения возможны для базовых идентификаторов, например идентификатора организации, которые нужны для multi-tenancy и row-level security.

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

По умолчанию чтение направляется на реплики, чтобы увеличить пропускную способность и снизить нагрузку на primary. Исключение - сценарии, где пользователь должен сразу увидеть собственные изменения. Тогда чтение направляется на primary или другим способом обеспечивается согласованность, чтобы избежать последствий задержки репликации.

В целевой модели горизонтальное масштабирование опирается на шардирование с учетом multi-tenant устройства системы и секционирование больших таблиц.

Большие и критичные таблицы должны находиться под постоянным наблюдением. Хранение таких данных в основной базе - явное продуктовое и инженерное решение. Оно требует контроля производительности, наблюдаемости и планирования емкости.

Состояние монолита на Q1 2026

Что уже было:

Чего не хватало:

Отдельные сервисы

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

Основная доменная логика по умолчанию остается в монолите. Для ее выделения нужно хорошо понимать границы и убедиться, что архитектурная и операционная польза оправдывает затраты.

Продуктовые домены

Каждый сервис реализует один бизнес-домен или четко определенный поддомен. Правила границ и ответственности те же, что внутри монолита:

Платформенный домен

Платформа отвечает за общую основу сервисов:

По мере развития сервисной архитектуры платформа вводит стандартные sidecar proxy. Они обеспечивают единообразную наблюдаемость, безопасность, маршрутизацию и контроль ресурсов, уменьшая объем таких реализаций в продуктовых доменах.

Состояние сервисной модели на Q1 2026

У платформы уже были определены SLO/SLI/SLA и ответственность за дежурства и on-call.

Продуктовым кластерам не хватало:

В общей сервисной основе еще не были реализованы целевые компоненты Event Bus, Auth и Gateway. Инфраструктурная поддержка была ограниченной, без sidecar и service discovery. Не было единого набора шаблонов сервисов и CI/CD, руководства по готовности к запуску и настройке окружения.

Взаимодействие команд

У каждого кластера должен быть понятный способ взаимодействия с ним. Его задают конкретные артефакты: описание доменов и границ, технические дизайны разного уровня, документация точек интеграции и прозрачный бэклог с объяснением приоритетов.

Продуктовые домены

За моделирование домена и его долгосрочное развитие отвечает Product Staff Engineer в тесном взаимодействии с Product Manager. Кластер сохраняет ответственность за реализацию и эксплуатацию.

Основные артефакты - Domain Profile и Public Interfaces. Они описывают:

Артефакты хранятся в репозитории технических дизайнов и поддерживаются через PR с ревью. Изменения границ, ответственности и интеграций должны быть видимы, прослеживаемы и проверены затронутыми командами.

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

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

Платформенный домен

У платформы три направления работы.

Платформа как внутренний продукт

Платформа разрабатывается техническим кластером. Ее план формируется из запросов продуктовых доменов, исследований и предложений платформенных Staff-инженеров, а также приоритетов технического руководства по архитектуре и безопасности.

У платформы есть конкретные внутренние пользователи, приоритеты и ожидаемые результаты.

Архитектурное управление

Платформа определяет и поддерживает долгосрочное архитектурное направление. Для этого используются документация, инструменты, метрики и ограничения, связанные с безопасностью, масштабированием и согласованностью системы.

Помощь продуктовым командам

Платформенные Staff-инженеры подключаются по запросу: помогают с дизайнами, которые вводят новые архитектурные подходы, меняют инфраструктуру, Domain Profile или требуют изменений платформы.

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

Цель - помочь командам применять целевую архитектуру и устранять системные риски. Ответственность за продуктовую логику остается у владельца домена.

Примеры и антипаттерны

Работа с доменами

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

Дублирование существующих возможностей: отдельные таблицы истории вместо использования домена истории действий; собственная реализация массового обновления вместо доменного асинхронного интерфейса.

Смешивание ответственности: модель пользователя одновременно хранит аутентификацию, подписи email и настройки уведомлений; модель организации собирает настройки нескольких несвязанных доменов.

Реализация вне границ домена: отдельный чат создается за пределами домена коммуникаций.

Работа платформы

Ожидаемый подход: платформенные Staff-инженеры помогают с техническим дизайном и анализом инцидентов. Например, с выбором OpenSearch как основного хранилища домена, системными исправлениями после повторных платежей или стабилизацией обработки документов.

Выход за границы ответственности: платформа навязывает выделение продуктовой логики в отдельный сервис без решения владельца домена, например для платежей.

Другой пример - платформенный Staff-инженер принимает доменные решения: нужна ли отдельная сущность для результата процесса или достаточно существующей сущности задачи. Аналогично, платформа не должна подменять продуктовую команду в discovery и решать за нее, нужен ли частный сценарий коммуникации или общий чат.

Материалы, на которые опирается модель

Подробнее о подходах: Team Topologies, DDD и монолит и микросервисы.