Кабинеты

Кабинет клиента: что показывать, а что никогда не показывать.

Прозрачный портал для заказчика — и инвариант, который нельзя нарушить ни при каких условиях. Что приходит клиенту в кабинет и почему изоляция реализована на уровне SQL.

АИ
Алексей Иванов
CTO actrix · Архитектура
6 МИН ЧТЕНИЯ

§01Что показывать клиенту

Заказчик хочет понимать три вещи: что именно ему продают, на какой стадии работа, и что ему нужно подписать. Всё остальное — шум.

  • Клиентская смета — только утверждённая, с корректировками после их согласования.
  • Прогресс работ — процент выполнения по объекту в целом и по каждой группе работ.
  • Документы на подпись — клиентские акты КС-2, КС-3, дополнительные соглашения.
  • История подписанных документов — то, что клиент уже одобрил и может скачать.
  • Контактное лицо — менеджер на нашей стороне с именем, телефоном, почтой.

§02Что скрывать всегда

Клиент никогда не видит подрядной стороны учёта. Это не настройка, а инвариант системы.

  • Подрядные сметы и их цены.
  • Подрядные акты и справки.
  • Любые документы, где side = CONTRACTOR.
  • Маржу, расчёт маржи, плановую/фактическую разницу.
  • Контрагентов-подрядчиков и их контакты.
  • Внутренние комментарии менеджеров и ПТО.
  • Чужие договоры и объекты другого клиента.
!

Утечка подрядной информации — баг критической приоритетности. В actrix такой случай привёл бы к немедленному откату последнего деплоя и разбору на уровне CTO. Не «доработка к следующему спринту», а «стоп-фикс».

§03Как реализована изоляция

Изоляция работает на трёх уровнях, и каждый последующий страхует предыдущий.

Уровень 1 — UI. В кабинете клиента просто нет элементов, отображающих подрядную сторону. Это первая линия обороны и самая слабая — UI всегда можно обойти.

Уровень 2 — middleware API. Все запросы из кабинета клиента проходят через guard, который проверяет роль (CLIENT_USER) и добавляет в запрос фильтры side=CLIENT и clientId=$currentClient. Любой запрос на ресурс с side=CONTRACTOR возвращает 403.

Уровень 3 — БД. На уровне Postgres настроены row-level security policies, которые отрабатывают, даже если в коде middleware появится баг. Это последний барьер, который не даёт случайному запросу вытащить чужие строки.

§04Инвариант

Сформулировано в документации архитектуры так: «Нет ни одного запроса из кабинета клиента, который мог бы вернуть строку, для которой нарушено условие side=CLIENT AND clientId=current_client». Этот инвариант проверяется автотестами на каждый коммит.

Если изоляция кабинетов — это «настройка», она однажды сломается. Если это инвариант — она ломаться не может, потому что её не на что переключать. — Из документации архитектуры actrix
КАБИНЕТЫ ИЗОЛЯЦИЯ БЕЗОПАСНОСТЬ