# Автоматическое создание групп и ограничение видимости пользователей

Разбор двух связанных вопросов администрирования: автоматическое создание групп при постановке задач (например, при добавлении новой компании) и ограничение видимости пользователей — чтобы сотрудники видели только коллег из своей группы. Документ для администраторов системы: содержит постановку задачи, анализ доступных и отсутствующих смарт-действий, обходные варианты и полный каскад механизмов видимости.

## Постановка задачи

Типичный сценарий:

1. Пользователи должны видеть **только пользователей из своей группы**.
2. Новые компании добавляются через карточки задач категории **«Участники»**, сотрудники — через категорию **«Пользователи»**.

**Два связанных вопроса:**

1. В смарт-действиях нет возможности после постановки задачи в категорию «Участники» автоматически создать группу. Можно создать орг.единицу, но группу придётся создавать вручную. Есть ли способ по событию создать группу и проставить спецправа?

2. Даже с включённым спецправом «Не видеть информацию о пользователях» — в поиске сотрудников пользователи видят всех и могут просматривать всю оргструктуру. В списке фильтрация работает корректно. Можно ли ограничить поиск и оргструктуру?


## Ответ на вопрос 1: Автоматическое создание группы

**Штатного смарт-действия «Создать группу» не существует** — назначение спецправ группе через смарт-действия тоже невозможно. Ниже перечислены доступные и отсутствующие смарт-действия секции «Оргструктура, группы, пользователи»:

### Доступные смарт-действия (секция «Оргструктура, группы, пользователи»)

Что есть и чего нет в смарт-действиях этой секции:

| Действие | Наличие | Комментарий |
|---|---|---|
| Создать орг.единицу | Да | Имя, тип, родительская орг.единица |
| Изменить орг.единицу | Да | Включая параметр «Связанная группа» (ID существующей группы) |
| Добавить пользователей в группы | Да | |
| Удалить пользователей из групп | Да | |
| Добавить пользователя в орг. единицу | Да | При наличии связанной группы — автоматически добавляет в неё |
| **Создать группу** | **Нет** | |
| **Назначить спецправо группе** | **Нет** | |

### Обходные варианты

#### Вариант A: Пул предсозданных групп

Готовые группы с нужными правами заранее создаются и по событию привязываются к новым орг.единицам:

1. Администратор заранее создаёт N групп (например, «Компания-001» ... «Компания-050») с нужным набором спецправ и прав группы на группу.
2. При постановке задачи в категорию «Участники» смарт-действие:
   - Создаёт орг.единицу (`Создать орг.единицу`).
   - Привязывает к ней очередную свободную группу (`Изменить орг.единицу` → параметр «Связанная группа»).
3. При постановке задачи в «Пользователи» смарт-действие:
   - Создаёт пользователя (`Создать пользователя`).
   - Добавляет в орг.единицу (`Добавить пользователя в орг. единицу`) — автоматически попадает в связанную группу.

**Плюсы:** работает штатно, без кода.
**Минусы:** ограниченный пул, требуется ведение «реестра» свободных групп (например, через ДП в задаче «Участники»).

#### Варианты B-D: альтернативные подходы (Lua, SQL, feature request)

**Вариант B: Lua-скрипт (смарт-скрипт).** Смарт-скрипты на Lua имеют доступ к расширенному API. Необходимо проверить, доступны ли через Lua функции создания групп и программного назначения спецправ. Если да — это полностью решает задачу: по событию «После постановки задачи» в «Участники» Lua-скрипт создаёт группу, назначает спецправа, привязывает к орг.единице. **Рекомендация:** уточнить у вендора доступность API создания групп через Lua.

**Вариант C: SQL-скрипт в пакете смарт-действий.** Смарт-действие «Выполнить SQL-скрипт» может вставить записи напрямую в таблицы `Groups` (создание группы), `GroupSpecialRights` (назначение спецправ), привязка группы к орг.единице. **Минусы:** хрупкое решение, зависит от внутренней схемы БД, не поддерживается официально, может сломаться при обновлении.

**Вариант D: Запрос на доработку вендору.** Запросить добавление смарт-действий «Создать группу» (с параметрами: имя, родительская группа, вложенные группы), «Назначить спецправо группе» (с параметрами: группа, список спецправ), «Назначить право группы на группу» (с параметрами: группа-субъект, группа-объект, право). Это логичное расширение существующего набора действий секции «Оргструктура, группы, пользователи».


## Ответ на вопрос 2: Видимость пользователей в поиске и оргструктуре

### Флаг Users.IsEmployee — физический фильтр

`Users.IsEmployee` (бит) — базовый фильтр: в блок «Сотрудники» и связанные выдачи попадают **только пользователи с `IsEmployee = 1`**.

- У сотрудников компании: `IsEmployee = 1`
- У внешних пользователей (клиенты, партнёры, экспедиторы): `IsEmployee = 0`

Это физическое ограничение — работает **поверх всех настроек прав и рабочих мест**. Если внешний пользователь видит в списке сотрудников других внешних пользователей — проверить их `IsEmployee` в первую очередь.

Проверка: `SELECT UserID, Login, IsEmployee FROM Users WHERE UserID IN (...)`

### Рабочее место группы (UserGroupSettings.StaffVisible) — рекомендуемый подход

Поле `StaffVisible` в таблице `UserGroupSettings` управляет видимостью блока «Сотрудники» в навигации для группы:

| Значение | Поведение |
|---|---|
| `0` | Не задано (наследуется или показывается по умолчанию) |
| `1` | **Не показывать** — блок «Сотрудники» скрыт из навигации |
| `2` | **Показывать** |

Скрытие через рабочее место убирает блок «Сотрудники» из навигации **и** скрывает вкладку сотрудников в результатах поиска. Примеры настройки:

- Группа внешних пользователей: `StaffVisible = 1` — блок не виден
- Группа партнёров: `StaffVisible = 2` — блок виден (партнёрам нужен справочник)

Настройка: **Администрирование → Рабочее место** (SPA: `/spa/admin-ds/forms/group-start/grid`).

> Альтернатива спецправу «Не видеть информацию о пользователях» — использовать рабочее место (`StaffVisible`) + физический фильтр `IsEmployee`. Это более гибкий и предсказуемый подход.

### Механизм видимости — полный каскад

Видимость пользователей складывается из нескольких механизмов — от физического фильтра до точечных прав:

| # | Механизм | Что делает |
|---|---|---|
| 0 | **`Users.IsEmployee = 0`** | Физически исключает пользователя из выдачи блока «Сотрудники» |
| 1 | **Рабочее место** (`StaffVisible = 1`) | Скрывает блок «Сотрудники» из навигации и поиска для группы |
| 2 | Спецправо **«Не видеть информацию о пользователях»** | Полностью скрывает профили: в справочнике, поиске, по прямой ссылке (ошибка) |
| 3 | Право группы на группу **«Просматривать профили участников группы»** | Восстанавливает видимость профилей конкретных групп при активном спецправе #2 |
| 4 | Спецправо **«Видеть орг.единицы у пользователей»** | Показывает оргструктуру в меню «Сотрудники», но переходы к профилям остаются заблокированы (при активном #2) |

Дополнительно:

- Спецправо **«Видеть всех пользователей в результатах поиска»** — при включении поиск показывает все результаты (а не первые 10). Его **не должно быть** у групп внешних пользователей.

### Видимость в API поиска контактов (`/mobile/users/search`)

Endpoint `POST /app/v1.0/api/mobile/users/search` используется фронтом и мобильными клиентами для поиска пользователей при выборе акцептанта подписи, подписчиков, при упоминании в комментариях, в чатах и т.п. Каскад выше относится к блоку «Сотрудники» в навигации, а этот endpoint имеет собственную цепочку фильтров.

**Базовый набор:** FTS-поиск по `DisplayName` + точный поиск по email; уволенные исключаются (`IsFired = 0`). Дополнительные параметры `ContactFilter`: только избранное (`InFavsOnly`), наличие email (`WithEmailOnly`), поиск по ДП (`InExtInfo`).

**Фильтры по правам запрашивающего:**

| Условие на запрашивающего | Эффект |
|---|---|
| Имеет спецправо `SeeOnlyUsersOfYourDomain` | Результат ограничивается тем же доменом входа |
| Имеет `NOTVIEWUSERINFO` И не имеет `VIEWALLSEARCHRESULTS` И ни одна его группа не имеет `ViewGeneralInformation` | Возврат пустого списка |
| **`Users.IsEmployee = 0` (не сотрудник)** | Каждый кандидат проходит дополнительную проверку: у группы запрашивающего должно быть межгрупповое право **`ViewGeneralInformation`** на группу кандидата. Несовпадающие отсеиваются |

**Типичный кейс:** группа внешних пользователей хочет видеть друг друга при выборе акцептанта подписи (или подписчика). По умолчанию — никого не возвращает.

Решение для администратора: настроить межгрупповое право **«Видеть общую информацию»** (`ActionsGroupOnGroup.ViewGeneralInformation`) от группы внешних пользователей на саму себя (или на ту группу, чьих участников нужно видеть). Путь: **Администрирование → Группы → выбранная группа → Права на группу → выбрать целевую группу → отметить «Видеть общую информацию» → Сохранить**.

![Вкладка «Права на группу»: межгрупповые права над участниками другой группы](https://help.1forma.ru/help-images/users-and-groups/admin_group_rights.png)

> Ограничение «несотрудникам показываются только контакты из избранного» срабатывает **только** при включённом фильтре «только избранное». Автоматического ограничения несотрудников избранным **нет**.

### Что проверить при настройке

Если пользователи видят лишних, проверьте по порядку:

1. **Спецправо «Видеть всех пользователей в результатах поиска»** — если оно выдано группе, пользователи видят всех в поиске. Нужно убрать.

2. **Спецправо «Видеть орг.единицы у пользователей»** — если выдано, пользователи видят всю оргструктуру. Имеет приоритет выше, чем «Не видеть информацию о пользователях». Если оргструктура не нужна — убрать.

3. **Право группы на группу «Просматривать профили участников группы»** — должно быть настроено **только на свою группу** (группу своей компании). Если настроено на «Все» или на лишние группы — пользователи видят чужих.

4. **Версия системы и клиент (SPA/старый)** — поведение может различаться. Документация утверждает, что спецправо #1 скрывает пользователей «в поиске и в справочнике сотрудников». Если в поиске всё равно видны — это может быть баг SPA-клиента.

### Ограничение: видеть только свою оргструктуру

**Штатно невозможно.** Спецправо «Видеть орг.единицы у пользователей» показывает **всю** оргструктуру или скрывает **всю**. Частичное ограничение по веткам (видеть только свою компанию) не поддерживается.

Возможный workaround:

- **Не выдавать** спецправо «Видеть орг.единицы» вообще — тогда оргструктура недоступна.
- Если нужно видеть коллег — использовать **право группы на группу → «Просматривать профили участников группы»** на свою группу. Пользователи увидят коллег в справочнике сотрудников (список), но не через оргструктуру.

### Блок «Коллеги» в профиле пользователя

Блок «Коллеги» в профиле формируется из участников **родительской группы**. Если все внешние пользователи входят в одну общую родительскую группу (например, «Экспедиторы») — они видят друг друга как коллег, даже при скрытом блоке «Сотрудники».

Варианты решения:

- Спецправо **«Не видеть коммерческую информацию»** (`spactionViewShortUserProfileInfo`) — скрывает блок «Коллеги» в чужих профилях. Побочный эффект: также скрываются отдел, должность, блок «Мои группы».
- Если побочный эффект неприемлем — оставить как есть. Скрытие блока «Сотрудники» (рабочее место) уже убирает основной путь к чужим профилям.

Если после корректной настройки спецправ поиск всё равно показывает всех пользователей, зафиксируйте какой именно поиск (быстрый в шапке, расширенный, выбор исполнителя в задаче) и версию системы, затем обратитесь в техподдержку — возможен баг в фильтрации поиска SPA-клиента при активном спецправе «Не видеть информацию о пользователях».


## Итоговая таблица

Сводка ответов и рекомендуемых действий:

| Вопрос | Ответ | Действие |
|---|---|---|
| Автоматически создать группу смартами | Невозможно штатно | Варианты: пул групп / Lua / SQL / feature request |
| Автоматически назначить спецправа группе | Невозможно штатно | Варианты: пул групп с предустановленными правами / Lua / SQL |
| Поиск сотрудников показывает всех | Проверить спецправа | Убрать «Видеть всех в поиске», проверить «Не видеть информацию» |
| Видеть только свою оргструктуру | Невозможно штатно | Не выдавать «Видеть орг.единицы», использовать права группы на группу |

