Направление работ: Back Код раздела: 1.4 Аккаунты и пользователи > Партнеры Статус: на валидации Ответственный: Рыженко И.С. Версия: 0.1 Обновлено: 22.07.26


1. Назначение

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

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

Партнер управляет данными зоны через личный кабинет (WebLk: 3.1, WebLk 3.3).

Сотрудники сервиса взаимодействуют с партнерскими зонами через административный кабинет (AdmLk: 3.3).

2. Ключевые понятия

Партнерская зона — сущность для хранения всей информации по площадкам и услугам партнера, представленным в интерфейсах платформы. Создается при регистрации в качестве партнера и привязывается к аккаунту-владельцу.

Партнер — пользовательская характеристика аккаунта МАРТ, присваиваемая при создании партнерской зоны

Владелец партнерской зоны — аккаунт, создавший партнерскую зону и назначенный ее владельцем системой в момент создания.

Менеджер по партнерской зоне — аккаунт сотрудника сервиса МАРТ, ответственного за отношения с партнером. Назначается вручную. Осуществляет модерацию контента (Back: 8.7).

Аккаунт — централизованная сущность пользователя в системе. Подробнее в Back: 1.1.

Данные “По умолчанию” — каналы оплаты и настройки, автоматически привязываемые к партнерской зоне при создании.

Тип партнерской зоны — физическое лицо (по умолчанию) или юридическое лицо. Определяет доступные тарифы и сценарии каналов оплаты.

3. Scope

Входит

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

S2 Данные партнерской зоны: номер, тип (физическое / юридическое лицо), публичное название*, логотип, описание деятельности, контактные email и телефон, публичные страницы (Telegram, ВКонтакте, сайт).

S3 Связанные сущности и данные: владелец партнерской зоны (аккаунт-создатель), менеджер по партнерской зоне (сотрудник сервиса), каналы оплаты для поступающих заказов, сервисные каналы оплаты, группы настроек партнерской зоны, параметры активации и продления доступа.

S4 Создание партнерской зоны: три этапа — прием обязательных данных, назначение аккаунта владельцем, привязка данных «По умолчанию»; инициировать создание может только зарегистрированный пользователь.

S5 Валидация и лимиты: проверка обязательных параметров при создании; лимит описания деятельности — 1000 символов; подтверждение email при изменении контактной почты.

Не входит

  • Партнерская зона доступа (роли, permissions) — Back: 1.4.1

  • Расширение партнерских прав через тарифы — Back: 1.4.2

  • Настройки партнерской зоны (правила работы с заказами, параметры по умолчанию) — Back: 2.8

  • Продление доступа — Back: 2.8.1

  • Объекты партнера — Back: 2.1

  • Площадки партнера — Back: 2.2

  • Услуги партнера — Back: 2.3

  • Управление партнерами (административные операции) — Back: 8.6

  • Характеристики партнерских зон в административном кабинете — Back: 8.6.1

  • Модерация контента — Back: 8.7

  • UI профиля партнера — WebLk: 3.1, WebLk 3.3

4. Требования

Правила и ограничения бизнеса на уровне данных, источник истины в системе

IDТребованиеКомментарийТип требованияВесСтатус
S1: BR1.4-1Система должна хранить партнерскую зону как обособленную сущностьПартнерская зона хранит всю информацию, необходимую для взаимодействия партнера с сервисом и его пользователямиСистемное1Реализовано
S2: BR1.4-2Партнерская зона должна хранить данные партнерской зоныСостав: • номер (уникальный, присваивается по возрастанию при создании); • владелец партнерской зоны; • тип (физическое / юридическое лицо, по умолчанию — физическое); • менеджер по партнерской зоне; • каналы оплаты для поступающих заказов (расчеты партнер–клиент); • сервисные каналы оплаты (расчеты партнер–сервис); • публичное название; • логотип; • описание деятельности (до 1000 символов); • электронная почта (по умолчанию — email владельца, для уведомлений по ПЗ); • телефон (по умолчанию — телефон владельца, справочно для жалоб и оспаривания сборов); • публичные страницы (Telegram, ВКонтакте, сайт)

Признак «По умолчанию» — атрибут канала оплаты (в сервисе каналов), а партнёрская зона лишь ссылается на выбранные при создании каналы
Системное1Частично \ #OQ1.4-7 \ #OQ1.4-8 \ #OQ1.4-14
S2: BR1.4-3Тип партнерской зоны определяет доступные тарифы, сценарии сервисных каналов оплаты и каналов оплаты для поступающих заказовПо умолчанию — физическое лицо. Логика тарифов раскрывается в Back: 1.4.2 и Back: 8.3Бизнес1Не реализовано \ #OQ1.4-1
S2: BR1.4-4Контактный email партнерской зоны после изменения или добавления требует подтвержденияПо умолчанию используется email аккаунта-владельца. Используется для рассылки уведомлений по партнерской зонеСистемное2Не реализовано \ #OQ1.4-2 \ #OQ1.4-11
S2: BR1.4-5Контактный телефон партнерской зоны не требует подтверждения при измененииПо умолчанию используется телефон аккаунта-владельца. Носит справочный характер — для жалоб и оспаривания сборовСистемное2Частично \ #OQ1.4-9
S3: BR1.4-6Партнерская зона должна быть связана с владельцем и может быть связана с менеджеромЛогика назначения владельца — Back: 1.4. Менеджер может осуществлять модерацию контента — Back: 8.7Системное1Частично \ #OQ1.4-3
S3: BR1.4-7При создании партнерской зоны автоматически привязываются каналы оплаты с признаком «По умолчанию»Привязываются: канал оплаты для поступающих заказов и сервисный канал оплаты. Логика каналов — Back: 5.1Системное1Реализовано
S3: BR1.4-8Партнерская зона должна хранить группы настроек партнерской зоныСостав: • организация • уведомления • платежная информация • параметры работы с заказами • сборы • заявки • абонементы • правила и условия работы с заказами • параметры активации и продления доступа • сотрудники партнерской зоны. Логика настройки групп раскрывается в соседних разделах.Системное1Частично \ #OQ1.4-4
S3: BR1.4-9Партнерская зона должна хранить параметры активации и продления доступаСостав: • статус продления • активный тариф • доступные тарифы • предварительная комиссия • комиссии к оплате • данные по оплатам • платежные документы. Логика активации и продления доступа раскрывается в Back: 2.8.1.Системное1Не реализовано \ #OQ1.4-5
S3: BR1.4-10В рамках партнерской зоны создаются и хранятся связанные сущностиСостав: • объекты (Back: 2.1), • площадки и услуги (Back: 2.2, 2.3), • правила работы с заказами (Back: 2.4), • позиции (Back: 2.5), цены (Back: 2.6), • скидки и акции (Back: 2.7); логика каждой сущности раскрывается в соответствующем разделеСистемное1Реализовано
S4: BR1.4-11Создать партнерскую зону может только зарегистрированный пользовательВ результате создания аккаунт пользователя становится владельцем партнерской зоныБизнес1Частично \ #OQ1.4-10 \ #OQ1.4-16
S4: BR1.4-12Создание партнерской зоны выполняется в три этапа: • прием обязательных данных • назначение аккаунта владельцем • привязка данных (Настроек) “По умолчанию”При создании автоматически генерируются настройки по умолчанию: • информация об организации (только для типа “Юридическое лицо”); • платежная информация — метод оплаты “Наличными на месте” (Back: 5.1.2); • параметры работы с заказами (Back: 2.4); • доступ и условия размещения в интерфейсах — активный тариф доступа (Back: 2.8.1). Логика последующих настроек — Back: 2.8Системное1Частично \ #OQ1.4-6
S5: BR1.4-13Система должна проверять наличие обязательных параметров при создании партнерской зоны и соблюдение лимитовОбязательный параметр — публичное название Партнерской зоны. Лимит на описание деятельности — не более 1000 символовСистемное1Не реализовано \ #OQ1.4-12 \ #OQ1.4-13

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

Вопросы прогнаны через гайдбук 1.4 (Партнеры, включая 2.8 / 2.8.1). Гайдбук подтвердил правила по типу зоны, подтверждению email, ручному назначению менеджера, дефолтам контактов от владельца, «организации только для юрлица», обязательности названия и лимиту 1000 символов — эти вопросы переведены в «Закрывает PM» или потеряли развилку. Открытыми остались: гонка номера (архитектура), проверка прав при создании, обязательный набор дефолтов и уникальность названия — последнего в гайдбуке нет.

IDИсточникВопросКомуСтатусРекомендации
#OQ1.4-1Код BR1.4-3Требование говорит: тип зоны (физ/юр) определяет доступные тарифы и сценарии каналов оплаты. В коде тип (EntityType) нигде не влияет на подбор тарифов или каналов: единственное применение — проверка согласованности типа компании при создании (физлицо → Individual; юрлицо → ИП/ООО). Логика тарифов/каналов тип не читает. \ PartnerZoneAggregate.cs:137-148Бизнес/РазработкаOpenГайдбук 1.4 говорит дословно: «Тип определяет: доступные для покупки тарифы; сценарии сервисных каналов оплаты; сценарии каналов оплаты для поступающих заказов» — значит правило целевое, вариант «избыточное / уточнить формулировку» отпадает. Это недоработка, а не спорный вопрос. Рекомендация: реализовать влияние типа на подбор тарифов и сценарии каналов. Объём и этапность — за архитектурой; сама логика тарифов — Back 1.4.2 / 8.3, каналов — 5.1.
#OQ1.4-2Код BR1.4-4Требование говорит: контактный email после изменения/добавления требует подтверждения. В коде механизма подтверждения нет вовсе: ни отправки письма, ни установки «подтверждён», ни сброса при смене. Признак IsEmailVerified структурно всегда false (см. OQ1.4-11). \ ContactInfo.cs:17,22-35; PartnerZoneAggregate.cs:238-244РазработкаЗакрывает PMГайдбук 1.4 прямо говорит: «По умолчанию используется электронная почта владельца аккаунта. После изменения нового адреса требуется подтверждение» — правило есть, вариант «снять требование» отпадает, продуктового выбора нет. Закрываю сам: реализовать процесс подтверждения контактного email зоны (отправка кода/ссылки, установка признака, сброс при смене) → тикет в Bitrix. Предпосылка — исправить дефект признака (OQ1.4-11), без него флаг всё равно теряется. Механику подтверждения переиспользовать из уже существующей (Mobile 1.2.2 / 5.2.1).
#OQ1.4-3Код BR1.4-6Требование говорит: зона связана с владельцем (обязательно) и может быть связана с менеджером (опционально, назначается вручную). В коде менеджер обязателен при создании (ManagerId — не-nullable, колонка NOT NULL) и не имеет операции ручного назначения/смены: Update не содержит ManagerId. \ CreatePartnerZoneCommands.cs:28; PartnerZone.cs:29-30; UpdatePartnerZoneCommand.cs:18-41РазработкаЗакрывает PMГайдбук 1.4 говорит: менеджер — «аккаунт сотрудника сервиса… назначается вручную». Ручное назначение несовместимо с обязательным полем при создании (создаёт-то партнёр, а не сотрудник сервиса) — значит код неверен, вариант «привести BRD к коду» отпадает. Закрываю сам: сделать ManagerId опциональным и добавить операцию ручного назначения/смены менеджера → тикет в Bitrix. Заодно исправить ошибочный комментарий поля в коде («ID владельца»). Назначение менеджера как административная операция — смежно с Back 8.6.
#OQ1.4-4Код BR1.4-8Требование говорит: зона хранит 10 групп настроек, в т.ч. уведомления, абонементы, сотрудники. В коде из 10 групп 6 смоделированы (организация, платёжная информация, заявки, сборы, параметры/правила работы с заказами — отдельными агрегатами по PartnerZoneId). Не найдены: «уведомления», «абонементы»; «сотрудники» хранятся не здесь — берутся по gRPC из сервиса идентификации. \ PartnerZoneAggregate.cs:38-58; EmployeeService.csРазработкаЗакрывает PMГайдбук отвечает по каждой из трёх: «Уведомления» — перечень шаблонов, ссылка на 7.2.1; «Абонементы» — часть «Параметров работы с заказами» (сборы/заявки/абонементы), то есть 2.8; «Сотрудники партнёрской зоны» — ссылка на 1.4.1. То есть все три по замыслу живут в других разделах, а не в данных этого сервиса — код верен. Закрываю сам: оставить BR1.4-8 картой-ссылкой (состав групп + ссылки на 7.2.1 / 2.8 / 1.4.1), требования к данным там; в 1.4 не дублировать → правка BRD.
#OQ1.4-5Код BR1.4-9Требование говорит: зона хранит параметры активации и продления доступа (статус продления, активный тариф, доступные тарифы, комиссии, данные по оплатам, платёжные документы). В коде подсистема практически не реализована: «активный тариф» (TariffId) при создании ставится в Guid.Empty и реальным тарифом нигде не заполняется; не найдены статус продления, данные по оплатам, платёжные документы; «доступные тарифы» выражены на стороне тарифа (AllowedZones), а не как список у зоны. \ PartnerZoneAggregate.cs:54,174; PartnerTariffSetAggregate.cs:18,26РазработкаЗакрывает PMГайдбук подтверждает дом: весь состав (статус продления, активный тариф, доступные тарифы, предварительная комиссия, комиссии к оплате, платёжные документы) раскрыт в разделе 2.8.1 «Активация и продление доступа», туда же отсылает и BRD. Гайдбук заодно даёт то, чего нет в требовании: статус продления принимает значения Активен / Пролонгация / Не продлен / Архивирован. Закрываю сам: оставить BR1.4-9 картой-ссылкой на 2.8.1 (добавив значения статуса продления), требования к данным вести там → правка BRD. Оговорка: «активный тариф» пересекается с 1.4.1/OQ1.4.1-9 (связь тариф↔зона неоднозначна) — техническую часть решать там.
#OQ1.4-6Код BR1.4-12Требование говорит: при создании генерируются настройки «по умолчанию»: организация только для юрлица; параметры работы с заказами; активный тариф доступа. В коде реализована только платёжная информация по умолчанию («Оплата на месте (наличные)» + базовый фильтр). Компания (Company) создаётся всегда, без условия «только юрлицо». Параметры работы с заказами по умолчанию не создаются. Активный тариф не назначается (Guid.Empty). \ CreatePartnerZoneCommandHandler.cs:137-184; PartnerZoneAggregate.cs:154-160,174Бизнес/РазработкаOpenГайдбук закрывает часть вопроса: «Организация — информация об организации и договоре. Доступно только для партнёрских зон с типом „Юридическое лицо“» → создание компании всегда — баг, спорить не о чем, беру на себя. Гайдбук также подтверждает три этапа создания и привязку данных «По умолчанию» (со ссылкой на 8.4 Параметры системы). Осталось бизнесу: гайдбук не перечисляет обязательный набор дефолтов поимённо — подтвердить, обязательны ли при создании параметры работы с заказами и активный тариф доступа, или достаточно платёжной информации. Состав дефолтов — 8.4; активный тариф — связать с OQ1.4-5.
#OQ1.4-7Код BR1.4-2Проблема: номер вычисляется как MAX(number)+1 без атомарности и без запрета дублей в базе: MAX читается отдельным запросом, +1 в C#, вставка позже — два одновременных создания получат одинаковый номер. Уникального индекса на partner_zone.number нет. \ CreatePartnerZoneCommandHandler.cs:62; PartnerZoneRepository.cs:153-159; DbInitializer.cs:163,406-408,473Разработка (Влад)OpenТребование «номер уникальный» держится ни на чём: ни код, ни база уникальность не гарантируют. Вопрос к Владу: (А, рекоменд.) перейти на последовательность БД (SERIAL/nextval) либо уникальный индекс + повтор при конфликте — даёт и возрастание, и уникальность; (Б) блокировка на запись (advisory lock) вокруг выдачи номера — проще, но дороже по конкуренции.
#OQ1.4-8Код BR1.4-2Требование говорит: email зоны по умолчанию — email владельца; телефон по умолчанию — телефон владельца. В коде при создании email и телефон жёстко проставляются пустой строкой, данные владельца не копируются; у команды создания вообще нет полей email/phone. Модель partner_zone_owner с флагами email_confirmed/phone_confirmed существует, но нигде не используется (мёртвый код). \ CreatePartnerZoneCommandHandler.cs:91-92; CreatePartnerZoneCommands.cs:12-30; PartnerZoneOwner.cs:27,33РазработкаЗакрывает PMГайдбук 1.4 говорит прямо: «По умолчанию используется электронная почта владельца аккаунта» и «По умолчанию используется телефон владельца аккаунта» — правило есть, вариант «убрать из BRD» отпадает, продуктового выбора нет. Закрываю сам: при создании подтягивать email/телефон владельца из сервиса аккаунтов и проставлять в контактные данные; заодно убрать или задействовать мёртвую модель partner_zone_owner → тикет в Bitrix. Закрывает и OQ1.4-9 (телефон).
#OQ1.4-9Код BR1.4-5Требование говорит: телефон по умолчанию — телефон владельца, подтверждение не требуется. В коде часть «не требует подтверждения» соблюдается (телефон — обычная строка, верификации нет), но «по умолчанию телефон владельца» не выполнено: при создании передаётся пустая строка. \ ContactInfo.cs:15; CreatePartnerZoneCommandHandler.cs:91РазработкаЗакрывает PMГайдбук подтверждает обе части: «По умолчанию используется телефон владельца аккаунта. Подтверждение номера не требуется». Вторая часть выполнена, первая — тот же корень, что OQ1.4-8 (данные владельца не копируются). Закрываю сам: решается той же правкой, что OQ1.4-8, отдельного тикета не требует.
#OQ1.4-10Код BR1.4-11Требование говорит: создать зону может только зарегистрированный пользователь; аккаунт становится владельцем. В коде «только аутентифицированный» обеспечивается на шлюзе: JWT проверяется, AccountId берётся из claim токена и перезаписывается (клиент подменить не может), белый список анонимных методов в проде пуст. Но в самом обработчике создания нет проверки существования аккаунта и нет проверки прав — в отличие от Update, который вызывает IAuthorizationService. \ RpcProxyController.cs:385-388; CreatePartnerZoneCommandHandler.cs:52-135; UpdatePartnerZoneCommandHandler.cs:31-53Бизнес/РазработкаOpenРешение: достаточно ли «аутентифицирован» на шлюзе, или создание тоже должно проверять аккаунт/права. (А, рекоменд.) согласовать и добавить проверку в обработчик, как в Update; (Б) оставить как есть, явно зафиксировав, что авторизация создания — целиком на шлюзе. Граница ответственности шлюз/сервис — частично продуктовое решение.
#OQ1.4-11Код BR1.4-4Проблема (дефект): конструктор ContactInfo принимает параметр isEmailVerified, но никогда не присваивает поле IsEmailVerified (поле readonly без init) — оно всегда false. Даже если бы флаг где-то выставляли, значение бы терялось. \ ContactInfo.cs:17,24,30-34РазработкаЗакрывает PMЯвный дефект: значение теряется молча. Продуктового выбора нет — присваивание поля нужно при любом решении по OQ1.4-2. Закрываю сам: исправить ContactInfo — присваивать поле в конструкторе (init/прямое присваивание) → тикет в Bitrix. Сам процесс подтверждения этим не вводится (его направление задаёт OQ1.4-2).
#OQ1.4-12Код BR1.4-13Требование говорит: обязательный параметр — публичное название; проверка обязательных параметров при создании. В коде непустота PublicName не проверяется нигде: ни в VO PartnerZoneInfo, ни в команде/обработчике, ни на уровне базы (тип string даёт NOT NULL, но пустая строка проходит). Метод IsNameUnique для названия существует, но не вызывается ни в Create, ни в Update. \ PartnerZoneInfo.cs:19-25; CreatePartnerZoneCommandHandler.cs:89; PartnerZoneRepository.cs:147-151РазработкаЗакрывает PMГайдбук подтверждает: «Публичное название — обязательное поле» (видно пользователям при начислении штрафов и выдаче промокодов). Закрываю сам: добавить проверку непустого PublicName в доменный VO PartnerZoneInfo — единое место enforce для Create и Update → тикет в Bitrix. Отдельная оговорка: про уникальность названия ни BRD, ни гайдбук не говорят, а метод IsNameUnique в коде есть и не вызывается — подтвердить нечем, уточнить у Германа (не додумываю за гайдбук).
#OQ1.4-13Код BR1.4-13Требование говорит: лимит описания деятельности — не более 1000 символов. В коде ограничение длины не проверяется нигде: ни в домене (Descriptionstring? без проверки), ни в команде, ни в базе (на колонке нет HasMaxLength). Значения 1000 рядом с описанием в коде нет. \ PartnerZoneInfo.cs:15,23; PartnerZone.cs:17-18РазработкаЗакрывает PMГайдбук подтверждает: «Описание деятельности… Максимальная длина — 1000 символов». Спорить не о чем. Закрываю сам: добавить проверку длины Description ≤ 1000 в доменный VO PartnerZoneInfo (вместе с OQ1.4-12, одна правка) → тикет в Bitrix.
#OQ1.4-14Код BR1.4-2, BR1.4-7Что подтверждено: большинство полей состава зоны присутствует. Уточнение по признаку «По умолчанию» для каналов оплаты: он хранится не на зоне, а на самом канале (IsDefault) в другом сервисе и читается оттуда при создании — на стороне зоны флага «канал по умолчанию» нет. \ CreatePartnerZoneCommandHandler.cs:76-78,112-116; PartnerZoneAggregate.cs:50РазработкаЗакрывает PMТекущее поведение (выбор канала по IsDefault) корректно покрывает BR1.4-7 — вопрос только в формулировке хранения. Уже внесено в BRD (комментарий к BR1.4-2). Закрываю сам: формулировка зафиксирована, дополнительных действий не требуется. \ Подтверждение: состав данных зоны подтверждён кодом.
#OQ1.4-15Код вне BRD (обратный проход)Что нашли: команда Update партнёрской зоны проверяет права через IAuthorizationService (право settings_write) — поведение авторизации на уровне приложения, не описанное в разделе 1.4. \ UpdatePartnerZoneCommandHandler.cs:31-53; AuthorizationService.cs:24-55РазработкаЗакрывает PMДом у находки есть по скоупу: права и проверка доступа — Back 1.4.1 (партнёрская зона доступа) и Back 1.2 (общая модель доступа), оба уже в «Не входит». Закрываю сам: «Не входит → 1.4.1 / 1.2»; в 1.4 при необходимости оставить одну строку-ссылку «операции над зоной ограничены правами (см. 1.4.1)», правила не дублировать. Оговорка: сама проверка сейчас не работает — резолвер IsAuthorized заглушка (см. 1.4.1).
#OQ1.4-16Код вне BRD (обратный проход)Что нашли: при создании зоны на стороне сервиса аккаунтов её владельцу добавляется роль "partner" и запись OwnedPartnerZone (таблица owned_partner_zones_to_accounts) — это и есть реализация «аккаунт становится владельцем/партнёром» из BR1.4-11, но через роль и связь, а не через флаг IsPartner. \ PartnerZoneCreatedEventConsumer.cs:9,19-24; AssignPartnerZoneCommand.cs:43-55РазработкаЗакрывает PMНе расхождение — механика требования, просто не описанная. Ключевое понятие «Партнер — характеристика аккаунта, присваиваемая при создании зоны» в разделе уже есть. Закрываю сам: отразить в комментарии к BR1.4-11 механику «становления партнёром» (роль partner + связь владения, а не флаг) → правка BRD.
#OQ1.4-17Код вне BRD (обратный проход)Что нашли: на зоне хранятся настройки штрафов ForfeitSettings (режим списания, формат бана, порог) и тайминги комиссии CommissionSettings (таймаут оплаты, период расчётов) — данные, явно не перечисленные в составе BR1.4-2/BR1.4-8 (BRD относит «сборы» к настройкам соседних разделов). \ PartnerZoneAggregate.cs:49,51; ForfeitSettings.cs; CommissionSettings.csРазработкаЗакрывает PMГайдбук даёт дом: «Параметры работы с заказами» включают сборы, заявки, абонементы — то есть настройки штрафов/сборов относятся к группе настроек зоны (2.8), а логика начисления — 3.2.1. Тайминги комиссии — к параметрам активации и продления доступа (2.8.1 / 4.4). Продуктового выбора нет, дом подтверждён. Закрываю сам: «Не входит → 2.8 / 2.8.1»; в 1.4 достаточно упоминания групп в BR1.4-8, детальный состав не дублировать.

Подстраницы


Вопросы по сверке с кодом

BRD 1.4 v0.1 · booking-monorepo · commit 9e19870 / dev/cms-conflict-warning · 2026-06-30 · якорь src/services/booking.partner-management Сводка: вопросов 14 (бизнесовых 6 / программных 8) · подтверждено без вопросов 3 (BR1.4-1, BR1.4-7, BR1.4-10) · находок обратного прохода 3 показано (П9–П11), 4 отрезано

Стек-примечание: сервис использует LinqToDB (не EF Core). Схема создаётся в DbInitializer.cs через CreateTable<T> + ручные CREATE [UNIQUE] INDEX; форма таблиц задаётся атрибутами [Table]/[Column] на моделях. Поэтому «ограничения в базе» проверялись по DbInitializer.cs и атрибутам моделей, а не по EF-миграциям.

Бизнесовые

Связано сЧто в BRDЧто в кодеГде в коде
Б1BR1.4-3Тип партнёрской зоны (физ/юр) определяет доступные тарифы и сценарии каналов оплатыТип (EntityType) нигде не влияет на подбор тарифов или каналов оплаты. Единственное применение типа — проверка согласованности типа компании при создании (физлицо → только Individual; юрлицо → ИП/ООО). Логика тарифов/каналов тип не читает — нужно решение: правило целевое (ещё не реализовано) или избыточноеPartnerZoneAggregate.cs:137-148; (использований EntityType в подборе тарифов/каналов не найдено за обход домена и persistence)
Б2BR1.4-4Контактный email после изменения/добавления требует подтвержденияМеханизма подтверждения email нет вовсе: ни отправки письма, ни установки «подтверждён», ни сброса при смене email. Признак IsEmailVerified структурно всегда false (см. П5). Нужно решение: нужен ли процесс подтверждения email зоны и каков онContactInfo.cs:17,22-35; PartnerZoneAggregate.cs:238-244; (команд confirm/verify email не найдено за обход всего сервиса)
Б3BR1.4-6Зона связана с владельцем (обязательно) и может быть связана с менеджером (опционально, назначается вручную)Менеджер обязателен при создании (ManagerId — не-nullable Guid, колонка manager_id NOT NULL) и не имеет операции ручного назначения/смены: Update не содержит ManagerId. «Может быть связана» и «назначается вручную» в коде не реализованы. Нужно решение: менеджер обязателен или опционаленCreatePartnerZoneCommands.cs:28; PartnerZone.cs:29-30; UpdatePartnerZoneCommand.cs:18-41; PartnerZoneAggregate.cs:205-353
Б4BR1.4-8Зона хранит 10 групп настроек, в т.ч. уведомления, абонементы, сотрудники партнёрской зоныИз 10 групп 6 смоделированы (организация, платёжная информация, заявки, сборы, параметры/правила работы с заказами — отдельными агрегатами по PartnerZoneId). Не найдены в этом сервисе: «уведомления», «абонементы»; «сотрудники» хранятся не здесь — берутся по gRPC из сервиса идентификации. Нужно решение: где источник истины для этих трёх группPartnerZoneAggregate.cs:38-58; Infrastructure/Services/EmployeeService.cs (сотрудники); («notification»/«абонемент» как настроек зоны не найдено за обход домена)
Б5BR1.4-9Зона хранит параметры активации и продления доступа: статус продления, активный тариф, доступные тарифы, предварительная комиссия, комиссии к оплате, данные по оплатам, платёжные документыПодсистема активации/продления доступа в этом сервисе практически не реализована. «Активный тариф» (TariffId) при создании ставится в Guid.Empty и реальным тарифом нигде не заполняется. Не найдены: статус продления, данные по оплатам, платёжные документы; «доступные тарифы» выражены на стороне тарифа (AllowedZones), а не как список у зоны. BRD сам отсылает к Back: 2.8.1 — нужно подтвердить, что эти данные живут тамPartnerZoneAggregate.cs:54,174; PartnerTariffSetAggregate.cs:18,26; (renewal/payment-data/payment-documents не найдено за обход сервиса)
Б6BR1.4-12При создании генерируются настройки «по умолчанию»: организация только для юрлица; параметры работы с заказами; активный тариф доступаРеализована только платёжная информация по умолчанию («Оплата на месте (наличные)» + базовый фильтр). Компания (Company) создаётся всегда, без условия «только юрлицо». Параметры работы с заказами по умолчанию при создании не создаются. Активный тариф доступа по умолчанию не назначается (Guid.Empty). Нужно решение: какой набор «по умолчанию» обязателенCreatePartnerZoneCommandHandler.cs:137-184 (платёжные дефолты); PartnerZoneAggregate.cs:154-160 (Company всегда); PartnerZoneAggregate.cs:174 (TariffId=Guid.Empty)

Рекомендация / варианты решения

  • Тип зоны → тарифы/каналы (Б1). Вариант А: реализовать влияние EntityType на доступные тарифы и сценарии каналов, как требует BRD (рекомендуется, если бизнес-смысл деления физ/юр в этом и состоит). Вариант Б: если на момент написания кода деление по типу осознанно не привязано к тарифам/каналам — согласовать с продуктом и уточнить формулировку BR1.4-3 (что именно определяет тип). Решение за продуктом, т.к. это целевая логика предметной области.
  • Подтверждение email (Б2) + бизнес-сторона дефекта (П5). Вариант А: ввести процесс подтверждения контактного email (отправка кода/ссылки, установка флага, сброс при смене) — рекомендуется, поскольку BR1.4-4 прямо этого требует, а сейчас флаг мёртв. Вариант Б: если подтверждение email зоны не нужно (email и так берётся из подтверждённого аккаунта) — согласовать с продуктом и снять требование. В обоих случаях программную часть (П5) закрыть нельзя без этого решения.
  • Опциональность менеджера (Б3). Вариант А: привести код к BRD — сделать ManagerId опциональным и добавить операцию ручного назначения/смены менеджера (рекомендуется, т.к. BRD описывает менеджера как назначаемого вручную сотрудника сервиса, а не как обязательное поле создателя). Вариант Б: привести BRD к коду — если по факту менеджер обязателен и задаётся при создании, зафиксировать это; но тогда неясно, кто его задаёт (комментарий поля в коде ошибочно гласит «ID владельца»). Разблокирует решение бизнес-сторона.
  • Отсутствующие группы настроек (Б4) и параметры доступа (Б5). Вариант А: подтвердить, что «уведомления», «абонементы», «сотрудники», а также активация/продление доступа — зона ответственности других разделов (Back: 1.4.1, 2.8, 2.8.1) и других сервисов, и оставить BR1.4-8/BR1.4-9 как карту-ссылку, а не как требования к данным этого сервиса (рекомендуется — согласуется со Scope «Не входит»). Вариант Б: если они должны храниться именно в партнёрской зоне — завести требования и реализацию здесь. Решение за продуктом: где источник истины.
  • Состав «по умолчанию» при создании (Б6). Вариант А: реализовать недостающие дефолты по BRD — условную организацию (только юрлицо), параметры работы с заказами, активный тариф доступа (рекомендуется, если эти дефолты обязательны для работы зоны). Вариант Б: согласовать с продуктом сокращённый набор дефолтов и привести BR1.4-12 к нему. Связано с Б5 (активный тариф) — закрывать совместно.

Программные

Связано сЧто в BRDЧто в кодеГде в коде
П1BR1.4-2Номер уникальный, присваивается по возрастанию при созданииНомер вычисляется как MAX(number)+1 без атомарности и без запрета дублей в базе: MAX читается отдельным запросом, +1 в C#, вставка позже. Два одновременных создания получат одинаковый номер. Уникального индекса на partner_zone.number нет (в DbInitializer уникальные индексы есть только для partner_tariffs, order-management, priority-placement)CreatePartnerZoneCommandHandler.cs:62; PartnerZoneRepository.cs:153-159; PartnerZone.cs:23-24; DbInitializer.cs:163,406-408,473
П2BR1.4-2Электронная почта зоны по умолчанию — email владельца; телефон по умолчанию — телефон владельцаПри создании email и телефон жёстко проставляются пустой строкой; данные владельца не копируются. У команды создания вообще нет полей email/phone. Модель partner_zone_owner с флагами email_confirmed/phone_confirmed существует, но нигде не используется (мёртвый код)CreatePartnerZoneCommandHandler.cs:91-92; CreatePartnerZoneCommands.cs:12-30; PartnerZoneOwner.cs:27,33
П3BR1.4-5Телефон по умолчанию — телефон владельца (подтверждение не требуется)Часть «не требует подтверждения» соблюдается (телефон — обычная строка, верификации нет). Но «по умолчанию телефон владельца» не выполнено: при создании передаётся пустая строка, телефон владельца не копируетсяContactInfo.cs:15; CreatePartnerZoneCommandHandler.cs:91
П4BR1.4-11Создать зону может только зарегистрированный пользователь; аккаунт становится владельцем«Только аутентифицированный» обеспечивается на шлюзе: JWT проверяется, AccountId берётся из claim токена и перезаписывается (клиент его подменить не может), белый список анонимных методов в проде пуст. НО в самом обработчике создания нет проверки существования аккаунта и нет проверки прав — в отличие от Update, который вызывает IAuthorizationService. Нужно решение: достаточно ли «аутентифицирован» на шлюзе, или создание тоже должно проверять аккаунт/праваRpcProxyController.cs:385-388; RpcAnonByRouteAuthorization.cs:48-95; appsettings.json:40-41; CreatePartnerZoneCommandHandler.cs:52-135; UpdatePartnerZoneCommandHandler.cs:31-53
П5BR1.4-4Контактный email требует подтверждения (значение признака должно быть осмысленным)Дефект: конструктор ContactInfo принимает параметр isEmailVerified, но никогда не присваивает поле IsEmailVerified (поле readonly без init), поэтому оно всегда false. Даже если бы флаг где-то выставляли, значение бы терялосьContactInfo.cs:17,24,30-34
П6BR1.4-13Обязательный параметр — публичное название; проверка обязательных параметров при созданииНепустота PublicName не проверяется нигде: ни в VO PartnerZoneInfo, ни в команде/обработчике, ни на уровне базы (тип string даёт колонку NOT NULL, но пустая строка "" проходит). Метод IsNameUnique для названия существует, но не вызывается ни в Create, ни в UpdatePartnerZoneInfo.cs:19-25; CreatePartnerZoneCommandHandler.cs:89; PartnerZoneRepository.cs:147-151
П7BR1.4-13Лимит описания деятельности — не более 1000 символовОграничение длины описания не проверяется нигде: ни в домене (PartnerZoneInfo.Descriptionstring? без проверки), ни в команде, ни в базе (на колонке description нет Length/HasMaxLength). Значения 1000 рядом с описанием в коде нетPartnerZoneInfo.cs:15,23; PartnerZone.cs:17-18; DbInitializer.cs (длины/HasMaxLength для description не найдено за обход)
П8BR1.4-2Состав данных зоны (включая логотип и публичные страницы)Внесено в БРД: Большинство полей присутствует. Уточнение по «признаку По умолчанию» для каналов оплаты (BR1.4-7): он хранится не на зоне, а на самом канале (IsDefault) в другом сервисе и читается оттуда при создании — на стороне зоны флага «канал по умолчанию» нет. Это влияет на трактовку «зона хранит каналы по умолчанию»CreatePartnerZoneCommandHandler.cs:76-78,112-116 (выбор по IsDefault); PartnerZoneAggregate.cs:50 (на зоне — только CommissionPayChannelId)

Рекомендация / варианты решения

  • Уникальность номера (П1). Вариант А (рекомендуется): убрать гонку — перейти на последовательность БД (SERIAL/GENERATED/nextval) либо добавить уникальный индекс на partner_zone.number + повтор при конфликте; это даёт и возрастание, и гарантию уникальности. Вариант Б: блокировка на запись (SELECT … FOR UPDATE/advisory lock) вокруг выдачи номера — проще, но дороже по конкуренции. Сейчас уникальность не гарантирована ни кодом, ни базой.
  • Дефолты email/телефона из владельца (П2, П3). Вариант А (рекомендуется): при создании подтягивать email/телефон владельца из сервиса аккаунтов и проставлять в ContactInfo, как требует BR1.4-2/BR1.4-5; заодно убрать или задействовать мёртвую модель partner_zone_owner. Вариант Б: если значения должны вводиться партнёром вручную позже — согласовать с продуктом и убрать из BRD формулировку «по умолчанию — данные владельца». Решение, копировать ли данные владельца, — продуктовое; реализация — программная.
  • Дефект IsEmailVerified (П5). Вариант А (рекомендуется): исправить ContactInfo — присваивать поле в конструкторе (init/прямое присваивание), чтобы значение не терялось. Это необходимое условие для любого процесса подтверждения email (Б2); само по себе исправление поля не вводит процесс — его направление задаёт бизнес-решение Б2.
  • Проверка обязательного названия и лимита описания (П6, П7). Вариант А (рекомендуется): добавить проверки в доменные VO (PartnerZoneInfo): непустое PublicName (ThrowIfNullOrEmpty) и длина Description ≤ 1000 — единое место enforce для Create и Update. Вариант Б: продублировать проверки в обработчиках команд (ближе к API, но легче рассинхронизировать). Заодно решить (П6), нужна ли уникальность названия — метод IsNameUnique уже есть, но не вызывается; если уникальность нужна — подключить его и/или добавить уникальный индекс.
  • Проверки прав при создании (П4). Вариант А (рекомендуется): согласовать, должно ли создание проверять права/существование аккаунта в обработчике (как это делает Update через IAuthorizationService), или достаточно аутентификации на шлюзе. Вариант Б: оставить как есть, явно зафиксировав, что авторизация создания — целиком на шлюзе. Граница ответственности шлюз/сервис — частично продуктовое решение, поэтому смежно с бизнес-блоком.
  • Трактовка «каналы по умолчанию» (П8). Вариант А (рекомендуется): уточнить в BRD, что признак «По умолчанию» — атрибут канала оплаты (в сервисе каналов), а партнёрская зона лишь ссылается на выбранные при создании каналы; отдельного флага на зоне нет и не требуется. Вариант Б: если бизнес ждёт хранения признака на стороне зоны — завести его. Текущее поведение (выбор канала по IsDefault) корректно покрывает BR1.4-7; вопрос только о формулировке хранения.

Находки обратного прохода (код сверх BRD)

Отрезано находок: 4 (плумбинг/чужие разделы — агрегаты Review, AdvertisingTariff, PriorityPlacement, расширенные настройки сборов Expense* — относятся к другим разделам BRD: 2.x/8.x). Ниже — бизнес-значимые находки, не покрытые требованиями раздела 1.4:

Связано сЧто в BRDЧто в кодеГде в коде
П9вне BRD (обратный проход)Команда Update партнёрской зоны проверяет права через IAuthorizationService (право settings_write) — поведение авторизации на уровне приложения, не описанное в разделе 1.4. Стоит зафиксировать как требование (кто и что может менять в зоне)UpdatePartnerZoneCommandHandler.cs:31-53; AuthorizationService.cs:24-55
П10вне BRD (обратный проход)При создании зоны на стороне сервиса аккаунтов её владельцу добавляется роль "partner" и запись OwnedPartnerZone (таблица owned_partner_zones_to_accounts) — это и есть реализация «аккаунт становится владельцем/партнёром» из BR1.4-11, но через роль и связь, а не через флаг IsPartner. Стоит отразить в BRD механику «становления партнёром»PartnerZoneCreatedEventConsumer.cs:9,19-24; AssignPartnerZoneCommand.cs:43-55
П11вне BRD (обратный проход)На зоне хранятся настройки штрафов ForfeitSettings (режим списания, формат бана, порог) и тайминги комиссии CommissionSettings (таймаут оплаты, период расчётов) — данные, не перечисленные в составе BR1.4-2/BR1.4-8 явно (BRD относит «сборы» к настройкам соседних разделов). Уточнить, входят ли они в состав данных зоныPartnerZoneAggregate.cs:49,51; ForfeitSettings.cs; CommissionSettings.cs

4 items under this folder.