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

UC-PRF-005. Запрет редактирования профиля для менеджера застройщика (TalentSync)

Назначение

Исключительный сценарий: менеджер застройщика (UserType = DeveloperManager, ContactsManagedBy = TalentSync) не может управлять профилем, контактами, ФИО и любыми персональными данными в PIN — источник знаний Talent Identity (требование INV-IDN-001). Фиксирует поведение проверок доступа profile/identity на каждом уровне (UI-флаги, API-отказы) и то, что остаётся доступным. Связан с контекстами profile и identity.

Metadata

ПолеЗначение
IDUC-PRF-005
Контекстprofile (см. docs/06-services/profile/); смежно — identity
Типисключительный
Статусdraft

Актор

ПолеЗначение
РольДевелопер (менеджер застройщика) — пользователь компании-застройщика, реплицируемый из Talent Identity
Permissions / scopeprofile.personal.view-self (просмотр реплики); manage-permissions над персональными данными не действуют — блокируются проверками доступа независимо от наличия permission
TenantTenantId = CompanyId застройщика в данных identity/crm; данные profile — record-level по Id = UserId (ADR-0052); Profile.CompanyId — информационная реплика
Record-levelтолько собственный профиль (read-only реплика)

Предусловие

  • Пользователь создан синком Talent (identity, UC-IDN-007): UserType = DeveloperManager, ContactsManagedBy = TalentSync, Status = Active.
  • Consumer identity-users-sync создал ProfileEntity-реплику (ContactsManagedBy = TalentSync); персона Self для не-инвестора не создаётся.

Триггер

ПолеЗначение
ИсточникUI button / API call
Триггерящий элементЛК /profile/personal менеджера застройщика; либо прямой API-вызов (обход UI)

Основной Поток

  1. Менеджер застройщика открывает /profile/personal. Фронт вызывает getMyProfile.
  2. getMyProfile возвращает реплику (Name, ContactPhone, ContactEmail, UserType = DeveloperManager, ContactsManagedBy = TalentSync) и вычисленные UI-флаги: canEditContacts = false, canEditName = false, canManagePersons = false, canManageTemplates = false, canSubmitVerification = false, canEditSettings = true.
  3. Фронт скрывает формы редактирования ФИО/контактов и блоки «Персоны», «Документы», «Шаблоны реквизитов», «Верификация»; показывает плашку «Данные управляются системой застройщика (Talent); для изменения обратитесь к администратору вашей компании».
  4. Менеджер (или злоумышленник с его токеном) вызывает API напрямую, минуя UI, — например createPerson (POST /profile/persons). Проверка доступа по профилю: ContactsManagedBy = TalentSyncотказ до любых мутацийPROFILE_MANAGED_EXTERNALLY (INV-PRF-2/INV-PRS-3, HTTP 403). Даже при SelfService следующая проверка отклонила бы не-инвестора PROFILE_PERSONS_NOT_ALLOWED_FOR_USER_TYPE (INV-PRF-4) — двойная защита. Целевые агрегаты не загружаются (fail-fast); состояние БД не меняется; отказ логируется (UserId, операция, код — без PII) и учитывается метрикой profile_managed_externally_rejections_total (alert на всплеск — README profile).
  5. Тот же порядок проверок (шаг 4) отклоняет все self-операции контекста над персональными данными: updatePerson, archivePerson, addPersonDocument, updatePersonDocument, attachDocumentScan, createRequisiteTemplate, updateRequisiteTemplate, setDefaultTemplate, createVerificationRequest, submitVerification — единая проверка режима самообслуживания во всех операциях над агрегатами (INV-PRF-2).
  6. Попытка сменить контакты/ФИО через identity (requestPhoneChange/requestEmailChange/ updateInvestor) отклоняется на стороне identity проверкой INV-4 ManagedContacts → IDENTITY_CONTACTS_MANAGED_EXTERNALLY (403) — см. UC-IDN-004, поток A3.
  7. Актуализация данных менеджера происходит только синком Talent: Talent Identity → identity (UC-IDN-007) → событие UserUpsertedKafkaEvent (pin.identity.users.v1) → consumer identity-users-sync обновляет реплику ProfileEntity (INV-PRF-1 MonotonicReplica).
  8. Что остаётся доступным менеджеру: просмотр профиля (read-only), updateMySettings (Locale/Timezone — не персональные данные, матрица в ../domain/profile.md), 2FA/пароль/пин в identity (секреты входа — PIN-локальные, Talent их не ведёт: UC-IDN-002, UC-IDN-003).

Альтернативные Потоки

A1. Настройки ЛК (разрешённая операция)

  1. Менеджер меняет язык/часовой пояс: updateMySettings — проверяется только Status = Active (INV-PRF-3); ContactsManagedBy не блокирует (настройки — собственность profile, не реплика Talent). Успех: публикуется ProfileSettingsChangedEvent.

A2. Агент/сотрудник ПИН (не TalentSync, но не инвестор)

  1. Для UserType ∈ {Agent, PartnerManager, PinEmployee} (ContactsManagedBy = SelfService) проверка режима самообслуживания (INV-PRF-2) проходит, но проверка типа пользователя (INV-PRF-4) отклоняет персоны/документы/шаблоны/верификацию → PROFILE_PERSONS_NOT_ALLOWED_FOR_USER_TYPE (403).
  2. Смена собственных ФИО/контактов через identity им разрешена (матрица в ../domain/profile.md). Сценарий завершается.

A3. Смена типа управления (пользователь перестал быть TalentSync)

  1. Talent/identity меняет ContactsManagedBy → SelfService (административная миграция учётки); UserUpsertedKafkaEvent обновляет реплику (INV-PRF-1: только при event.Version > ReplicaVersion).
  2. Между сменой в identity и догоном consumer-а (окно eventual-consistency — секунды) guard решает по прежней реплике: self-операции ещё отклоняются по старому ContactsManagedBy (fail-closed, A4).
  3. После применения события проверка пропускает self-операции по новой реплике; фронт получает новые флаги из getMyProfile без ручных действий. Возврат к обычным сценариям UC-PRF-001..004 (для инвестора).

A4. Устаревшая реплика (событие ещё не доехало)

  1. Реплика в profile консервативнее фактического состояния identity: проверка решает по реплике — до догона consumer-а операции могут отклоняться по старому ContactsManagedBy.
  2. Поведение принято осознанно (fail-closed для персональных данных); операция повторяется после догона consumer-а (синка реплики).

Постусловие

  • Состояние БД profile не изменено ни одной отклонённой операцией (проверка срабатывает до мутаций и до сохранения).
  • Отказы зафиксированы в логах/метрике profile_managed_externally_rejections_total (без PII).
  • Данные менеджера в ЛК соответствуют последнему применённому событию Talent-синка.

Возможные Ошибки

КодHTTPУсловиеПоведение клиента
PROFILE_MANAGED_EXTERNALLY403Любая self-операция над персональными данными при ContactsManagedBy = TalentSync (INV-PRF-2)Скрыть формы, плашка «управляется Talent»
IDENTITY_CONTACTS_MANAGED_EXTERNALLY403Смена ФИО/email/phone на стороне identity (INV-4)То же — UC-IDN-004 A3
PROFILE_PERSONS_NOT_ALLOWED_FOR_USER_TYPE403Не-инвестор (A2, INV-PRF-4)Скрыть блоки персон/шаблонов/верификации
PROFILE_USER_BLOCKED403Status ∈ {Blocked, Archived} (INV-PRF-3)Экран блокировки
401 UNAUTHORIZED401Нет JWTAuth-модалка

Доменные События

СобытиеКогда поднимаетсяSubscribers
Отклонённые операции доменных событий не поднимают (мутаций нет); отказ — только лог + метрика
ProfileSettingsChangedEventA1 (разрешённая смена настроек)in-proc

Kafka Интеграционные События

СобытиеTopicКогда публикуетсяConsumers
Отклонённые операции события не публикуют
Consumed: UserUpsertedKafkaEvent.v1pin.identity.users.v1Единственный канал актуализации данных менеджера (шаг 7)profile (consumer identity-users-sync)

Acceptance Criteria

#КритерийПроверка
AC1Все 10+ self-операций над персональными данными (персоны/документы/сканы/шаблоны/верификация) возвращают 403 PROFILE_MANAGED_EXTERNALLY для TalentSync-пользователя, БД не меняетсяпараметризованный тест по всем операциям + снапшот БД
AC2getMyProfile для DeveloperManager отдаёт все canEdit*-флаги = false (кроме настроек)тест флагов
AC3updateMySettings доступен DeveloperManager (Locale/Timezone меняются)тест A1
AC4Guard срабатывает по реплике: смена ContactsManagedBy в identity вступает в силу в profile только после события (INV-PRF-1)тест A3/A4 с задержкой consumer-а
AC5Агент получает PROFILE_PERSONS_NOT_ALLOWED_FOR_USER_TYPE, а не PROFILE_MANAGED_EXTERNALLY (различимые причины)тест A2
AC6Отказы инкрементируют метрику и логируются без PIIпроверка лога/метрик
AC7Смена контактов менеджера в Talent доезжает в ЛК PIN без ручных действийсквозной тест синка (UC-IDN-007 → consumer)

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

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

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

  • Domain entity: ../domain/profile.md (INV-PRF-2/3/4, матрица возможностей ЛК), ../domain/person.md (INV-PRS-2/3).
  • Identity: ../../identity/domain/user.md (INV-4 ManagedContacts, ContactsManagementMode), UC-IDN-004 (A3 — запрет на стороне identity), UC-IDN-007 (источник данных менеджеров).
  • Consumer: ../consumers/identity-users-sync.md.
  • Наблюдаемость: README profile — alert «всплеск отказов PROFILE_MANAGED_EXTERNALLY».
  • Связанные UC: UC-PRF-001 (нормальный self-service инвестора — контраст), UC-PRF-006 (разрешённая смена контактов для SelfService-типов).