5.3 KiB
Raw Permalink Blame History

directory-policy Specification

Purpose

Политика видимости справочников поверх прав: что именно из ГК/ЮЛ/ГСК видит пользователь, определяется данными о его филиале, а не кодом роли (§10.1 05-domain-rules.md).

Requirements

Requirement: Область видимости вычисляется из филиала пользователя

Для каждого запроса ядро SHALL вычислять область видимости из Principal: если regional_office.is_head_office = true — вся система; иначе — ГК с company_group.base_regional_office_id = app_user.regional_office_id, их ЮЛ и ГСК/ГСЗ, а также монозаёмщики с legal_entity.regional_office_id = app_user.regional_office_id. Код роли (role.code) MUST NOT участвовать в вычислении; business_segment в Срезе 1 не используется (ASSUMPTION(OQ-86)).

Scenario: Пользователь филиала видит только своё

  • WHEN есть ГК А (филиал X) и ГК Б (филиал Y), пользователь KA_RF филиала X запрашивает список ГК
  • THEN в ответе только ГК А, total = 1

Scenario: Пользователь ГО видит всё

  • WHEN пользователь с is_head_office = true запрашивает список ГК
  • THEN в ответе обе ГК

Requirement: Объект вне видимости неотличим от несуществующего

Чтение, изменение и любые операции над ГК/ЮЛ/ГСК вне области видимости SHALL возвращать 404 с тем же телом, что и для несуществующего идентификатора; 403 для этого случая MUST NOT использоваться.

Scenario: Чужая ГК по id

  • WHEN пользователь филиала X запрашивает GET /directories/company-groups/{id} ГК Б
  • THEN ответ 404, текст совпадает с ответом на случайный uuid

Requirement: Политика применяется до прав на изменение

Проверка права (require) и проверка видимости SHALL выполняться обе; порядок: право → видимость → операция. Создание ГК пользователем филиала SHALL привязывать её к его филиалу, если base_regional_office_id не указан; указание чужого филиала пользователем филиала → 422 OFFICE_NOT_ALLOWED.

Scenario: Создание ГК из филиала

  • WHEN пользователь филиала X с DIRECTORY_EDIT создаёт ГК без филиала
  • THEN у ГК base_regional_office_id = X, и она видна создателю

Requirement: Видимость консолидаций и редактируемость версии

Консолидация и её версии SHALL быть видимы тем же пользователям, что и её ГК (company_group); чужие и несуществующие — 404 с одинаковым телом (код NOT_FOUND, сообщение CONSOLIDATION_NOT_FOUND / VERSION_NOT_FOUND; так устроены все 404 этого среза: NotFoundError несёт только текст сообщения). Правка версии (периметр, ручная смена статуса, сопоставление контрагента) SHALL проходить проверки в порядке: право → видимость → статус версии ∈ {INITIATED, DOCUMENTS_PROCESSING, DATA_CORRECTION} (иначе 409 VERSION_NOT_EDITABLE) → активная consolidation_lock есть (иначе 409 LOCK_REQUIRED) и принадлежит пользователю (иначе 409 LOCKED_BY_OTHER с владельцем). Проверка реализуется чистой функцией в domain/policy.py без обращения к коду роли. Чтение (карточка, свод, чек-лист, экспорт, кандидаты) и загрузка/подтверждение документов от статуса блокировки MUST NOT зависеть. Зоны ответственности не учитываются (ASSUMPTION(OQ-86)).

Scenario: Чужая блокировка

  • WHEN версию держит А, Б с CONSOLIDATION_EDIT вызывает PUT …/members
  • THEN 409 LOCKED_BY_OTHER, detail.locked_by = A

Scenario: Аннулированная версия

  • WHEN версия в CANCELLED, владелец прежней блокировки вызывает POST …/osv/entries/{id}/counterparty
  • THEN 409 VERSION_NOT_EDITABLE

Scenario: Куратор ГО читает

  • WHEN curator_go (только CONSOLIDATION_VIEW) запрашивает свод версии любого филиала
  • THEN 200