--- title: “1.3.1 Клиентская зона доступа” slug: homepage/d750da42741c/texnicheskaja-dokumentacija/brd/dokumentacija-po-funkcionalurazdelam/1-akkaunty-i-polzovateli/1.3-klienty/1.3.1-klientskaja-zona-dostupa source: 1.3.1 Клиентская зона доступа
1.3.1 Клиентская зона доступа
Направление работ: Back Код раздела: 1.3.1 Аккаунты и пользователи > Клиенты > Клиентская зона доступа Статус: черновик Ответственный: Панкова Л.А. Версия: 0.1 Обновлено: 17.07.26
1. Назначение
Клиентская зона доступа определяет, какие операции и возможности доступны клиенту при взаимодействии с платформой.
Система определяет состав клиентских возможностей на основании активной Подписки, связанной с Карточкой клиента.
Документ фиксирует правила доступа в клиентской зоне, а карточка клиента, управление подписками описываются в соседних разделах.
2. Ключевые понятия
Клиентская зона доступа — зона клиентских операций и возможностей, доступных Аккаунту на основании активной Подписки.
Аккаунт — цифровое представление пользователя в системе, которому передаются права клиентской зоны.
Карточка клиента — сущность, через которую создается клиент и передаются права доступа активному Аккаунту.
Подписка — сущность, которая определяет набор клиентских возможностей при взаимодействии с платформой.
Базовая подписка — подписка по умолчанию, которая дает базовый клиентский доступ.
Расширенная подписка — подписка, которая расширяет набор клиентских возможностей.
3. Scope
Входит
S1 Клиентская зона доступа: зависимость доступных операций и возможностей клиента от активной Подписки.
S2 Активация клиентского доступа: активация базовой Подписки при создании Карточки клиента и передача прав активному Аккаунту.
S3 Возможности по Подписке: базовые и расширенные клиентские возможности, лимиты и правила, которые определяются активной Подпиской.
Не входит
- Back: 1.2 Организация доступа к системе, зоны доступа, категории прав и общая проверка доступа
- Back: 1.2.1 Группировка прав по ролям и тарифам
- Back: 1.3 Клиенты и Карточка клиента
- Back: 4.3 Стоимость доступа к платформе
- Back: 8.3.4 Подписки
- Mobile: 5.6 Подписки
- Catalog: 4.1.3 Работа с подписками
- Widget: 6.1 Информация о клиенте
4. Требования
Правила и ограничения бизнеса на уровне данных, источник истины в системе
| ID | Требование | Комментарий | Тип требования | Вес | Статус |
|---|---|---|---|---|---|
| S1: BR1.3.1-1 | Клиентская зона доступа должна определять доступные операции и возможности клиента на основании активной Подписки | Подробнее Подписки описаны в Back: 8.3.4. | Бизнес | 1 | Не реализовано \ #OQ1.3.1-1 \ #OQ1.3.1-6 \ #OQ1.3.1-7 |
| S2: BR1.3.1-2 | Аккаунт должен получать базовый клиентский доступ через активацию базовой Подписки | Активация базовой Подписки осуществляется при создании Карточки клиента. Карточка клиента передает активному Аккаунту полученные права доступа после активации Подписки. Подробнее Карточка клиента описана в Back: 1.3. | Бизнес | 1 | Не реализовано \ #OQ1.3.1-2 \ #OQ1.3.1-3 \ #OQ1.3.1-8 \ #OQ1.3.1-9 |
| S3: BR1.3.1-3 | Подписка должна предоставлять клиентские возможности исходя из ее настроек | Состав возможностей: https://wiki.yandex.ru/homepage/d750da42741c/texnicheskaja-dokumentacija/brd/dokumentacija-po-funkcionalurazdelam/a3c284db2d88/8.3-tarify/8.3.4-podpiski/ | Бизнес | 1 | Не реализовано \ #OQ1.3.1-4 \ #OQ1.3.1-10 |
5. Открытые вопросы
| ID | Источник | Вопрос | Кому | Статус | Рекомендации | Итоговое решение |
|---|---|---|---|---|---|---|
| #OQ1.3.1-1 | Код BR1.3.1-1 | Требование говорит: доступные операции и возможности клиента определяются активной Подпиской. В коде такого механизма нет вообще: проверка доступа решает по ролям и правам (роль client и её набор прав), активную подписку/тариф клиента не читает; набора «клиентских операций по подписке» в модели нет. Сущность с похожим именем (ClientTariffAggregate) — чисто биллинговая (цена, период, кэшбэк, лимиты заказов). \ IsAuthorizedQuery.cs:113-174; ClientTariffAggregate.cs:10-38 | Бизнес/Разработка | Open | Гайдбук 1.3.1 прямо говорит: «Клиентская зона доступа определяет список доступных операций и возможностей клиента исходя из активной подписки» — значит модель «доступ от подписки» подтверждена, вариант «признать доступ ролевым и переписать BRD под код» гайдбуку противоречит. Это не расхождение значений, а отсутствующая основа раздела. Рекомендация: привести код к BRD — зафиксировать целевую модель «активная Подписка → набор клиентских возможностей», ввести в данные явные возможности/уровень подписки и связать активацию с правами Аккаунта. Объём работ и этапность — за архитектурой; развилку закрыть до детализации OQ1.3.1-3/-4. Корневой вопрос раздела: от него зависят OQ1.3.1-2, -3, -4, -8, -9, -10. | Требуется бизнес-решение: подтвердить, что целевая модель клиентского доступа строится именно от активной Подписки, то есть активная Подписка должна определять набор доступных клиенту возможностей и операций. Если подтверждается модель «доступ от Подписки», разработке необходимо реализовать отсутствующую связку «активная Подписка → клиентские возможности/права Аккаунта». Если бизнес решит, что доступ остаётся ролевым, BRD 1.3.1 нужно скорректировать и убрать из него зависимость клиентского доступа от Подписки. |
| #OQ1.3.1-2 | Код BR1.3.1-2 | Требование говорит: Аккаунт получает базовый клиентский доступ через активацию базовой Подписки при создании Карточки клиента. В коде создание карточки не активирует никакую подписку: при регистрации создаётся клиент и начисляются регистрационные баллы, выдача тарифа (ClientTariffPurchase) не вызывается. Базового доступа «через подписку» как факта нет. \ CreateClientCommandHandler.cs:19-52; AccountCreatedClientConsumer.cs | Разработка | Закрывает PM | Гайдбук 1.3.1 прямо говорит: «Активация базовой подписки осуществляется при создании карточки клиента» — правило есть, продуктового выбора нет, это недоделка. Закрываю сам: добавить выдачу базовой Подписки в сценарий создания карточки → тикет в Bitrix. Реализация следует за моделью из OQ1.3.1-1 (что именно активируем) и связью из OQ1.3.1-8. Это же снимает вопрос, оставленный в Back 1.3 (OQ1.3-8) — дом правила здесь. | Реализовать автоматическую выдачу базовой Подписки при создании Карточки клиента. В сценарий создания клиента необходимо добавить шаг активации базовой Подписки через механизм выдачи ClientTariffPurchase, чтобы базовый клиентский доступ появлялся не только через роль аккаунта, а согласно требованию BR1.3.1-2. Конкретный состав прав и возможностей базовой Подписки должен использовать модель, зафиксированную по OQ1.3.1-1. |
| #OQ1.3.1-3 | Код BR1.3.1-2 | Требование говорит: есть «Базовая подписка» (по умолчанию) и «Расширенная» (расширяет возможности). В коде деления нет: ни типа, ни уровня подписки; единственный признак — булев флаг IsDefault на тарифе, и он операционно ничего не запускает — никакой код не выбирает «тариф по умолчанию» и не выдаёт его. \ ClientTariffAggregate.cs:13; выбор/выдача дефолтного тарифа — не найдено за обход | Разработка | Закрывает PM | Гайдбук 1.3.1 даёт состав обеих подписок явно: базовая (управление аккаунтом и карточкой, свои заказы, отмена по стандартным правилам, кэшбэк 1%, лимит активных заказов 5) и расширенная (кэшбэк 2%, лимит 10, группировка заказов, объединение заказов в группы, публичная страница, лояльные правила погашения сборов, подписка на занятое время, скрытие рекламы, отмена по лояльным правилам, уведомления о горящих). Значит деление реально, спорить не о чем. Закрываю сам: внести состав базовой/расширенной в требования по гайдбуку и завести уровень подписки в данных → тикет. Формат хранения — OQ1.3.1-10. | Реализовать формальное деление клиентских Подписок на базовую и расширенную. В модели тарифа/подписки необходимо добавить явный признак уровня Подписки, а флаг IsDefault использовать только для выбора базовой Подписки по умолчанию. При создании Карточки клиента система должна находить базовую Подписку и автоматически выдавать её клиенту. Состав возможностей базовой и расширенной Подписки зафиксировать по гайдбуку 1.3.1; формат хранения возможностей реализовать в рамках решения по OQ1.3.1-10. |
| #OQ1.3.1-4 | Код BR1.3.1-3 | Требование говорит: Подписка предоставляет клиентские возможности исходя из её настроек. В коде настройки подписки — это биллинг и лояльность, а не возможности: цена за период, период (день/месяц), кэшбэк, авто-продление и «лимиты», ограничивающие количество и сумму заказов по зоне. Полей «возможности/права/операции» у подписки нет. \ ClientTariffAggregate.cs:10-25; LimitRule.cs:7-14 | Бизнес/Разработка | Open | Гайдбук частично отвечает: перечень возможностей задан (см. OQ1.3.1-3), и часть из них — это как раз лимиты и кэшбэк, которые в коде уже есть (кэшбэк, лимит заказов) — то есть код покрывает цифровую часть подписки. Не покрыто ничего из функциональной: публичная страница, скрытие рекламы, группировка заказов, лояльные правила отмены/сборов, подписка на занятое время, уведомления о горящих. Решение: гайдбук 1.3.1 отсылает параметры подписки к 8.3.4 — там подтвердить, какие настройки открывают возможности, и в каком виде. Зависит от OQ1.3.1-1, формат — OQ1.3.1-10. | Требуется бизнес-решение: подтвердить, какие настройки Подписки должны влиять на клиентские возможности. Нужно разделить цифровые параметры Подписки, которые уже частично есть в коде (кэшбэк, лимиты заказов), и функциональные возможности, которых сейчас нет в модели (публичная страница, скрытие рекламы, группировка заказов, лояльные правила отмены/сборов, подписка на занятое время, уведомления). После фиксации бизнесом перечня настроек и связанных возможностей разработке необходимо реализовать хранение и проверку этих возможностей в модели Подписки; формат хранения связать с решением по OQ1.3.1-10. |
| #OQ1.3.1-5 | Код вне BRD | Что нашли: код выдачи подписки соблюдает бизнес-правила, которых в разделе нет: глобальный лимит активаций тарифа, «один раз на клиента», максимум суммарных периодов на клиента, проверка уплаченной цены против ожидаемой. \ CreateClientTariffPurchaseHandler.cs:40-104 | Разработка | Закрывает PM | Дом у находки есть по скоупу: правила покупки/выдачи относятся к самому продукту «подписка», а гайдбук 1.3.1 прямо отсылает параметры подписки к 8.3.4 Подписки (и 8.3.4 уже стоит в «Не входит»). В гайдбуке 1.3.1 этих правил нет. Закрываю сам: «Не входит → 8.3.4», правила зафиксировать там; в 1.3.1 не дублировать. | Не дублировать правила покупки и выдачи Подписки в разделе 1.3.1. Зафиксировать найденные ограничения в профильном разделе 8.3.4 «Подписки»: глобальный лимит активаций тарифа, ограничение «один раз на клиента», максимальное количество суммарных периодов и проверку оплаченной цены. В 1.3.1 оставить только ссылку на 8.3.4, так как текущий раздел описывает клиентский доступ по активной Подписке, а не правила покупки/выдачи самой Подписки. |
| #OQ1.3.1-6 | Код BR1.3.1-1 | Проблема: проверка доступа сейчас — временная заглушка: и обработчик, и gRPC-метод безусловно возвращают «разрешено». Реальная логика (по ролям/правам) закомментирована и недостижима. То есть никакое правило доступа не соблюдается вообще — ни по подписке, ни по роли. \ IsAuthorizedQuery.cs:87 (// Временная заглушка, return true); IdentityGrpcService.cs:23 | Разработка (Влад) | Open | Самый срочный пункт: пока заглушка открыта, ни одно требование раздела нельзя валидировать на проде, и клиентская зона фактически не ограничена. Вопрос к Владу: (А, рекоменд.) включить настоящую проверку доступа (довести закомментированную ролево-правовую логику) и согласовать срок; (Б) осознанно оставить заглушку на MVP — но тогда явно отметить в BRD, что проверка доступа отложена. Инфраструктурная предпосылка для OQ1.3.1-1. | Убрать временную заглушку return true из проверки доступа и включить реальную авторизацию. На первом этапе необходимо восстановить и довести ролево-правовую проверку, чтобы клиентская зона перестала быть открытой для всех. Далее проверку доступа нужно расширить моделью активной Подписки после фиксации решения по OQ1.3.1-1. До снятия заглушки требования раздела 1.3.1 по ограничению клиентского доступа считаются технически невалидируемыми. |
| #OQ1.3.1-7 | Код BR1.3.1-1 | Требование говорит: источник истины для доступа — «активная Подписка». В коде «активность» — вручную проставляемый булев флаг IsActive на выдаче; окно дат StartDate/EndDate хранится, но с текущей датой нигде не сравнивается, авто-истечения нет. При запросе тарифа клиента фильтра по активности/датам/архиву нет — возвращаются тарифы по всем выдачам, активным и нет. \ ClientTariffPurchaseAggregate.cs:17; GetClientTariffByClientHandler.cs:21-33; ClientTariffPurchaseRepository.cs:35-47 | Разработка (Влад) | Open | В гайдбуке 1.3.1 термин «активная подписка» используется, но механика активности (флаг / окно дат / оба) не раскрыта — подтвердить нечем на уровне этого раздела. Вопрос к Владу: что считать активной подпиской и где это вычислять — (А, рекоменд.) флаг + окно дат StartDate/EndDate с фильтрацией архивных при резолве; (Б) зафиксировать, что активность = ручной флаг без авто-истечения. Определение параметров подписки — с 8.3.4. Связать с OQ1.3.1-10. | Формализовать вычисление активной Подписки в коде. Активной считать только неархивную выдачу Подписки с IsActive = true, у которой текущая дата попадает в период StartDate / EndDate. При получении Подписки клиента необходимо фильтровать выдачи по активности, датам действия и архивности, чтобы в проверку доступа попадала только фактически активная Подписка. Механику авто-истечения и снятия активности реализовать на уровне сервиса Подписок либо отдельного фонового процесса; это решение связать с форматом хранения возможностей по OQ1.3.1-10. |
| #OQ1.3.1-8 | Код BR1.3.1-2 | Требование говорит: Карточка клиента после активации подписки передаёт права активному Аккаунту. В коде этой связки нет ни в одном слое: выдача подписки не порождает доменных событий, событие «подписка активирована» никто не публикует и не потребляет, в сервисе авторизации нет потребителя тарифа, на шлюзе проверки по тарифу нет. Account.TariffId зашит в Guid.Empty с пометкой «убрать заглушку с тарифов». \ ClientTariffPurchaseAggregate.cs:47-62; RegistrationMobileEndCommandHandler.cs:122,131 | Разработка (Влад) | Open | Гайдбук 1.3.1 прямо говорит: «карточка клиента передаёт активному аккаунту полученные права доступа после активации подписки» — значит связь нужна, вопрос только в её архитектуре. Вопрос к Владу: носитель связи — выдача ClientTariffPurchase уже хранит ClientId/TariffId; добавить доменное событие активации + потребителя в сервисе авторизации, заменить Account.TariffId = Guid.Empty на реальную привязку. Зависит от OQ1.3.1-1. Связать с OQ1.3.1-9. | Реализовать связку «активация Подписки → права активного Аккаунта». При выдаче/активации ClientTariffPurchase необходимо публиковать доменное событие об активации Подписки с ClientId, TariffId и периодом действия. Сервис авторизации должен потреблять это событие и обновлять права или доступные возможности активного Аккаунта клиента. Заглушку Account.TariffId = Guid.Empty заменить на реальную привязку к активной Подписке. Логику проверки доступа расширить этой связкой после фиксации целевой модели по OQ1.3.1-1. |
| #OQ1.3.1-9 | Код BR1.3.1-2 | Проблема: привязки подписки к Карточке клиента нет — у агрегата карточки нет такого поля, в БД-модели клиента нет колонки тарифа. Параметр tariffId в методе обновления карточки объявлен, но в теле не используется (мёртвый параметр), и единственный вызывающий код тариф не передаёт. \ ClientAggregate.cs:185,65-114; AttachAccountToClientCommandHandler.cs:30 | Разработка (Влад) | Open | Где живёт связь «клиент ↔ его подписка» (карточка, выдача или отдельная связь) — гайдбук не раскрывает, это архитектурный выбор. Вопрос к Владу. Общий корень с OQ1.3.1-8. Независимо от решения: мёртвый параметр tariffId либо довести до реальной записи, либо удалить — чистка кода уместна в любом случае, беру на себя. | Закрепить связь клиента с Подпиской через выдачу ClientTariffPurchase, так как она уже содержит ClientId, TariffId и период действия Подписки. Не добавлять отдельное поле тарифа в Карточку клиента, чтобы не дублировать источник истины. При необходимости получать активную Подписку клиента через резолв активной выдачи по правилам OQ1.3.1-7. Мёртвый параметр tariffId в ClientAggregate.Update удалить либо довести до использования только если будет принято отдельное архитектурное решение хранить текущую Подписку прямо в Карточке клиента. |
| #OQ1.3.1-10 | Код BR1.3.1-3 | Проблема: у подписки/тарифа нет ни перечисления статусов, ни справочника возможностей: единственный относящийся перечислимый тип — единица периода (день/месяц). Состояние подписки выражено булевыми флагами и свободными датами, а не статусом и не набором прав — «возможностям» из требования негде храниться. \ PeriodType.cs:3; ClientTariffAggregate.cs:10-38; ClientTariffPurchaseAggregate.cs:9-19 | Разработка (Влад) | Open | Формат хранения возможностей (перечень фич / флаги / уровни) гайдбук не задаёт — он даёт только их состав (см. OQ1.3.1-3). Вопрос к Владу: ввести явный носитель возможностей/уровня подписки и вычисление активности (общий корень с OQ1.3.1-7). Зависит от OQ1.3.1-1 и от того, что решат по параметрам в 8.3.4 (OQ1.3.1-4). | Ввести отдельную модель клиентских возможностей Подписки. Для тарифа/Подписки хранить уровень (Basic / Extended), набор функциональных возможностей через связь TariffId → Feature, а числовые параметры (кэшбэк, лимит активных заказов) хранить как настройки тарифа. При проверке доступа система должна находить активную выдачу ClientTariffPurchase, получать по её TariffId список доступных фич и настройки, после чего разрешать или запрещать клиентскую операцию. Такой подход не дублирует данные в Карточке клиента, позволяет расширять список возможностей без изменения основной модели тарифа и разделяет функциональные права от биллинговых параметров. |
| #OQ1.3.1-11 | Код вне BRD | Что нашли, три момента вокруг подписки-тарифа: (1) нет запрета на две одновременно активные подписки у одного клиента — ни ограничения в базе, ни проверки в коде, пересекающиеся активные выдачи допускаются; (2) авто-продление хранится флагом, но самого продления нет — ни планировщика, ни фоновой службы; (3) Client_tariff в правах — это категория админ-права на управление клиентскими тарифами, а не «право клиентской зоны» (легко спутать при чтении BRD). \ ClientTariffPurchaseMapping.cs:15-46 + миграция без индекса; планировщик продления — не найдено за обход; PermissionType.cs:3-9 | Бизнес (Герман) | Open | Разбор по пунктам: (1) в гайдбуке 1.3.1 про одновременность подписок ничего нет — подтвердить нечем, решение бизнеса: нужен ли инвариант «одна активная подписка на клиента» (тогда ограничение в базе + проверка) или допускается осознанно. (2) гайдбук 1.3 (Клиенты) перечисляет «Автопродление тарифа» и ссылается сюда, но гайдбук 1.3.1 про автопродление молчит — пробел гайдбука, не додумываю: решить, реализуем продление или поле зарезервировано (правила продления — вероятно 8.3.4). (3) терминологическое — беру на себя: развести в BRD Client_tariff (админ-право управления тарифами) и «право клиентской зоны». |
Вопросы по сверке с кодом
BRD 1.3.1 v0.1 · booking-monorepo · commit 9e19870 / dev/cms-conflict-warning · 2026-06-30 · якорь src/services/booking.clients (+ кросс-проверка src/services/booking.authentication) Сводка: вопросов 11 (бизнесовых 5 / программных 6) · подтверждено без вопросов 0 · отрезано находок 0
Главный вывод сверки: BRD описывает подписку как механизм доступа (активная Подписка определяет набор операций клиента и передаёт права Аккаунту). В коде сущность с похожим смыслом — это клиентский тариф (ClientTariffAggregate + его выдача клиенту ClientTariffPurchaseAggregate), и он полностью биллинговый (цена, период, кэшбэк, лимиты на заказы). Связки «подписка → права клиента» в коде нет ни в одном слое, а сама проверка доступа (IsAuthorizedQuery) сейчас — временная заглушка, возвращающая «разрешено» всем. Поэтому большинство вопросов — это не «расхождение значений», а «механизма из BRD в коде ещё нет».
Бизнесовые
| № | Связано с | Что в BRD | Что в коде | Где в коде |
|---|---|---|---|---|
| Б1 | BR1.3.1-1 | Клиентская зона доступа определяет доступные операции и возможности клиента на основании активной Подписки | Проверка доступа решает по ролям и правам (роль client и её набор прав), активную Подписку/тариф клиента не читает вовсе; набора «клиентских операций по подписке» в модели нет. Сущность «подписки» (ClientTariffAggregate) — чисто биллинговая. — нужно решение: существует ли вообще модель «доступ от подписки» как целевая, или доступ остаётся ролевым | IsAuthorizedQuery.cs:113-174 (логика по ролям/правам); ClientTariffAggregate.cs:10-38 (поля тарифа) |
| Б2 | BR1.3.1-2 | Аккаунт получает базовый клиентский доступ через активацию базовой Подписки при создании Карточки клиента | Создание Карточки клиента не активирует никакую подписку: при регистрации создаётся клиент и начисляются регистрационные баллы; выдача тарифа (ClientTariffPurchase) не вызывается. То есть «базовый доступ через активацию базовой подписки» как факт отсутствует. — нужно решение: должна ли при создании карточки автоматически выдаваться базовая Подписка | CreateClientCommandHandler.cs:19-52; AccountCreatedClientConsumer.cs (создание клиента + баллы, без тарифа) |
| Б3 | BR1.3.1-2 | Существует «Базовая подписка» (по умолчанию), дающая базовый доступ, и «Расширенная» (расширяет возможности) | В модели нет деления на базовую/расширенную: нет типа/уровня подписки, единственный признак — булев флаг IsDefault на тарифе, и он операционно ничего не запускает (никакой код не выбирает «тариф по умолчанию» и не выдаёт его). — нужно решение: чем формально считать «базовую» и «расширенную» подписку в данных | ClientTariffAggregate.cs:13 (IsDefault); не найдено за обход (выбор/выдача дефолтного тарифа) |
| Б4 | BR1.3.1-3 | Подписка предоставляет клиентские возможности исходя из её настроек | Настройки подписки в коде — это биллинг и лояльность, а не возможности: цена за период, период (день/месяц), кэшбэк, авто‑продление, и «лимиты», которые ограничивают количество заказов и сумму заказов по зоне (а не доступ к операциям). Поля «возможности/права/операции» у подписки отсутствуют. — нужно решение: что именно из настроек подписки должно открывать клиентские возможности | ClientTariffAggregate.cs:10-25; LimitRule.cs:7-14 (OrdersCount, OrdersSumPerZone) |
| Б5 | вне BRD | — (в этом BRD не описано) | Код выдачи подписки соблюдает реальные бизнес‑правила, которых нет в разделе: глобальный лимит активаций тарифа, «один раз на клиента», максимум суммарных периодов на клиента, проверка уплаченной цены против ожидаемой. Стоит решить, относятся ли эти правила к 1.3.1 или живут в разделе про подписки (8.3.4). — нужно решение: где зафиксировать эти правила | CreateClientTariffPurchaseHandler.cs:40-104 |
Рекомендация / варианты решения
- Корень бизнес‑вопросов Б1–Б4 один: в коде «подписка» = биллинговый тариф, а механизма «доступ/возможности от подписки» нет, и доступ сейчас ролевой (и к тому же открыт заглушкой, см. П1). Это решение продукта о целевой модели:
- Вариант А (привести код к BRD, рекомендуется): зафиксировать целевую модель «активная Подписка → набор клиентских возможностей», ввести в данные явные «возможности/уровень» подписки и связать активацию подписки с правами Аккаунта. Рекомендуется, потому что BRD заявляет подписку именно как механизм доступа, а в коде этого слоя пока нет вовсе — это не доработка, а отсутствующая основа раздела.
- Вариант Б (привести BRD к коду): признать, что доступ остаётся ролевым (раздел 1.2 «зоны доступа/категории прав»), а «подписка» — это коммерческий тариф (цена/период/кэшбэк/лимиты заказов из 8.3.4); тогда 1.3.1 переформулировать как «клиентская зона = роль
client», а влияние подписки описать как влияние на лимиты заказов/кэшбэк, а не на состав операций. - Эту развилку нужно закрыть до детализации Б3/Б4: пока не решено «доступ от подписки или ролевой», понятия «базовая/расширенная» и «возможности из настроек» определить в данных нельзя.
- По Б2 отдельно согласовать с продуктом: нужна ли авто‑выдача базовой Подписки при создании карточки (вариант А — добавить шаг выдачи дефолтного тарифа в сценарий регистрации) или базовый доступ обеспечивается ролью
clientбез подписки (вариант Б, рекомендуется при выборе Б по Б1 — тогда убрать из BRD привязку «базовый доступ ⇐ активация подписки»). Сегодня по факту базовый доступ даёт роль, а на регистрацию выдаются только баллы. - По Б5 (правила выдачи подписки, найденные в коде): согласовать, где их место — вариант А: вынести в раздел «Подписки 8.3.4» (они про сам продукт «подписка»); вариант Б (рекомендуется): кратко отразить и в 1.3.1 как ограничения активации клиентского доступа, раз раздел про активацию. Решение за владельцем раздела.
Программные
| № | Связано с | Что в BRD | Что в коде | Где в коде |
|---|---|---|---|---|
| П1 | BR1.3.1-1 | Доступ к операциям должен определяться (по активной Подписке) — то есть проверка доступа должна реально что‑то решать | Проверка доступа сейчас — временная заглушка: и обработчик, и gRPC‑метод безусловно возвращают «разрешено» (true). Реальная логика (по ролям/правам) закомментирована и недостижима. Значит сейчас никакое правило доступа (ни по подписке, ни по роли) фактически не соблюдается. — нужно решение: сроки включения настоящей проверки доступа | IsAuthorizedQuery.cs:87 (// Временная заглушка, return true); IdentityGrpcService.cs:23 (return true) |
| П2 | BR1.3.1-1 | «Активная Подписка» как источник истины для доступа | «Активность» подписки — это вручную проставляемый булев флаг IsActive на выдаче; окно дат StartDate/EndDate хранится, но нигде не сравнивается с текущей датой, авто‑истечения нет. При запросе тарифа клиента фильтра по IsActive/датам/архиву нет — возвращаются тарифы по всем выдачам, активным и нет. — нужно решение: что считать «активной подпиской» (флаг, окно дат или оба) и где это вычислять | ClientTariffPurchaseAggregate.cs:17; GetClientTariffByClientHandler.cs:21-33 (без фильтра активности); ClientTariffPurchaseRepository.cs:35-47 |
| П3 | BR1.3.1-2 | Карточка клиента после активации подписки передаёт права активному Аккаунту | Связки «выдача подписки → права аккаунта» нет ни в одном слое: ClientTariffPurchaseAggregate не порождает доменных событий, событий «подписка активирована» никто не публикует/не потребляет, в booking.authentication нет потребителя тарифа/подписки, на шлюзе нет проверки по тарифу. Account.TariffId зашит в Guid.Empty с пометкой «убрать заглушку с тарифов». — не найдено за обход (передача прав от подписки к аккаунту) | ClientTariffPurchaseAggregate.cs:47-62 (нет событий); RegistrationMobileEndCommandHandler.cs:122,131 (TariffId = Guid.Empty, TODO); не найдено за обход (потребитель в authentication / шлюз) |
| П4 | BR1.3.1-2 | Привязка подписки к Карточке клиента | Карточка клиента (ClientAggregate) не хранит ссылку на подписку/тариф: у агрегата нет такого поля, в БД‑модели клиента нет колонки тарифа. Параметр TariffId? tariffId в методе ClientAggregate.Update объявлен, но в теле метода не используется (мёртвый параметр); единственный вызывающий его код тариф не передаёт. — нужно решение: где должна жить связь «клиент ↔ его подписка» (карточка, выдача или отдельная связь) | ClientAggregate.cs:185 (мёртвый параметр tariffId); ClientAggregate.cs:65-114 (нет поля тарифа); AttachAccountToClientCommandHandler.cs:30 (вызов без тарифа) |
| П5 | BR1.3.1-3 | Подписка определяет возможности «исходя из её настроек» — состав возможностей хранится в подписке | У подписки/тарифа нет ни перечисления статусов, ни справочника «возможностей/фичей»: единственный относящийся enum — PeriodType {Day, Month} (единица периода). Состояние подписки выражено булевыми флагами и свободными датами, а не статусом и не набором прав. — нужно решение: формат хранения «возможностей подписки» (перечень фич, флаги, уровни) | PeriodType.cs:3; ClientTariffAggregate.cs:10-38; ClientTariffPurchaseAggregate.cs:9-19 |
| П6 | вне BRD | — (в этом BRD не описано) | Несколько программных моментов вокруг подписки‑тарифа, которые стоит зафиксировать как требования: (1) нет запрета на две одновременно активные подписки у одного клиента — ни ограничения в базе (нет уникального/частичного индекса на выдачи), ни проверки в коде, пересекающиеся активные выдачи допускаются; (2) AutoRenewal/IsAutoRenewal хранятся, но авто‑продления нет — ни планировщика, ни фоновой службы в сервисе; (3) Client_tariff в PermissionType — это категория админ‑права на управление клиентскими тарифами, а не «право клиентской зоны» (легко спутать при чтении BRD). — нужно решение: какие из этих пунктов должны стать требованиями раздела | (1) ClientTariffPurchaseMapping.cs:15-46 + миграция client_tariff_purchases без индекса; (2) не найдено за обход (планировщик/служба продления); (3) PermissionType.cs:3-9 + GetPartnerPermissionsByFilter.cs:8-12 |
Рекомендация / варианты решения
- П1 (проверка доступа — заглушка
return true) — самый срочный программный пункт: пока она открыта, ни одно правило доступа из раздела не действует. Вариант А (рекомендуется): включить настоящую проверку доступа (раскомментировать/довести ролево‑правовую логику) и согласовать срок; вариант Б: осознанно оставить заглушку на время MVP, но тогда явно отметить в BRD, что проверка доступа отложена — иначе любые требования 1.3.1 о доступе нельзя валидировать на проде. Это инфраструктурная предпосылка для Б1. - П2 + П5 имеют общий корень — нет формализованного понятия «активная подписка» и нет места для «возможностей»: вариант А (рекомендуется, если выбран бизнес‑вариант А по Б1): ввести вычисление активности (флаг + окно дат
StartDate/EndDate, фильтрация архивных) и явный носитель «возможностей/уровня» подписки, фильтровать выдачи по активности при резолве. Вариант Б: если подписка остаётся биллингом — зафиксировать в BRD, что «активность» = ручной флагIsActiveбез авто‑истечения, и убрать формулировку про «возможности по настройкам». - П3 + П4 — общий корень отсутствие связи «подписка ↔ права/карточка»: вариант А (рекомендуется при бизнес‑варианте А): определить носитель связи (выдача
ClientTariffPurchaseуже хранитClientId/TariffId; добавить доменное событие активации и потребителя вauthentication, заменитьAccount.TariffId = Guid.Emptyна реальную привязку), заодно довести мёртвый параметрtariffIdвClientAggregate.Updateдо реальной записи. Вариант Б: если связи быть не должно — удалить мёртвый параметр и снять из BRD пункт «карточка передаёт права после активации подписки». Удаление/доведение мёртвогоtariffIdуместно в любом случае (чистка кода). - П6 — отдельные технические решения продукта/реализации: (1) запрет двух активных подписок — согласовать, нужен ли инвариант (вариант А: частичный уникальный индекс/проверка по
ClientIdсреди активных; вариант Б: допускается осознанно — описать в BRD); (2)AutoRenewal— либо реализовать продление (планировщик), либо пометить поле как зарезервированное; (3) терминологически развести в BRDClient_tariff(админ‑право управления тарифами) и «право клиентской зоны», чтобы не путать при чтении.