Перейти к основному содержимому

ADR-0052: Tenancy-модель PIN — TenantId = CompanyId, инвестор вне tenant

Статус

Accepted

Дата

2026-07-13

Контекст

SDK Talent.Common.* даёт tenant-изоляцию через ITenantedEntity/INullableTenantedEntity и tenant-интерсепторы. В PIN верхнеуровневые организации — компании (застройщик/агентство/брокер/партнёр/ПИН) со своими workspace; но инвестор — самостоятельный пользователь без родительской компании (ТЗ.md:45), а часть данных (каталог, посты, избранное) — платформенные.

Решение

  1. TenantId = CompanyId: границей tenant в PIN является компания. Данные компании (проекты, фиксации, сделки со стороны компании, роли компании) — ITenantedEntity.
  2. Инвестор и его данные — вне tenant: сущности инвестора (профиль, избранное, лиды со стороны инвестора) используют INullableTenantedEntity (TenantId = null) либо не tenanted; изоляция — по UserId/record-level.
  3. Платформенные данные (каталог, справочники, посты, permissions-SEED) — не tenanted; видимость решается permissions/ранжированием.
  4. Scope-иерархия авторизации (платформа → организация → группа проектов → проект) живёт в identity и не подменяет tenant-изоляцию: tenant — граница данных, scope — граница прав.

Последствия

  • Один и тот же SDK-механизм (ITenantContext, интерсепторы) работает для компаний; для инвесторских сущностей обязательные фильтры — по UserId (record-level), тесты изоляции обязательны.
  • Сущности с двумя «сторонами» (сделка: компания и инвестор) хранят TenantId компании-владельца процесса (застройщик для сделки; агентство для лида) + явные InvestorUserId/AgentUserId для record-level.
  • Кросс-tenant доступ (Менеджер ПИН, Служба заботы) — только через явные permissions уровня «платформа».

Обратные ссылки

Автоссылки: где используется этот документ.

Связанные документы

  • docs/06-services/identity/ (scope-модель, permissions), docs/00-overview/service-boundaries.md, SDK: docs/11-backend-sdk/ (tenant-интерсепторы).