Персонал — отделы, сотрудники, проекты, задачи, кадровый резерв
Простыми словами: это собственный внутренний PM/staffing-инструмент P4P — здесь компания ведёт свои отделы, проекты и задачи, а также рассматривает людей, которые хотят работать с P4P. Несмотря на то, что /team/* не совпадает по форме с обычным /org/:slug/*, под капотом это теперь по-настоящему рабочее пространство организации — P4P Internal, а не функция уровня Platform: см. Архитектурные уровни. До 2026-08-18 этот модуль был закрыт правами Platform RBAC (platform:staffing:*); docs/staffing/ADR-002-org-rbac-migration.md перевёл его на Organization RBAC, ограниченную организацией P4P Internal — тот же механизм Role/Permission/TenantGuard+ PermissionsGuard, что использует любая другая организация, теперь под ключами workspace:staffing:*. PlatformStaffMembership остаётся отдельным, не связанным с этим гейтом сверху (HR/кадровый факт — «признан ли этот человек сотрудником P4P вообще» — миграция его не затронула): нужны оба, чтобы вообще что-то здесь увидеть, но отвечают они на разные вопросы.
Все роуты разделяют middleware: 'staffing-access' + requiresPermission: 'workspace:staffing:read' (гейт уровня страницы; отдельные изменяющие действия требуют :manage, см. ниже) и layout: 'team' — кроме /account/hr-pool (см. Твой профиль в кадровом резерве) — обычной страницы с layout: 'account' и вовсе без гейта workspace:staffing:*, построенной как раз для той аудитории, которую весь остальной модуль по определению исключает. Бэкенд: apps/core-api/src/modules/staffing/*.
Как сделать...
Сгруппировано так же, как технические разделы ниже — иконка помощи каждой страницы ведёт прямо в свою группу, а не во весь этот список.
Поиск
Поиск… Ctrl K в шапке (на телефоне — лупа) или Ctrl+K (⌘K на Mac) в любом месте раздела открывает окно поиска. Наберите хотя бы 2 символа: найдутся задачи, проекты, люди, отделы и кандидаты HR pool по названию (люди — ещё по почте, кандидаты — по навыкам), до 5 в каждой группе. ↑ ↓ — выбрать, Enter — открыть, Esc — закрыть. Пока вы ничего не набрали, окно показывает, что вы недавно открывали из поиска. Ищутся только названия, не описания и не комментарии, и только то, что вы и так можете открыть из списков; проекты в архиве не показываются.
Отделы
Создать отдел — «Персонал → Отделы» → Создать новый отдел → Название, выбери Руководителя → Создать отдел. См. гайд по полям — что означает каждое поле.
Отредактировать отдел — открой отдел → меню ⋯ (справа вверху) → Редактировать отдел. Те же поля, что при создании.
Удалить отдел — открой отдел → ⋯ → Удалить. Заблокировано, пока у отдела есть активные суб-отделы — см. Суб-отделы. Это лишь архивирует отдел.
Восстановить удалённый отдел — список Персонал → Отделы → вкладка Архив → кнопка Восстановить в строке отдела. Члены, роли и привязанные проекты возвращаются как были.
Создать/отредактировать отдел — гайд по полям
- Название — обязательно, от 2 до 100 символов, видно везде в приложении (списки, хлебные крошки, карточки).
- Руководитель — обязательно; найди и выбери сотрудника. Он сразу получает доступ к собственной финансовой книге отдела просто по факту руководства — больше ничего настраивать не нужно.
- Описание — необязательно, до 2000 символов, показывается на вкладке Overview отдела.
- Родительский отдел — необязательно; оставь «Нет», если это не суб-отдел. Вложенность ограничена одним уровнем, поэтому у суб-отдела не может быть своих суб-отделов.
Участники
Добавить кого-то в отдел — открой отдел → вкладка Члены → Добавить члена → выбери сотрудников → Добавить (N). См. гайд по полям.
Описать, чем человек реально занимается в отделе — отдел → вкладка Члены → меню ⋯ строки → Изменить функции. См. гайд по полям.
Удалить кого-то из отдела — отдел → вкладка Члены → меню ⋯ строки → Удалить из отдела.
Вкладка «Члены» — гайд по полям
- Добавить члена — найди и выбери одного или нескольких сотрудников, ещё не состоящих в этом отделе → Добавить (N).
- Роль (только для чтения) — реальная платформенная роль человека (например «P4P Admin»). Чтобы реально изменить, что он может делать, выдавай или отзывай его платформенную роль на странице Администрирование платформы → Пользователи — эта вкладка её только показывает.
- Функции — свободная заметка о том, чем человек реально занимается в отделе (клик по ячейке «Функции» или ⋯ → Изменить функции), отдельно от Роли выше. До 2000 символов; в таблице видна одна строка, клик разворачивает полный текст. Собственный руководитель отдела может это редактировать даже без более широких прав управления.
Проекты (вкладка «Проекты» отдела)
Прикрепить проект к отделу — отдел → вкладка Проекты → Прикрепить проект → выбери → подтверди. См. также Проекты → Участники — то же самое со стороны проекта.
Открепить проект от отдела — отдел → вкладка Проекты → меню ⋯ строки → Открепить от отдела.
Суб-отделы
Создать суб-отдел — отдел → вкладка Суб-отделы → Новый подотдел (тот же пункт есть и в меню ⋯) — та же форма, что и создание любого отдела, с уже заполненным родительским отделом. Недоступно, если у отдела уже есть родитель — вложенность ограничена одним уровнем.
Сотрудники
Добавление здесь — не действие staffing, а процесс приглашения в штат платформы, описанный в «Как сделать...» Администрирования платформы, просто со ссылкой отсюда для удобства.
Отправить кого-то в отпуск или вернуть из него — открой профиль → меню ⋯ → Отправить в отпуск / Вернуть из отпуска. Это меняет только внутренний статус занятости, не сам аккаунт — см. Администрирование платформы → Пользователи для блокировки аккаунта целиком.
Описать, что человек делает на проекте — открой профиль → вкладка Проекты → Указать функцию / Изменить функцию в строке проекта. Это проектный аналог заметки Функции по отделам выше и редактирует ту же заметку участника, что показывает вкладка Участники самого проекта.
Проекты
Создать проект — «Работа → Проекты» → Новый проект → заполни поля → Создать. См. гайд по полям.
Отредактировать проект — либо из списка «Работа → Проекты» (меню ⋯ строки → Редактировать), либо изнутри самого проекта (иконка карандаша рядом с его названием). Те же поля, что при создании, плюс Статус и Прогресс.
Удалить проект — список «Работа → Проекты» → меню ⋯ строки → Удалить. Удаляет навсегда всё содержимое — отделы, этапы, задачи и участников.
Создать/отредактировать проект — гайд по полям
- Название — обязательно, от 1 до 100 символов.
- Описание — необязательно, до 2000 символов, показывается в списках и карточках проектов.
- Отдел — необязательно; команда, которой принадлежит проект (его место в оргструктуре). Выбери живой отдел или оставь «Без отдела». Показывается в Обзоре проекта и используется для группировки — это отдельно от выводимых «ещё задействованных» отделов (в каких отделах состоят назначенные участники), которые Обзор показывает рядом. При создании проекта с выбранным отделом галочка предлагает сразу добавить в участники текущий состав этого отдела (разовый снимок).
- Статус (только при редактировании) — Planned / Active / Completed / Archived. Каждый новый проект начинается со статуса Planned.
- Прогресс (только при редактировании) — число от 0 до 100 для полосы прогресса проекта. Его устанавливаешь вручную — он не считается сам из завершённости задач или этапов.
- Владелец — необязательно; найди и выбери сотрудника, или оставь пустым, и по умолчанию им станешь ты сама. Владелец может прикрепить участников к своему проекту даже без более широких прав управления проектами — см. Участники ниже.
- Vision — необязательно, до 2000 символов, о том, зачем нужен проект и как выглядит «готово». Поддерживает форматирование (жирный текст, списки, ссылки) и живёт на вкладке Overview проекта, где его можно редактировать прямо там же.
Шаблоны проектов
Шаблон проекта — это готовая заготовка проекта для команды: описание, видение, этапы по порядку и все задачи (с метками и подзадачами). Люди, даты, статусы, бюджет, комментарии и файлы в шаблон не входят.
- Создать: откройте проект → ⋯ (вкладка «Обзор») → Сохранить как шаблон и дайте имя. Сохраняются все задачи, выполненные тоже.
- Изменить: поправьте проект и снова сохраните его под тем же названием — окно предупредит, что шаблон будет заменён.
- Использовать: в окне Новый проект выберите шаблон в поле Из шаблона. Описание и видение заполнятся сами; строка под выбором говорит, сколько этапов и задач создастся. После Создать они появятся, все задачи — заново.
- Управлять шаблонами: на странице проектов кнопка шаблонов рядом с + (на телефоне ⋯ → Шаблоны проектов) — посмотреть состав, переименовать или удалить. Управляют те, кто может создавать проекты. Удаление шаблона не меняет проекты, уже созданные из него.
Обсуждение проекта
Написать в проект — проект → вкладка Обсуждение → поле внизу → Отправить (Enter отправляет, Shift+Enter — новая строка). Работает форматирование: жирный, списки, ссылки.
Изменить или удалить свою запись — навести на запись → карандаш или корзина. Их видит только автор: руководитель не может переписать чужие слова. Изменённая запись помечается «изменено», удалённая оставляет строку в Истории, чтобы ветка не менялась незаметно.
Посмотреть журнал событий — та же вкладка → История. Это автоматическая запись (создали задачу, добавили человека, передвинули этап); обсуждение — то, что писали люди. Раньше они шли одним потоком и были разделены, потому что вместе читались как шум.
Что сюда писать
Всё по проекту, что не относится к одной задаче: клиент передвинул дедлайн, вот бриф, решили не делать второй лендинг. Вопрос по конкретной задаче — в комментарии этой задачи, там его увидят те, кто над ней работает.
Участники
Отдельной вкладки «Отделы» нет (убрана 2026-08-30). Все на проекте — это явные участники; отдел показывается как группа, только если кто-то из его людей на проекте.
Посмотреть, кто на проекте — проект → вкладка Участники. Сверху переключатель Штат / Кадровый резерв. Для «Штата» дальше — По отделам (дерево) / Списком.
Добавить целый отдел разом — проект → вкладка Участники → + → Добавить всех из отдела → выбери отдел → Добавить участников. Отдел самого проекта (если задан) уже отмечен. Все текущие члены отдела становятся участниками. Это разовый снимок — тот, кто вступит в отдел позже, сам не появится. (То же самое предлагается галочкой в форме создания проекта, когда задаёшь отдел проекта.)
Добавить одного человека — проект → вкладка Участники → + → Добавить участника → вкладка Штат или Кадровый резерв → выбери человека → подтверди. См. гайд по полям.
Убрать одного человека — меню ⋯ строки → Убрать с проекта.
Убрать нескольких разом — отметь строки галочками (или галочку в заголовке группы отдела, чтобы выбрать всех из него) → Убрать выбранных в появившейся панели → подтверди. В отделах они остаются — снимается только привязка к этому проекту.
Отредактировать заметку об участнике — меню ⋯ строки → Редактировать. Ту же заметку «что делает» можно задать и с другой стороны: карточка сотрудника → вкладка Проекты → Указать функцию / Изменить функцию в строке проекта (workspace:staffing:projects:manage). У проекта, где человек только выполняет задачи и никогда не был добавлен участником, заметки нет.
Добавить участника — гайд по полям
- Источник (при добавлении) — Штат для действующего сотрудника P4P или Кадровый резерв для внешнего контрактора.
- Человек (при добавлении) — обязательно. В списке Штат — действующие сотрудники P4P с доступом к Team Management (
workspace:staffing:read), ещё не на проекте; в списке Кадровый резерв — только записи со статусом Approved. - Что делает на проекте — одна необязательная свободная заметка (роль, задачи, зона ответственности). Это не поле «роль» — реальная роль человека в Team Management отдельная и живёт на его карточке сотрудника.
Этапы
Добавить этап — проект → вкладка Этапы → Добавить этап → название/описание/даты → создать.
Изменить порядок этапов проекта — проект → вкладка Этапы → перемести этап стрелками ↑/↓.
Отредактировать или удалить этап — проект → вкладка Этапы → меню ⋯ строки → Изменить стадию или Удалить этап. При удалении задачи этапа не удаляются, а открепляются.
Добавить/отредактировать этап — гайд по полям
- Название — обязательно, от 1 до 100 символов.
- Описание — необязательно, до 2000 символов.
- Дата начала / Срок — оба необязательны; они следят друг за другом, так что нельзя выбрать начало позже срока или наоборот.
- Статус (только при редактировании) — Planned / In progress / Completed. Каждый новый этап начинается со статуса Planned, и ты устанавливаешь его вручную — список этапов отдельно отмечает, если статус расходится с задачами внутри (например, отмечен завершённым, а задачи ещё открыты), но не исправляет это за тебя.
- Владелец — необязательно, чисто информационное поле, как и у проекта.
Спринты (вкладка проекта «Спринты»)
Спринт — это отрезок времени для части работы проекта, обычно одна-две недели, с необязательной целью. Новый спринт предлагает следующий номер и две недели после последнего спринта; спринты одного проекта не могут пересекаться по дням. Одновременно идёт только один спринт: Начать спринт у запланированного (пока идёт другой, кнопка объясняет, почему нельзя).
У идущего спринта видны цель, даты, сколько дней осталось, сколько задач и часов готово, и его задачи в виде маленькой доски (К выполнению / В работе / Готово). Ниже — запланированные спринты и бэклог: задачи проекта без спринта, которые ещё не готовы. Отметьте задачи бэклога и нажмите В спринт, чтобы запланировать их. Спринт задачи можно выбрать и в её Деталях → Спринт (это может тот, кто может менять срок задачи). Завершить спринт оставляет готовые задачи в нём и спрашивает, куда деть незаконченные: в следующий запланированный спринт или обратно в бэклог. Удалить можно только запланированный спринт; его задачи вернутся в бэклог. На странице задач то же показывают колонка и фильтр Спринт.
График (вкладка проекта «График»)
План проекта на шкале времени, только для просмотра. Каждый этап — тонкая полоса по его датам, под ним его задачи (раньше начинающиеся — выше, подзадачи с отступом), затем задачи без этапа. Задача с началом и сроком — полоса цвета её статуса; только со сроком — ромб; незаконченная задача с прошедшим сроком обведена красным. Стрелки идут от задачи к той, что её ждёт (зависимости); значок связи означает зависимость от задачи из другого проекта — наведите, чтобы увидеть какой. Красная вертикальная линия — сегодня. Неделя / Месяц / Квартал меняет масштаб, выбор запоминается. Клик по названию или полосе открывает задачу. Задачи без дат перечислены под графиком — укажите им начало или срок (страница задачи → Детали или Изменить задачу), чтобы они появились. Задача не может начинаться позже срока.
Задачи (вкладка «Задачи» проекта)
Создание и управление задачами изнутри проекта — тот же процесс, что и в разделе Задачи ниже, просто заранее привязан к этому проекту.
Задачи
Создать задачу откуда угодно — «Работа → Задачи» (сквозная доска по всем проектам) → Новая задача → название → Выберите проект → Выберите сотрудника → Создать задачу. Список исполнителей здесь — вся компания, не только участники выбранного проекта; если выбранный человек (в том числе ты сама) ещё не прикреплён к проекту, форма это явно покажет и попросит подтверждения, прежде чем заодно с созданием задачи добавить его туда. См. гайд по полям.
Изменить статус/исполнителя и т.д. у задачи — Статус и Прогресс редактируются прямо в списке (в колонках «Статус» и «Прогресс»: статус — выпадающим списком, прогресс — ползунком в границах, заданных текущим статусом); статус можно сменить ещё и в диалоге Изменить задачу — меню ⋯ строки → Редактировать, и на вкладке «Задачи» проекта, и в сквозном списке «Задачи» (только :manage; сквозной список на лету подгружает контекст проекта задачи, чтобы открыть тот же диалог). Остальные поля — кликом прямо на странице задачи. См. гайд по полям.
Перенастроить список статусов задач — «Работа → Задачи» → иконка шестерёнки → Настройка колонок → добавляй/переименовывай/меняй порядок/деактивируй статусы. См. гайд по полям.
Удалить задачу — открой задачу → меню ⋯ → Удалить, либо меню ⋯ строки → Удалить на вкладке «Задачи» проекта или в сквозном списке «Задачи» (только :manage).
Изменить много задач сразу — Работа → Задачи, вид Список → отметьте строки (или флажок в заголовке — вся страница) → над таблицей появится панель: Статус, Приоритет, Срок, Метки, а с правом :manage — ещё Ответственный и Удалить. Каждое действие спрашивает, что поставить, и применяет это ко всем выбранным задачам. Задача, которую вам менять нельзя (или, для Ответственного, задача из проекта, к которому человек не допущен), пропускается — итог покажет, какие и почему; остальные меняются. Выбор — в пределах страницы, до 100 задач. На телефоне пока недоступно.
Указать, какая задача какую ждёт — откройте задачу → Зависимости (под описанием) → + → выберите Эта задача ждёт… или Эта задача блокирует… → найдите другую задачу по названию (в любом проекте) → Добавить зависимость. Задача, которая ещё ждёт незаконченные задачи, отмечена песочными часами (Ждёт задачи) на своей странице, в списке задач и на карточках доски. Перевести её в работу или в «Готово» всё равно можно — появится только предупреждение. Добавлять и убирать то, чего ждёт задача, может только тот, кто может менять саму ждущую задачу; задача не может ждать саму себя или — через цепочку — задачу, которая ждёт её. Песочные часы — это не статус Заблокирована: его по-прежнему ставят вручную.
Создать/отредактировать задачу — гайд по полям
Два входа в эту форму ведут себя немного по-разному:
- «Новая задача» с общей доски «Задачи» (и с карточки сотрудника) — отдельный диалог с полем Проект, только на создание, без редактирования. Кандидаты на Исполнителя/Помощников — вся компания; если выбранный ещё не на проекте, диалог спрашивает согласия и сам добавляет его туда вместе с созданием задачи.
- Диалог внутри проекта (вкладка «Задачи» проекта — им же открывается и создание, и редактирование существующей задачи) — проект уже известен, поле не показывается. Кандидаты на Исполнителя/Помощников — только уже прикреплённые к этому проекту: сотрудники из его привязанных отделов, сотрудники, прикреплённые индивидуально, и контракторы кадрового резерва этого проекта.
Остальные поля у обоих одни и те же. Статус — единственное, что предлагается только при редактировании: новая задача всегда стартует со статуса по умолчанию. Сделать задачу подзадачей — отдельное действие, см. примечание в конце.
- Название — обязательно, от 1 до 150 символов.
- Проект — обязательно (только в форме с общей доски); от выбранного проекта зависят Этап, Отдел и список кандидатов на Исполнителя/Помощников, все сбрасываются при его смене.
- Приоритет — Urgent / High / Medium / Low. По умолчанию Medium.
- Этап — необязательно; появляется после выбора проекта, предлагает его собственные этапы.
- Отдел — необязательно; должен быть одним из привязанных отделов проекта.
- Описание — необязательно, до 2000 символов.
- Исполнитель — обязательно, человек, ответственный за задачу, и это поле никогда не остаётся по-настоящему пустым:
- при создании по умолчанию подставляется тот, кто создаёт задачу — если он сам годится в исполнители;
- при редактировании, если исполнителя ещё нет, по умолчанию подставляется автор задачи — опять же только если он сам годится; поле нельзя очистить до пустоты, можно только сменить на другого человека.
- Единственный случай, когда поле остаётся пустым, — ни у создателя/автора нет права быть исполнителем на этом проекте (например, старая задача без записанного автора); тогда выбираешь вручную, и кнопка сохранения недоступна, пока не выберешь.
- Оценка времени, ч — необязательно; плановое время на задачу в часах, десятичным числом (например,
1.5= 1 час 30 минут). Ни на что не влияет автоматически, чисто ориентир для планирования — фактически потраченное время смотри в Учёте времени ниже. - Срок — необязательно.
- Повторяется — необязательно; см. Повторяющиеся задачи ниже. У подзадачи этого поля нет.
- Помощники — необязательно; любое число дополнительных людей в поддерживающей роли, из того же списка кандидатов, что и Исполнитель.
- Статус (только при редактировании) — любой статус из словаря (те же, что колонки канбан-доски). При смене статуса прогресс задачи пересчитывается по категории нового статуса. Статус редактируется и прямо в списке — выпадающим списком в колонке «Статус», везде, где у тебя есть право писать эту задачу.
- Стоимость / Валюта — обычное число для внутреннего учёта бюджета — это заметка, а не настоящая запись в книге учёта (сравни с Выплатами за задачи, которые как раз ей и являются).
- Сделать задачу подзадачей — отдельное действие: меню ⋯ задачи → Add subtask, делается один раз при создании и не меняется позже. Только один уровень вложенности — у подзадачи не может быть своих подзадач.
Автоматизации
Автоматизации (страница задач → ⋯ → Автоматизации, для тех, кто может настраивать статусы и метки) — правила, которые меняют задачи за вас: Когда с задачей что-то происходит — она создана, её статус стал выбранным или назначен ответственный, — если она подходит под выбранные условия (проекты, метки, приоритеты; оставьте пустыми для любой задачи), то по порядку выполняются действия: назначить ответственного, добавить метку, поставить приоритет, сменить статус, добавить наблюдателя или создать задачу из шаблона в том же проекте.
Правило срабатывает сразу после изменения, от имени того, кто последним его сохранил, и в истории задачи рядом с его изменением написано Автоматизация «…». Изменения, сделанные правилом, другие правила не запускают. У каждого правила видно, сколько раз и когда оно сработало и был ли последний запуск с ошибкой; Журнал показывает последние срабатывания и причину сбоя (например, человек больше не в проекте). Выключатель отключает правило, не удаляя его.
Шаблоны задач
Шаблон — это готовая заготовка задачи для всей команды, например «Еженедельный отчёт» или «Онбординг сотрудника». В нём есть название задачи, описание, приоритет, оценка времени, метки и список подзадач. Людей и дат в шаблоне нет — их выбирают для каждой задачи.
- Использовать шаблон: в окне Новая задача (на доске или внутри проекта) выберите его в поле Из шаблона. Название, описание, приоритет и оценка заполнятся сами — их можно изменить. Строка под выбором говорит, что ещё получит задача: после Создать добавятся её метки и создадутся подзадачи. Подзадачу из шаблона создать нельзя.
- Сохранить задачу как шаблон: откройте задачу → ⋯ → Сохранить как шаблон и дайте имя. Сохранятся название, описание, приоритет, оценка, метки и названия подзадач.
- Управлять шаблонами: на странице задач ⋯ → Шаблоны задач — создать, изменить или удалить. Пользоваться шаблонами может каждый, кто видит задачи; управлять — те, кто может создавать задачи. Двух шаблонов с одинаковым названием быть не может. Изменение или удаление шаблона не меняет задачи, уже созданные из него.
Свои поля задач
Свои поля — это поля, которых нет в задаче по умолчанию, например «Клиент», «Оценка в очках» или «Согласовано клиентом». Поля общие для всей команды. Есть пять видов: текст, число, дата, список (выбор одного варианта) и да/нет.
- Настроить поля: на странице задач ⋯ → Поля задач. Там можно добавить, изменить, удалить поле и поменять порядок стрелками. Для каждого поля выберите: все проекты или только некоторые проекты. Вид поля после создания изменить нельзя. Настраивать поля могут те, кто настраивает команду.
- Заполнить поле: в задаче, в блоке Детали → раздел Поля, нажмите карандаш у поля. Заполнять поля может тот, кто может менять задачу. Каждое изменение видно в Истории задачи.
- Таблица и фильтр: у каждого поля есть своя колонка в таблице задач (новые колонки сначала скрыты — включите их кнопкой колонок). Поля «список» и «да/нет» можно выбрать в Фильтрах; такой фильтр сохраняется в сохранённых фильтрах.
- Что стирается: если удалить вариант списка, он снимается с задач, где был выбран. Если убрать проект у поля, значения этого поля у задач проекта стираются. Если удалить поле, стираются все его значения — окно заранее говорит, у скольких задач оно заполнено.
Повторяющиеся задачи
Повторяется возвращает задачу по расписанию: каждый день, каждую неделю в выбранные дни, раз в две недели или каждый месяц в одно и то же число — с необязательной датой До. Повтор можно задать при создании задачи, в Изменить задачу или на странице задачи → Детали → Повторяется. Менять повтор может тот, кто может менять задачу.
В каждый день повтора, рано утром, появляется новая копия задачи — даже если прошлая ещё не закончена. У неё те же название, описание, приоритет, этап, отдел, оценка, исполнитель, помогающие и метки, что у последней копии, поэтому изменение последней копии переходит в следующие. Комментарии, время, стоимость, файлы и подзадачи не копируются. Даты копии сдвигаются вместе с ней: задача с понедельника по среду с еженедельным повтором станет задачей с понедельника по среду следующей недели; у задачи только со сроком срок станет днём повтора. Первая копия появляется после собственной даты начала или срока задачи.
У повторяющейся задачи на доске и в таблицах есть значок ⟲ — наведите на него, чтобы увидеть правило. В «Деталях» под Повторяется видно, когда будет следующая копия. Изменение повтора касается только будущих копий. Вариант Не повторяется останавливает повтор; уже созданные копии остаются обычными задачами. Подзадача повторяться не может — включите повтор у родительской задачи.
Учёт времени на задаче
На странице самой задачи, в панели «Детали», сразу под Оценка времени — поле Затрачено: сумма всех залогированных часов по задаче. Кнопка + рядом с ним видна только тем, кто сам исполнитель или помогающий этой задачи — открывает маленькую форму «часы + дата» и добавляет запись, увеличивая сумму. Список отдельных записей из интерфейса пока не виден — только итоговая сумма; просмотреть, изменить или удалить конкретную запись можно только через API.
Настройка колонок — гайд по полям
Каждая строка здесь — статус, в котором может находиться задача, те же статусы становятся колонками канбан-доски на вкладке «Задачи» каждого проекта и на сквозной странице Задачи.
- Название — от 1 до 50 символов. 5 встроенных статусов (To Do, In Progress, In Review, Blocked, Done) переименовать нельзя; пользовательские — можно, на любом языке.
- Цвет — один из 6 образцов, чисто визуальный.
- Категория — TODO / In progress / Done. Это не косметика — именно она определяет процент прогресса задачи. Каждый статус не-Done получает равную долю диапазона 0–100 по порядку; перевод задачи в любой статус категории Done сразу фиксирует прогресс на 100.
- Изменить порядок (стрелки ↑/↓) — меняет и порядок колонок канбан-доски, и доли прогресса по Категории выше, поскольку они следуют этому же порядку.
- Переключатель «Активен» (только для встроенных статусов) — обратимая альтернатива удалению: выключение прячет статус везде, но сохраняет историю. Статус по умолчанию (сейчас To Do) выключить нельзя, пока не сделаешь другой статус основным. Если на статусе ещё есть задачи, при выключении сначала спросят, куда их перенести.
- Удалить (только для пользовательских статусов) — неактивна, если это последний оставшийся, и спрашивает, куда перенести задачи, если они есть.
- Название / цвет / категория нового статуса (нижняя строка) — добавляет новый пользовательский статус в конец списка; кнопка Добавить неактивна, пока не введено название.
Дашборд и Активность
Главная (в боковом меню — «Главная») — только для чтения, настраивать нечего. Баннер «Мои выплаты» разобран в Финансах.
Активность (в боковом меню — «Активность») — тоже только для чтения, со своими фильтрами над лентой: тип, действие, актор, проект, отдел, период. Действие группирует похожие события вместе (Создание, Обновление, Удаление и так далее), а не перечисляет каждый конкретный вид события отдельно.
Кадровый резерв
Провести заявку из кадрового резерва через рассмотрение — «Персонал → Кадровый резерв» → меню ⋯ у строки → Взять в работу, затем Одобрить, затем Пригласить на платформу (отправляет приглашение в штат). Свежую заявку со статусом Submitted можно сразу Одобрить, минуя Взять в работу.
Отредактировать классификацию заявки — открой заявку → меню ⋯ → Редактировать. См. гайд по полям.
Добавить заметку о рассмотрении — открой заявку → Заметки о рассмотрении → впиши. Отдельно от собственных заметок кандидата, видно только сотрудникам. См. гайд по полям.
Удалить заявку из кадрового резерва — меню ⋯ строки → Удалить. Возможно только для заявки без истории по проектам или задачам.
Кадровый резерв в личном кабинете
Посмотреть свои проекты и задачи — Мой аккаунт → Профиль в резерве (показывается только если у тебя есть привязанная запись в кадровом резерве). Делать здесь ничего не нужно — страница просто показывает то, что уже решили в другом месте, и обновляется сама, как только сотрудники прикрепят тебя к проекту или задаче.
Уведомления
О чём этот модуль сообщает людям и кому именно. Правило везде одно: вы узнаёте о событии, только если оно касается вас, и никогда — о собственных действиях. Полное объяснение в Уведомлениях.
Задачи
Назначили на задачу — исполнителю приходит уведомление в колокольчик и на почту. То же при снятии с задачи и при удалении задачи, над которой он работает (группа Мои задачи).
Добавили комментарий — всем, у кого есть отношение к задаче: исполнителям и автору, кроме того, кто написал (группа Комментарии). Несколько комментариев к одной задаче приходят одной записью со счётчиком, а не по одной на сообщение.
Изменился статус — тот же круг, но тише: без письма, пока вы его не попросите (группа Статусы моих задач). Правка описания, срока или приоритета не уведомляет никого — на активной задаче это происходит постоянно, и уведомлять о таком — верный способ сделать колокольчик не стоящим открытия.
Предложили или ответили на выплату — см. Выплаты.
Много задач изменено сразу — массовое изменение из списка задач присылает одно уведомление на человека («статус ваших задач изменён на „Готово“ — задач: 12»), а не по одному на задачу. Кого касается только одна из задач, тот получает обычное уведомление об этой задаче.
Задачу можно начинать — когда готова последняя незаконченная задача, которую она ждала, её наблюдатели получают уведомление (группа Статусы моих задач).
Обсуждение проекта
Кто-то написал в обсуждении проекта — участники проекта и его владелец, кроме автора записи (группа Комментарии). Несколько записей по одному проекту приходят одной строкой со счётчиком, как и комментарии к задаче. В уведомлении только название проекта и никогда — текст записи: колокольчик читают через плечо.
Участники проекта
Добавили в проект или убрали из него — самому человеку, в колокольчик и на почту (группа Проекты и отделы). Остальным участникам проекта не сообщается; изменение и так видно в ленте активности тем, кому это нужно.
Работает одинаково, добавлен ли участник напрямую или через свою запись в HR-пуле — запись со связанным аккаунтом это живой человек с живым колокольчиком.
Участники отдела
Добавили в отдел, убрали из него или изменили роль — самому участнику (группа Проекты и отделы). То, в каком отделе человек состоит, определяет, чего от него ждут, поэтому перевести его не сказав — верный способ сделать человека ответственным за то, чего он не видел.
HR-пул
Пришла новая заявка — всем, кто может рассматривать заявки (workspace:staffing:hr_pool:manage), пришла она с публичной формы или человек записался сам (группа Администрирование). Это единственное уведомление, чья аудитория задана правом, а не отношением к записи, — заявка, о которой никому не сообщили, ждёт, пока кто-нибудь не догадается заглянуть.
Тому, кто записался сам, о собственной заявке не сообщают, даже если у него есть это право.
Кадровый резерв в личном кабинете
Сама страница никого не уведомляет. О прикреплении к проекту или задаче сообщает колокольчик — см. Участники проекта и Задачи — эта страница просто заодно обновляется сама в тот момент, когда приходит то же самое уведомление, вместо того чтобы ждать перезагрузки.
Главная и Активность
Ни Главная, ни Активность никого не уведомляют. Обе — та половина пары, за которой идут сами: открываете страницу и видите всё, что произошло в команде. Колокольчик — вторая половина: он сам приходит к вам, но только с тем, что касается вас.
Именно это разделение и делает колокольчик стоящим открытия. Если бы он нёс ещё и каждую созданную кем-то задачу, его бы пролистывали не глядя. Когда нужна полная картина — вы идёте на Главную или Активность; когда что-то нужно лично от вас — оно само приходит через колокольчик.
Что из происходящего там дойдёт лично до вас, решают ваши настройки уведомлений.
Отделы
Сама эта страница не уведомляет никого. Добавление, удаление и смена роли происходят на вкладке Участники конкретного отдела и сообщают этому человеку — см. Участники отдела.
Проекты
Сама эта страница не уведомляет никого. Привязка и отвязка участников происходят на вкладке Участники конкретного проекта и сообщают этому человеку — см. Участники проекта.
Модель прав в одной таблице
Разделено 2026-08-14 из одного плоского platform:staffing:manage на по одному праву на домен, чтобы роль могла, например, делегировать «управление задачами» без одновременной выдачи «удаления отделов». Везде ниже сокращение `:manage` означает собственное доменное право этого раздела — departments:manage в Отделах, projects:manage в Проектах, tasks:manage в Задачах, hr_pool:manage в Кадровом резерве — а не один общий ключ:
| Право | Даёт |
|---|---|
workspace:staffing:read | Просмотр всего — базовый гейт каждой страницы списка/деталей |
workspace:staffing:departments:manage | Создание/редактирование/удаление отдела, его аватара, добавление/удаление любого участника |
workspace:staffing:members:add_own | Добавление участника только в свой собственный отдел (Department.leaderId) — единственное действие с отделом, на которое распространяется исключение для руководителя; см. Отделы → Участники |
workspace:staffing:projects:manage | Создание/редактирование/удаление проекта, его обложки, связей с отделами, этапов и назначений |
workspace:staffing:assignments:add_own | Добавление участника только в свой собственный проект (Project.ownerId) — см. Проекты → Участники |
workspace:staffing:tasks:manage | Создание/удаление задачи и назначение/снятие исполнителей любой задачи; управление любой задачей независимо от того, кто её создал |
workspace:staffing:tasks:manage_own | На задаче, которую ты создала или на которую назначена (RESPONSIBLE/HELPER), только: смена статуса/прогресса/описания/срока/приоритета и комментирование — никогда не проверяется декоратором роута, всегда разрешается в TaskAccessService.resolveTaskWriteAccess() для конкретной задачи |
workspace:staffing:hr_pool:manage | Просмотр/обновление/удаление записей кадрового резерва, приглашение для конвертации, добавление заметок |
workspace:staffing:configure | Только реестр статусов задач (цвета/порядок/активация системных статусов) — общая, разделяемая настройка, намеренно отделена от повседневного :manage |
workspace:staffing:restore | Восстановление заархивированных отделов, проектов и других мягко удалённых записей staffing |
Оба права _own устроены одинаково: само право не привязано к записи — именно проверка на уровне сервиса (Department.leaderId/Project.ownerId против актора) сужает его до «своего собственного» — реальное, отзываемое, выдаваемое через UI право, а не жёстко закодированное исключение, то же соглашение, что docs/iam/PERMISSIONS_CATALOG.md использует для tasks:manage_own. Обладание блоковым правом :manage уже покрывает всё, что делает вариант _own — _own существует для того, кто должен уметь расширять свой собственный отдел/проект, не получая при этом версию на всю платформу.
Несколько роутов намеренно не несут декоратор @RequirePlatformPermission вовсе — записи финансовой книги отдела используют вместо этого сырую проверку на уровне сервиса «является ли этот актор руководителем отдела», а изменение функции участника (заголовок + описание) — специальный DepartmentLeaderOrStaffingManageGuard, по той же причине: это право — по записи, а не то, что может выразить строка платформенного права (то же правило, что docs/iam/PERMISSIONS_CATALOG.md документирует для доступа по записи уровня организации). Этот гард ненадолго исчез 2026-08-14 вместе со всей системой DepartmentRole, которую он тоже закрывал (роуты управления ролями отдела), а на следующий день вернулся, сузившись только до этого поля, раз его решили оставить отдельно (см. Участники выше).
Отделы (/team/departments)
Простыми словами: оргструктура компании. У отдела есть руководитель, участники (у каждого — его реальная платформенная роль и необязательная функция в рамках этого отдела), привязанные проекты и — если руководитель ведёт её — собственная финансовая книга.
- Список/дерево на десктопе; карточная сетка на мобильном (без переключателя). «Новый отдел» (
:manage) открывает тот же диалог формы, что и редактирование. - Вкладки карточки: Overview (статистика, суб-отделы, активные проекты, недавняя активность), Activity, Finances (см. Финансы → Собственная книга отдела), Members, Projects, Sub-departments — каждая разобрана в своём разделе ниже.
- Меню «⋯» в шапке карточки предлагает и «Новый суб-отдел» (2026-08-14) — та же форма, что и у собственной кнопки вкладки Sub-departments, с этим отделом заранее выбранным и заблокированным как родитель (это поле остаётся редактируемым при обычном «Добавить отдел» или в режиме редактирования — блокируется только когда родитель подразумевается тем, как был открыт диалог). Скрыто у отдела, у которого уже есть родитель — вложенность ограничена одним уровнем.
- Удаление отдела (
:manage) блокируется на сервере, пока у него есть активные суб-отделы — тост с подтверждением теперь показывает именно эту причину, а не общую ошибку (исправлено 2026-08-14; раньше молча показывал общий текст независимо от реальной причины). - Архив/восстановление (
workspace:staffing:restore, 2026-08-13) — удаление отдела делает только мягкое удаление (участники, роли и привязанные проекты не трогаются и появляются как есть при восстановлении); список отделов получает вкладки Active/Archive, тот же паттерн, что и собственный сплит Active/Trash у Общих документов, но только для того, у кого реально есть это право — смотреть архив бессмысленно, если нет возможности с ним что-то сделать. Намеренно уже, чем:manage, и исключено из набора прав P4P Admin по умолчанию: отменить чужое удаление без ведома этого человека ближе к территории «кто следит за следящими», чем к повседневной работе с отделами. Восстановление уведомляет всех, у кого естьworkspace:staffing:read.
Участники (вкладка Members отдела)
Добавление (:manage, или собственный руководитель отдела через members:add_own — добавлено 2026-08-14), удаление (только :manage — здесь исключения для руководителя нет, добавление и удаление намеренно асимметричны), изменение функции участника (руководитель или :manage, через DepartmentLeaderOrStaffingManageGuard — без строки права, та же логика и тот же гард, что и до 2026-08-14, восстановленный на следующий день уже только для этого более узкого поля).
Колонка «Роль» у каждого участника — это его реальная(ые) PlatformRole — только для чтения, берётся тем же способом, что показывает Администрирование платформы → Пользователи. Убрано 2026-08-14: раньше это была DepartmentRole — каталог должностей на уровне отдела (руководитель или :manage мог создавать/редактировать/назначать её, например «Рекрутёр»), не дававший никаких реальных прав — неотличимая от настоящей роли в интерфейсе, при этом структурно ничего не делающая, что оказалось скорее вводящим в заблуждение, чем просто декоративным.
Колонка «Функции» у каждого участника — другое дело, пережившее это удаление: оставлена намеренно, по прямой просьбе пользователя, поскольку персональное описание «чем человек реально занимается здесь» — законная потребность, отдельная от метки-роли, и сама по себе никогда не была проблемой. Она переехала с DepartmentRole (общей для всех, у кого была эта роль) непосредственно на DepartmentMember (один человек, один отдел, одна запись), доступна через PATCH .../members/:userId, тот же роут/гард, что раньше делил с назначением DepartmentRole, теперь сузившийся только до этого поля. Изначально (2026-08-15) — одно свободнотекстовое поле (duties); в тот же день разбито на DepartmentMember.functionTitle (короткий заголовок, показывается в колонке и в усечённом виде на собственной карточке сотрудника) и DepartmentMember.functionDescription (более длинное описание, показывается при разворачивании строки здесь и во всплывающей подсказке на карточке сотрудника) — по образцу формы старой DepartmentRole (название + duties), но ни одно из полей не даёт никаких прав.
Проекты (вкладка Projects отдела)
Проекты, где есть люди этого отдела. «Привязать проект» массово добавляет текущих участников отдела на выбранный проект (:manage) — тот же разовый снимок, что и со стороны проекта (см. Проекты → Участники); «отвязать» убирает их всех.
По каждому проекту таблица показывает: статус, сколько людей от этого отдела задействовано, его собственную разбивку Задач (в плане / в работе / готово) и Бюджет (сумма цен задач этого отдела, по валютам — только с правом workspace:finance:read), привязанные отделы, сроки, прогресс. Этот срез по проекту переехал сюда 2026-08-30, когда убрали вкладку «Отделы» у проекта. Полные финансы отдела по-прежнему на вкладке Finances.
Суб-отделы (вкладка Sub-departments отдела)
Глубина ограничена одним уровнем — у суб-отдела не может быть своих суб-отделов. Поэтому же удаление отдела с активными суб-отделами заблокировано (см. выше) — сначала их нужно осознанно повысить или переназначить, а не потерять молча при удалении.
Оргструктура (/team/org-chart)
Проще говоря: отделы в виде дерева — компания вверху, под ней отделы, под ними подотделы.
- Видят все, у кого есть
workspace:staffing:read. Только просмотр — структуру меняют в формах отделов. - В карточке — отдел, его руководитель и число людей. Люди показывает участников с должностями; вторая кнопка сворачивает подотделы. Раскрыть всё / Свернуть всё делают это для всех карточек.
- Без отдела — активные сотрудники, которые не входят ни в один отдел.
- Имя человека открывает его карточку сотрудника.
- Архивные отделы и ушедшие сотрудники не показываются. На телефоне схема — список с отступами.
Сотрудники (/team/members)
Простыми словами: профиль каждого сотрудника P4P — но добавление здесь не действие staffing, а тот же самый процесс приглашения в штат платформы из Администрирования платформы, просто продублированный сюда для удобства.
Поиск, фильтры, сортировка и страницы списка работают на сервере; фильтр «Отдел» показывает отделы, где кто-то остаётся при текущем поиске и статусе, с числом людей.
- Список: поиск + фильтры по отделу/статусу. «Добавить сотрудника» закрыто правом
platform:users:invite(то же право — и тот же диалог массового приглашения, теперь по email-строке — что и у/platform/staff; делегировано 2026-08-13, см. Администрирование платформы → Приглашения в штат, до этого было жёстко закодированоSUPER_ADMIN/P4P Owner). - Вкладки карточки: Overview (контакты, навыки/интересы), Departments (все отделы, в которых состоит человек, с его Функцией в каждом — добавлено 2026-08-15, вынесено из собственной карточки «Отделы» на Overview, когда у Функции появилось реальное описание, которое стоило показывать полностью), Activity (что этот человек сделал, а не что сделали с ним), Candidate application (показывается только если человек пришёл через кадровый резерв — снимок его исходной заявки только для чтения), Projects, Tasks.
- Действия меню «⋯» «Отправить в отпуск»/«Вернуть из отпуска» и «Убрать из штата» вызывают роуты модуля IAM/Users (
POST /admin/users/:id/leave,DELETE /admin/users/:id/platform-staff), а не staffing — эта страница просто удобная точка входа в действия, которые живут в Администрирование платформы → Пользователи. - Детали вкладки Overview (2026-08-15, закрывает три пробела, обнаруженных пользователем): если у роли задано
PlatformRole.description, название рендерится с пунктирным подчёркиванием и показывает это описание во всплывающей подсказке при наведении — везде, где показывается название роли (эта страница, ростер, вкладка Members отдела). Навыки/специализация — самостоятельно заполняемое поле (User.skills/interestAreas) без права переопределения админом — при просмотре чужой карточки показывается обычная подсказка, что поле заполняется самостоятельно; на своей карточке появляется иконка карандаша при наведении (та же договорённость, что и у редактирования/удаления комментария к задаче:Cardполучаетclass="group"+opacity-0 group-hover:opacity-100), ведущая на/account/profile— и для этой карточки, и для карточки «Личные данные» рядом с ней; админ, просматривающий чужую карточку, эту иконку никогда не видит. - Вкладка Departments: каждая запись показывает заголовок функции человека сразу под названием отдела, а описание — в отличие от собственной вкладки Members отдела (заголовок в колонке, описание только при разворачивании строки) или прежней компактной карточки на Overview (описание только во всплывающей подсказке) — рендерится прямо под ним, без всякого взаимодействия: у отдельной вкладки достаточно места, компромисс, который оправдывал скрытие описания в других местах, здесь не нужен. См. Участники выше о том, что такое функция. То же исключение «своя строка — логин ведёт в свой аккаунт», что и на ростере (
PersonLink.vue), добавлено в тот же день и для заголовка этой страницы: логин под именем обычно ведёт на/platform/users/:id, но на/account/profile— и всегда, независимо отplatform:users:read— когда это твоя собственная карточка. - Вкладка «Проекты»: колонка Что делает (в сетке и в списке) — это заметка человека как участника проекта. С правом
workspace:staffing:projects:manageв каждой строке есть Указать функцию / Изменить функцию — тот же add/edit-элемент, что и у вкладки «Отделы» для функции по отделу (2026-09-02); он пишет ту жеProjectAssignment.note, что редактирует вкладка Участники самого проекта. Проект, с которым человек связан только через задачи (нет строки участника), показывает просто «—» и никакого элемента — привязать заметку не к чему.
Проекты (/team/projects)
Простыми словами: внутреннее управление проектами — отделы и люди, привязанные к проекту, дорожная карта этапов и доска задач, плюс (если видны финансы платформы) доля этого проекта в книге владельца.
Поиск, фильтры и страницы списка проектов работают на сервере, новые сверху; фильтр «Отдел» показывает отделы, участвующие в проектах при текущем поиске и статусе, с числом проектов.
- Список: переключатель grid/list, фильтры по статусу/отделу. «Новый проект» (
:manage). - Вкладки карточки: Overview (статистика прогресса, прогресс по этапам, недавние задачи, участвующие отделы, редактируемое инлайн rich-text поле «Vision»), Participants, Stages, Tasks, Discussion (ветка проекта плюс журнал событий) и Finances (см. Финансы → Вкладка «Финансы» проекта) — каждая разобрана в своём разделе ниже.
- Отдел задачи должен быть одним из тех, чьи люди есть на проекте — проверяется на сервере (см. Участники).
Участники (вкладка Participants проекта)
ProjectDepartment (живая связь отдел↔проект) убрана 2026-08-30 (docs/staffing/ADR-001-staffing-pm-tool.md, Decision 1). Участники проекта — это только явные строки ProjectAssignment; отдел показывается группой, если ≥1 его член назначен. Отдельной вкладки «Отделы» больше нет — всё здесь.
- Сверху переключатель: Штат (
STAFF-строки) / Кадровый резерв (HR_POOL). - «Штат» можно смотреть по отделам (дерево — одна таблица, строка-папка на отдел + группа «Без отдела», сворачивается) или списком. У каждой строки — свободная заметка Что делает. Колонка «Аккаунт» (только в пуле / есть логин / бывший штат) есть только в «Кадровом резерве» — в «Штате» она всегда одинаковая.
- Прикрепить отдел (
POST .../projects/:id/departments/:deptId,:manage) — разовое массовое добавление текущих членов отдела; каждому — уведомление «вас добавили». Живой связи нет. - Отвязать отдел (
DELETE ...) — убирает всех текущих членов этого отдела с проекта одним запросом. - Добавить / убрать одного —
POST/DELETE .../assignments(:manage, или владелец проекта черезassignments:add_ownдля добавления). Массовое удаление — отметить строки и удалить каждое назначение.
Обсуждение (вкладка Discussion проекта)
Собственная ветка проекта — ProjectComment, та же форма, что у TaskComment задачи, только уровнем выше (docs/staffing/ADR-001-staffing-pm-tool.md, Decision 23). Две части одной вкладки: Обсуждение (что писали люди) и История (журнал TeamEvent по этому проекту).
- Чтение —
workspace:staffing:read, как и всё остальное на карточке. - Запись —
workspace:staffing:projects:manageили личное отношение к этому проекту: участие в нём либо владение им. Без этого вместо поля ввода стоит строка о том, кто может писать, — поле никогда не исчезает молча. - Правка и удаление — только автором, проверяется на сервере. Ни менеджер проекта, ни администратор не могут переписать чужую запись.
- Записи — обычный rich text (жирный, списки, ссылки). Вложений пока нет: у задачи они есть, потому что задача владеет областью загрузки, у проекта такой области пока нет.
- Каждая запись, правка и удаление попадают в аудит и ленту активности (
project.comment_created/_updated/_deleted); от удалённой записи в истории остаётся однострочная выжимка — payloadTeamEventденормализован намеренно.
Этапы (вкладка Stages проекта)
Упорядоченная дорожная карта, перестановка через ↑/↓ (:manage). Каждой задаче можно назначить этап; прогресс по этапам на вкладке Overview считается от этого. Создание, редактирование или удаление этапа уведомляет всех участников проекта (2026-08-13, project_stage.created/updated/deleted — группа «Активность проекта»).
Задачи (вкладка Tasks проекта)
Список или канбан-доска, 5 режимов группировки — только в рамках этого проекта. Сквозной аналог по всем проектам сразу — раздел Задачи ниже.
Задачи (/team/tasks)
Простыми словами: сквозная доска задач — все задачи по всем проектам в одном месте, в отличие от вкладки Tasks внутри конкретного проекта.
В режиме таблицы поиск, фильтры, сортировка и страницы работают на сервере; плитки считают то, что оставляют фильтры, а в списках фильтров видно, сколько задач у каждого варианта. Доска тоже приходит с сервера: у каждой колонки видно настоящее число задач и первые 20 карточек, остальные — кнопкой Показать ещё.
- Переключатель список/канбан, 5 режимов группировки канбана (статус/ответственный/приоритет/проект/этап). Drag-and-drop закрыт
:manage(перетаскивание карточки между колонками «ответственный» вызывает тот же роут добавления исполнителя, что и форма задачи). - Старые выполненные задачи по умолчанию скрыты — задачи, выполненные больше 14 дней назад, не загружаются ни в список, ни в канбан (как «скрывать выполненные задачи старше N дней» в Jira). Строка под плитками статистики об этом говорит, а кнопки Показать все / Скрыть старше 14 дней переключают режим (выбор запоминается на неделю). «Выполнена» — это момент, когда задача последний раз перешла в статус категории Done (
Task.completedAt); правка старой выполненной задачи не возвращает её на доску. Подзадача следует за родительской, поэтому счётчик «2 из 5» на карточке остаётся верным. Плитки статистики считают только загруженное. - Метки — поле Метки в карточке «Детали» задачи. Выберите существующие или введите новое название и нажмите Создать (может любой, кто вправе менять задачу). Метки видны на карточках доски и в таблицах, среди фильтров доски есть Метки. Переименовать, перекрасить и удалить метку (это меняет все задачи с ней) можно в ⋯ → Метки на доске — с правом
workspace:staffing:configure. - Таймер — в задаче, где вы исполнитель, кнопка ▶ рядом с Потрачено запускает таймер. Он виден в шапке на всех страницах (на телефоне — значком таймера) и не теряется при перезагрузке или на другом устройстве. ■ останавливает его и записывает время обычной записью на день старта; меньше минуты не записывается. Один таймер на человека: запуск другого останавливает и записывает текущий. Если таймер шёл больше 12 часов, появится окно, чтобы подтвердить или исправить часы. В меню таймера в шапке его можно отменить без записи.
- Экспорт в CSV — ⋯ → Экспорт в CSV сохраняет задачи, которые сейчас видны на доске (с фильтрами и поиском), в файл для таблиц. Цен и выплат в нём нет никогда. У отчёта по времени своя кнопка Экспорт в CSV: все записи времени за даты и проект отчёта — дата, человек, задача, минуты, часы, комментарий — для табеля или счёта.
- Сохранённые фильтры — вверху меню фильтров доски. Выберите фильтры, введите название и нажмите Сохранить; позже нажмите на сохранённый фильтр, чтобы применить его снова. Они только ваши и доступны на любом устройстве. Сохранение под уже занятым именем заменяет тот фильтр.
- @упоминания — наберите
@в комментарии, описании задачи или сообщении в обсуждении проекта и выберите человека из списка (поиск по имени или email). Он получит уведомление — только в первый раз, когда текст его упоминает, правка не уведомит повторно — и начнёт наблюдать за задачей. В списке только те, у кого есть доступ к управлению командой. - Наблюдение — кнопка Наблюдать / Вы наблюдаете в шапке задачи решает, получаете ли вы уведомления о её комментариях и изменениях. Наблюдение включается само, когда вы создаёте задачу, становитесь исполнителем или пишете комментарий. Если вы перестали наблюдать, это сохраняется: новый комментарий или назначение не подпишут вас снова — только кнопка Наблюдать. Уведомления «вас назначили / сняли» приходят в любом случае.
- Обновления в реальном времени — изменение, сделанное другим человеком, перечитывает только затронутую задачу, а не всю доску; полная перезагрузка бывает только после переподключения или при очень большой пачке изменений.
- Настройка статусов задач — отдельной страницы нет, но есть настоящий диалог настроек (иконка шестерёнки, только
workspace:staffing:configure), покрывающий весь реестр статусов: создание/редактирование/переупорядочивание/удаление. 5 посеянных системных статусов нельзя удалить окончательно, только деактивировать. - Карточка задачи — каждое поле редактируется инлайн, в стиле Jira. Название/этап/отдел/ответственный/помощники/цена требуют
:manage; статус/описание/приоритет/срок/прогресс открыты для:manageили:manage_ownна своей задаче (создатель, или назначена как RESPONSIBLE/HELPER — включая через связанную запись кадрового резерва, не только через прямое назначение сотруднику). Статус и прогресс с тем же разделением:manage/:manage_ownправятся и прямо из списка задач (выпадающий список + ползунок в колонках), не только на карточке; собственный drag-and-drop канбан-доски (смена статуса перетаскиванием карточки) — отдельный путь, всё ещё только:manage(перетаскивание дёргает тот же route, что и этот select, но сама доска остаётся жёстче огорожена). Написание нового комментария следует тому же разделению:manage/:manage_own(композер скрыт, вместо него — заметка о том, кто может писать); правка или удаление уже написанного своего комментария завязаны на клиенте исключительно на авторство, без отдельной проверки:manage/canWriteOwn(реальное применение — на сервере,TaskAccessService.resolveTaskWriteAccess, как и везде на этой странице). Удаление задачи — только:manage; и меню ⋯ строки (Редактировать / Удалить) — тоже только:manage, и на вкладке «Задачи» проекта, и в этом сквозном списке; пользователь с:manage_ownредактирует со страницы задачи. У сквозного списка не загружен контекст проекта, поэтому Редактировать там на лету подгружает этапы и отделы проекта задачи и открывает тот жеTaskFormDialog, что и вкладка проекта. - Исправлено, 2026-08-04: прикрепление файла к комментарию или описанию раньше требовало блокового
:manageбез какого-либо исключения:manage_ownвообще — пользователь с:manage_ownмог написать и отправить комментарий, но кнопка прикрепления всегда отвечала 403, хотя в UI выглядела доступной. Эндпоинт загрузки (POST /admin/staffing/attachments) общий (используется также для Project Vision) и по умолчанию не знает, к какой сущности относится файл; фикс протягивает необязательныйtaskIdчерез вызов загрузки, чтобы сервер мог применить ту же проверкуmanage_own+ создатель/назначенный, что уже использует остальная часть задачи, вместо требования блокового:manageвсегда, когда задача на самом деле идентифицируема.
Отсутствия (/team/time-off)
Персонал → Отсутствия. Нажмите Запросить отсутствие, выберите вид (отпуск, больничный, другое), первый и последний день и, если хотите, комментарий. Окно покажет, сколько это рабочих дней.
- Больничный засчитывается сразу — без одобрения; руководитель отдела и менеджеры получат уведомление.
- Отпуск и «другое» ждут решения руководителя любого вашего отдела или человека с правом
workspace:staffing:time_off:manage(Team Manager, Team Admin). Свою заявку одобрить нельзя. О решении придёт уведомление; причина отказа видна в заявке. - Отменить можно ожидающую заявку или одобренную, которая ещё не началась (те, кто одобряет, получат уведомление).
- На одобрение (только для тех, кто решает) — ожидающие заявки и кто ещё отсутствует в эти дни.
- Кто отсутствует — одобренные отсутствия всех, начиная с сегодня, только даты. Вид и комментарий видят только сам человек и те, кто решает.
- Одобренные дни вычитаются из нормы человека на странице загрузки, видны в командном календаре как «отсутствует» и считаются занятыми при назначении встречи.
Загрузка (/team/reports/workload)
Работа → Загрузка показывает, кто перегружен, а у кого есть время. Строки — люди, колонки — эта неделя и пять следующих, плюс Без срока. В ячейке — «запланированные часы / норма»:
- Норма — недельная норма человека (задаётся в настройках норм отчёта по времени). Для этой недели считаются только оставшиеся рабочие дни, начиная с сегодня. В дни отпуска сотрудника и одобренных отсутствий нормы нет — если в неделе её не осталось, в ячейке написано В отпуске.
- Запланированные часы — остаток каждой открытой задачи (оценка минус уже потраченное время), поровну между исполнителями и равномерно по рабочим дням до срока. Просроченная работа идёт в эту неделю.
- Задача без оценки не добавляет часов — она показана числом под часами («+2 без оценки»). Ставьте задачам оценку, чтобы картина была точной.
- Зелёный — меньше 80% нормы, жёлтый — 80–100%, красный — больше нормы. Нажмите на ячейку, чтобы увидеть её задачи и открыть любую.
Фильтр оставляет один отдел. Доступно с правом workspace:staffing:reports:read (те же люди, что видят отчёт по времени).
Кадровый резерв (/team/hr-pool)
Простыми словами: воронка для людей, которые хотят работать с P4P, но не являются сотрудниками (пока или вообще) — публичная форма заявки наполняет очередь на рассмотрение; одобрение позволяет пригласить человека на проект как подрядчика, необязательно делая его сотрудником платформы.
- Публичная заявка (
/hr-pool/apply, без входа, вообще без гейтаworkspace:staffing:*— Turnstile + рейт-лимит) — лендинг в маркетинговом стиле с формой (имя/email/телефон/мессенджер/тип/области интересов/навыки, поле Дополнительная информация с форматированием и необязательное резюме — один файл PDF / DOC / DOCX / TXT, до 5 МБ). СоздаётHRPoolEntryбез привязанногоUser. - Очередь на рассмотрение (
/team/hr-pool, только для сотрудников) — плитки статистики по статусам, фильтруемая таблица. «⋯» по строке: переход по статусам рассмотрения,:manage— не строгий линейный конвейер: «Взять на рассмотрение» доступно только изSUBMITTED, а «Одобрить» — изSUBMITTEDилиUNDER_REVIEW(свежую заявку можно одобрить сразу, минуя рассмотрение целиком — см. инструкцию выше), а «Деактивировать» — из любого статуса, кроме ужеINACTIVE. «Пригласить» (только когдаAPPROVEDи ещё не привязана к пользователю,:manage— отправляет приглашение в штат платформы), удаление (только если у записи нет истории назначений). Поиск, фильтры, сортировка и страницы работают на сервере, поэтому большой резерв не тормозит; плитки статусов считают то, что оставляют поиск и другие фильтры. Направления и навыки не сортируются, а тип и источник сортируются по внутреннему коду. - Карточка записи — те же действия, плюс Редактировать (тип заявителя, области интересов, навыки — поля классификации,
:manage) и внутренний журнал заметок рассмотрения (:manageдля добавления заметки; отдельно от собственных заметок заявителя). - Подтверждённый пробел (2026-08-04), частично закрыт (2026-08-16): два готовых на бэкенде пути были недостижимы из интерфейса —
Публичные роуты принятия— исправлено:HrPoolInvitationsControllerне имели соответствующей страницы/hr-pool-invitations/:tokenтеперь существует, зеркалируя/platform-staff-invitations/:token. У приглашения, отправленного из очереди кадрового резерва (или через кнопку Пригласить на платформу на карточке записи — в тот же день вынесенную из меню «⋯» отдельной видимой кнопкой), теперь есть реальное место для перехода.- Самостоятельный опт-ин «указать меня как доступный ресурс» (
POST hr-pool/opt-in, открыт любому вошедшему пользователю платформы, не только сотрудникам) по-прежнему не имеет триггера в интерфейсе нигде в портале — сегодня существуют только публичная форма заявки и внутренняя очередь на рассмотрение.
Отредактировать заявку / добавить заметку о рассмотрении — гайд по полям
Диалог Редактировать охватывает только то, как классифицирован этот заявитель — его имя, email, телефон и предпочитаемый мессенджер были заданы один раз самим заявителем и здесь вообще не меняются (в форме их нет). В отличие от большинства других диалогов редактирования в этом модуле, Сохранить активна не только после изменения — она включается сразу, как только заполнены Тип заявителя и хотя бы одна Область интересов, так что клик по ней без реальных изменений просто пересохранит те же значения.
- Тип заявителя (обязательно) — Individual / Agency / Company / Service provider.
- Области интересов (обязательно, множественный выбор) — Consulting / Marketing / Development / Design / QA / AI / Events / Other. Нужна хотя бы одна; выбор Other открывает поле свободного текста под ней, но — несмотря на то, что оно стоит прямо под обязательным полем, — само остаётся необязательным, до 200 символов.
- Навыки (необязательно) — свободный текст, до 500 символов.
- Заметки о рассмотрении (отдельная панель под собственной информацией заявки, не часть диалога «Редактировать») — растущий журнал, а не одно поле: каждая заметка — простое текстовое поле от 1 до 4000 символов, отправляется собственной кнопкой Отправить (неактивна, пока пусто) и навсегда добавляется вместе с твоим именем и временем — заметки нельзя редактировать или удалить после отправки. Видны только сотрудникам с доступом к этой странице, никогда заявителю.
Твой профиль в кадровом резерве (/account/hr-pool)
Простыми словами: единственное место, где подрядчик — человек с привязанной записью в кадровом резерве, но без платформенной роли сотрудника — вообще может увидеть что-то о своём участии. Весь /team для него закрыт полностью, потому что каждая страница там требует workspace:staffing:read, которого у него по определению нет.
- Никакого гейта
workspace:staffing:*вообще — достаточно просто быть вошедшим и иметь привязанную запись (GET /hr-pool/meи соседние ручки проверяют только личность, ничего больше). Открывается через плитку на странице рабочих пространств и пункт в боковом меню личного кабинета — оба показываются только когдаGET /meсообщает про привязанную запись (hrPoolEntryId), и снова скрываются, как только человек становится платформенным сотрудником: тогда всё то же самое уже показывает настоящая/team/hr-pool/:id. - Твоя запись — статус, области интересов, навыки. Только для чтения, формы редактирования здесь пока нет.
- Проекты — все проекты, к которым ты прикреплён, с ролью на каждом.
- Задачи — все задачи, назначенные тебе, со статусом и сроком.
- Живое обновление (2026-08-16): прикрепление к проекту или задаче появляется здесь без перезагрузки — страница подписана на твой личный канал (
userRoom, доступ по одной лишь личности, тот же самый, что использует колокольчик), и обновляется по тому же сигналуnotification.created, что зажигает и колокольчик. См. Участники проекта.
Дашборд и активность
/team/dashboard — реальные данные повсюду: приветствие, баннер «Мои выплаты» (показывается только когда есть ожидающие ответа предложения выплат — см. Finance для полного описания процесса выплат), до восьми единообразных карточек разделов — Tasks/Projects/Team/ Departments/HR Pool/Calendar/Finance/Shared Documents, каждая показывается только при наличии своего права (первые пять требуют workspace:staffing:read; Calendar — workspace:calendar:read; Finance — workspace:finance:read, более узкое право, как и её пункт бокового меню; Shared Documents — files:read, см. IAM — это тоже не настоящее право Персонал) — недавняя активность и ссылки быстрых действий (каждая тоже с собственным гейтом; «Новый сотрудник» дополнительно требует быть супер-админом или владельцем организации). Отдельной карточки Activity нет — панель «Недавняя активность» под карточками разделов уже показывает ту же ленту, отдельная карточка с тем же счётчиком не сказала бы ничего нового.
/team/activity — неотфильтрованная сквозная лента (все виды событий по задачам/проектам/отделам/записям кадрового резерва/сотрудникам/событиям календаря), с фильтрами по типу/действию/актору/проекту/отделу/периоду. Обновляется в реальном времени.
Раньше здесь был собственный раздел про общие документы — перенесён в IAM → Общие документы (2026-08-20): под капотом это никогда не было функцией Персонал, просто маршрут жил в URL-пространстве Team Management, поэтому она теперь описана вместе с остальной частью возможности файлового хранилища. Сама страница ненадолго переехала на /org/p4p-internal/shared-documents в тот же период, а затем вернулась на /team/shared-documents (2026-08-23), когда выяснилось, что это стоит дороже в повседневном поиске фичи, чем архитектурная чистота маршрута — полное обоснование см. в разделе IAM. Доступ по-прежнему в один клик — из сайдбара этого модуля (layouts/team.vue, закрыт files:read, а не workspace:staffing:read) и с карточки раздела и quick action на /team/dashboard выше.
Тестирование этого модуля
scripts/e2e/menu/staffing.mjs (68 проверок, можно перезапускать в любой момент — полный список см. в scripts/e2e/README.md) прогоняет основные сценарии этого модуля от начала до конца: дашборд (карточки разделов и быстрые действия для супер-админа с полным доступом — случай с урезанными правами остаётся известным пробелом, требует кастомной platform-роли), всю семью отделов (создание/редактирование/удаление, собственные вкладки «Роли» и «Суб-отделы» отдела, его вкладку «Активность», прикрепление/ открепление проекта в обоих направлениях), всю семью проектов (создание/ редактирование/удаление, его вкладку «Отделы», вид «По отделам» на вкладке «Участники», создание/переупорядочивание/удаление этапов, List-вид вкладки «Задачи» и поле Vision на вкладке Overview), сквозной сценарий создания задачи плюс собственный List-вид сквозной страницы «Задачи» (поиск, фильтр по проекту, сброс фильтров), собственные inline-редактируемые поля страницы задачи (Название, Приоритет — по одному полю от каждого из уровней прав :manage/canWriteOwn), её карточку «Подзадачи» (добавление настоящей подзадачи — впервые вживую проверяет parentTaskId — смена её статуса инлайн, удаление), её Комментарии (отправка, правка, удаление — настоящий комментарий через тот же rich-text композер, что используется и в других местах страницы; пересекается с более глубоким отдельным task-comment-edit-delete.mjs — см. scripts/e2e/README.md про эту принятую, задокументированную избыточность), и её вкладку «История» (переключение на неё и подтверждение, что реальные события уже отображаются — от правок Названия/Приоритета чуть выше), и кадровый резерв (заявка создаётся напрямую в БД — сама публичная форма заявки закрыта Turnstile, не автоматизируется, см. примечание ниже — проводится через статусы проверки: взять на рассмотрение, одобрить, добавить заметку рассмотрения на собственной странице записи, пригласить в штат, удалить). Собственная логика публичной формы заявки (всё, кроме виджета Turnstile и реальной отправки) покрыта юнит-тестами, apps/portal/pages/hr-pool/apply.test.ts (6 тестов, 2026-08-12): honeypot молча притворяется успехом, ни разу не вызывая API; полный payload отправки (interestAreaOther включается только когда OTHER среди выбранных областей интереса; phone/preferredMessenger отправляются как undefined, а не '', если оставлены пустыми — чтобы бэкенд не сохранял пустую строку); ответ с рейт-лимитом показывает сообщение о cooldown и запускает общий таймер повторной отправки; общая ошибка API показывает собственное сообщение сервера. NuxtTurnstile — локальная заглушка со шпионом reset(), подтверждающая, что собственный вызов handleFormSubmit'а turnstileRef.value?.reset() срабатывает после каждой попытки отправки (успешной или нет — токен Turnstile одноразовый). А также Сотрудники (/team/members, раньше вообще не имевшая живого покрытия — раунд 1 покрыл список/оболочку/Overview: поиск в ростере находит реального сотрудника, карточка сотрудника загружается с реальными данными; раунд 2 добавил вкладку «Задачи», показывающую реальную задачу, назначенную этому сотруднику ранее в том же прогоне; раунд 3 добавил «Расписание» и «Активность», обе загружаются без ошибок; раунд 4 закрывает юнит-покрытие вкладки «Заявка кандидата», без новой живой проверки — см. примечание ниже, почему). Вкладки «Проекты» и «Заявка кандидата», а также «Отправить в отпуск» и «Открепить от штата» остаются без живого покрытия, см. то же примечание. Board-вид и drag-and-drop на странице «Задачи» покрыты отдельно, вживую, скриптом realtime-board-and-task.mjs — здесь не дублируются. Это закрывает живое покрытие всех 4 блоков разбиения раунда для страницы задачи — пагинация feed'а (раскрытие более старых элементов) и дедупликация/переход-к-источнику панели «Вложения» остаются покрыты только юнит-тестами (чтобы вызвать их вживую, нужно 15+ комментариев — слишком медленно для этого сьюта).
/team/activity (глобальная, нефильтрованная сквозная лента — каждое событие /team без предустановленного скоуп-фильтра, в отличие от любой другой поверхности активности этого модуля) имеет две отдельные ветки живого покрытия, проверенные в первую очередь до добавления чего-либо нового: механизм живого обновления «N новых» на этой самой странице уже основательно подтверждён realtime-new-items-pill.mjs (обе половины правила — строки беззвучно вливаются наверху, задерживаются и предлагаются как счётчик после прокрутки в историю) и realtime-two-sessions.mjs; новый файл, scripts/e2e/menu/activity.mjs (7 проверок, 2026-08-12), покрывает то, чего не касается ни один из них — собственные фильтры и поиск страницы: лента загружается с реальными событиями, бессмысленный поисковый запрос опустошает её до состояния «ничего не найдено», а очистка восстанавливает ленту; список опций фильтра по типу отображает реальные значения; выбор/сброс фильтра включает/отключает кнопку «Сбросить фильтры» панели (единственный видимый сигнал того, что фильтр активен, поскольку сам триггер — иконка без видимой подписи). Сопутствующее юнит-покрытие, apps/portal/pages/team/activity.test.ts (10 тестов) — поиск по всем 5 полям, по которым может совпасть лента (исполнитель/предмет/имя/проект/отдел), фильтры по типу/действию/ исполнителю/проекту/отделу/периоду, каждый корректно сужающий список, activeFilterCount, намеренно исключающий поиск, и — первая страница этого модуля, реально задействующая это — собственная пагинация loadMore на основе курсора у useTeamActivity() (hasMore отключается, когда приходит короткая страница), которую тесты любой ДРУГОЙ поверхности активности вообще не затрагивают, поскольку ни одна из них не отображает состояние «загрузить ещё».
Общие документы (единое общее файловое пространство «P4P Internal», на /team/shared-documents — см. IAM → Общие документы) не имели покрытия вообще, ни юнит, ни живого, до этого раунда. Новый файл, scripts/e2e/menu/shared-documents.mjs (8 проверок, 2026-08-12), — первый скрипт во всём этом сьюте, который вживую прогоняет реальную загрузку файла — скрытый <input type="file"> за drag-and-drop зоной FileUpload принимает page.setInputFiles напрямую, в обход собственного UI drag-and-drop/click-to-open (это забота самого компонента, уже покрытая его собственными ui-kit-тестами). Один непрерывный жизненный цикл, переиспользующий один и тот же загруженный файл, а не создающий три: загрузка реального .txt-файла (подтверждено реальным 201), нахождение через поиск, мягкое удаление, подтверждение попадания в Корзину, восстановление, подтверждение возврата в активный список, затем повторное мягкое удаление и окончательная очистка — полностью самоочищающийся. Один реальный нюанс, найденный при написании проверок «исчез»: тост удаления гласит «{name}» удалён, что буквально содержит само имя файла, так что поиск текста по всей странице не может отличить «всё ещё в таблице» от «упомянут в тосте, который ещё не исчез» — каждая проверка присутствия/отсутствия привязана к реальной строке таблицы (page.locator('tr', { hasText: fileName })) вместо этого. Сопутствующее юнит-покрытие, apps/portal/pages/org/[slug]/shared-documents.test.ts — блок A (список, поиск, переключатель активные/корзина, гейтинг canManage, скачивание, мягкое удаление, восстановление, окончательное удаление; 11 тестов) и блок B (сам поток загрузки, тот же раунд, ещё 12 тестов — 23 всего): выбор изображения сразу даёт blob-превью, а непревьюируемый файл — нет (превью PDF/видео — это реальная работа браузера — динамически импортируемое декодирование pdf.js и захват кадра через offscreen <video> canvas — намеренно не проверяется здесь, то же решение «не стоит мокировать реальный pipeline декодирования», что и в других местах этой инициативы), удаление выбранного файла отзывает его blob URL, реальное создание XMLHttpRequest в confirmUpload с правильными заголовками Authorization/X-Organization-Id и реальное событие upload.onprogress, обновляющее процент элемента, 201 очищает элемент и перезагружает список, статус ошибки, отличный от 401, показывает собственное сообщение сервера (с откатом к общему для не-JSON тела), сетевой сбой xhr.onerror, 401 обновляет токен через глобальный Nuxt $fetch — не через мок api-клиента, поскольку обновление происходит ДО того, как есть валидный токен для прикрепления — и повторяет попытку с новым, неудачное обновление оставляет элемент со статусом ошибки, а не бесконечными повторами, onRetry повторно отправляет тот же ожидающий файл, и onRemove делает последующий onRetry для этого id no-op-ом. Первая страница этой инициативы, которой вообще понадобилось мокирование XMLHttpRequest/$fetch — локальный фейк MockXHR плюс застабленный $fetch, ни один пока не промотирован в общий test setup (единственное использование пока что). Живая проверка загрузки выше уже доказывает счастливый путь от начала до конца; покрытие блока B намеренно охватывает КРАЙНИЕ случаи, которые нет чистого способа воспроизвести вживую (реальный 401, сетевой сбой посреди загрузки) — то же разделение «живое доказывает счастливый путь, юнит доказывает края», которое эта инициатива уже использует в других местах (например, calendar.mjs пропускает живой drag-move в пользу юнит-протестированного отката в onMoveEvent).
У каждой вкладки под /team/departments/[id]/* и /team/projects/[id]/* есть и свой юнит-тест-файл (apps/portal/pages/team/{departments,projects}/**/*.test.ts), детально покрывающий права доступа, логику фильтров/дедупликации и предупреждения о рассогласовании. apps/portal/pages/team/dashboard.test.ts (28 юнит-тестов) делает то же самое для дашборда: видимость каждой карточки и каждого быстрого действия по правам, подсчёт в карточке Calendar по occurrences, а не по собственному startsAt события (первому вхождению повторяющейся серии, а не текущей неделе), и сверку несовпадений в карточке Finance. apps/portal/pages/team/tasks/index.test.ts (14 юнит-тестов) так же покрывает List-вид сквозной страницы «Задачи»: каскадные списки опций фильтров (фильтр по проекту сужает списки отдела/этапа/ответственного до этого проекта), два watcher'а, сбрасывающих устаревший нижестоящий фильтр, фильтры по сроку и приоритету, одноразовый переход по ?project= со вкладки «Задачи» конкретного проекта (который, в отличие от собственного ?stage= этой вкладки, ещё и переключает вид на канбан), производные счётчики в карточках статистики и сборку подзадач для канбан-карточки. Редирект-страница activity.vue покрыта в том же файле. apps/portal/pages/team/tasks/[id].test.ts (38 юнит-тестов) покрывает всё 4-блочное разбиение страницы задачи целиком: тело PATCH каждого inline-поля (обе стороны обнуления Этапа/Отдела/Цены, нюанс явного null вместо холостого undefined у Срока, POST/DELETE вызовы для Ответственного/Помощников), полную матрицу прав :manage-vs-canWriteOwn — Статус выглядит так, будто должен быть только :manage (сгруппирован с Этапом/Отделом/Ответственным/Помощниками/Ценой везде в этом документе), но на самом деле это canWriteOwn, тот же уровень, что у Описания/Приоритета/ Срока/Прогресса; только собственный drag-and-drop канбан-доски со сменой статуса остаётся только :manage — дебаунс слайдера прогресса, удаление задачи, правила видимости карточки «Подзадачи», асимметрию между canWriteOwn-select статуса самой задачи и более строгим :manage-only select строки подзадачи, Комментарии (гейт canComment на композере, неудачная отправка сохраняет черновик для повтора через собственный контракт useChatSubmit, а правка/удаление комментария завязаны исключительно на авторство — isMyComment — независимо от :manage/canWriteOwn вообще, проверено во всех трёх комбинациях прав), и Историю/feed-инфраструктуру (переключение вкладки «История» и исключение task.comment_created, feedVisibleCount/revealOlderFeed/feedHasMore, дедупликация панели «Вложения» по id файла из разных источников, и реальный баг, найденный при написании этого покрытия: goToAttachmentSource расширяет feedVisibleCount, чтобы показать вложение из старого комментария, но если клик заодно переключает вкладку (например, начиная с «Истории»), собственный watch(feedTab, ...) страницы (который сбрасывает окно при каждом переключении вкладки) срабатывает ровно на том же await nextTick(), который дальше ждёт сама функция, — и молча отменяет только что сделанное расширение; проявляется только при переключении вкладки, подтверждено рядом с проходящим контрольным тестом без переключения; пока не исправлено, сообщено согласно постоянной инструкции «пиши о найденных пробелах во время разработки»). apps/portal/pages/team/hr-pool/index.test.ts (13 юнит-тестов) и .../[id].test.ts (8 юнит-тестов) вместе покрывают полную конечную машину статусов кадрового резерва — это не строгий линейный конвейер: «Взять на рассмотрение» доступно только из SUBMITTED, «Одобрить» — из SUBMITTED или UNDER_REVIEW (свежую заявку можно одобрить напрямую), «Деактивировать» — из любого статуса, кроме уже INACTIVE, «Пригласить» — только при APPROVED и ещё не привязанной к пользователю записи, а «Удалить» — только если у записи нет истории назначений, плюс гейт composer'а заметок рассмотрения на собственной странице записи, в духе canComment. apps/portal/pages/team/members/ {index,[id],[id]/index,[id]/projects,[id]/tasks,[id]/schedule, [id]/activity,[id]/candidate-application}.test.ts (раунд 1 4-раундового разбиения покрыл список/оболочку/Overview; раунд 2 добавил Проекты+Задачи; раунд 3 добавил Расписание+Активность; раунд 4 добавляет «Заявку кандидата», закрывая /team/members и весь этот модуль целиком) покрывает фильтры поиска/отдела/статуса в ростере, departmentsLabel/rolesLabel, объединяющие все значения, а не только первое, «Добавить участника», требующую platform:staffing:manage И (isSuperAdmin или isOwner — совпадает с SuperAdminOrOwnerGuard реального эндпоинта приглашения) на момент написания этого раунда — с тех пор заменено: теперь это единая проверка platform:users:invite без объединённого условия staffing/суперадмин, см. Сотрудники выше, маршрутизацию вкладок оболочки и её меню «⋯» («Отправить в отпуск»/«Вернуть из отпуска» под platform:users:manage, «Открепить от штата» под isSuperAdmin/isOwner), поля личной информации/интересы вкладки Overview, режим отображения вкладки «Проекты» (сетка/список, сохраняется в localStorage, переживает новое монтирование) и её два разных пустых состояния, порядок сортировки вкладки «Задачи» (открытые задачи перед завершёнными, ближайший срок — первым внутри группы) и подсветку просроченных (завершённая задача с прошедшим сроком намеренно НЕ подсвечивается), разделение вкладки «Расписание» на видимые/закрытые интервалы, видимость закрытого времени (TEAM показывает реальное название, всё остальное читается как обобщённое «Занято», повторяющийся блок добавляет подсказку «повторяется еженедельно»), и дедупликацию занято/видимое событие (собственный интервал подтверждённой встречи не должен рисовать дублирующий непрозрачный чип «занято» в том же слоте), фид вкладки «Активность», ограниченный автором — это первая страница во всей инициативе, затрагивающая собственные composable-функции модуля Календаря (useCalendarEvents/useEventTooltip/toCalendarItems), задолго до будущего отдельного раунда /team/calendar, который переиспользует тот же подход к заглушкам, — и поля контактов вкладки «Заявка кандидата», ветку interestAreaLabel для OTHER с собственным уточнением, гейт присутствия карточки заметок, и то, что вся вкладка не рендерит вообще ничего для сотрудника без заявки на файле. Намеренно БЕЗ живой e2e-проверки в этом раунде — собственный флоу HR Pool в staffing.mjs (testHrPool) приглашает кандидата в штат и сразу удаляет запись HR Pool, но приглашение никто не принимает, поэтому реального TeamMember с заполненным candidateApplication в текущем прогоне этого набора вообще не существует; добавить его означало бы принять второе одноразовое приглашение через новый контекст браузера (той же формы, что acceptStaffInvite) исключительно ради уже полностью покрытого юнит-тестами read-only представления — непропорциональная стоимость настройки для этого раунда, то же решение, что пропустило живые «Duplicate» (раунд 27) и «Transfer ownership» (раунд 26).
Найдено, не исправлено, эскалировано в этом раунде (тестовая инфраструктура, не код приложения): staffing.mjs никогда не открепляет от штата одноразовый аккаунт «E2E Staffing Member», который приглашает в каждом прогоне — в отличие от отделов/проектов (каждый исправлен в своём раунде), здесь ничего не подчищает, поэтому ростер накопил 10+ сирот. Раньше это описывалось как засорение БД; в этом раунде выяснилось, что хуже — собственный поиск по имени в ростере попал на участника из УСТАРЕВШЕГО прогона вместо текущего, из-за чего новая проверка вкладки «Задачи» начала флейкать (у того участника вкладка корректно говорила «Задач пока нет», просто не у того человека). Обойдено поиском по staffEmail (уникальный, с меткой времени) вместо общего отображаемого имени, но само накопление сирот всё ещё не устранено и будет ловить любой будущий поиск по имени тем же образом. Отмечено, а не исправлено единолично.
Реальные баги, найденные и исправленные по ходу (2026-08-04 — 2026-08-11): ошибка 403 для manage_own при прикреплении файла (описана в разделе «Задачи» выше); отсутствующая организация system-org-shared-documents (пересоздана и перенесена в packages/database/prisma/seed.ts, чтобы переживать будущие сбросы БД) — без неё любая загрузка вложения к задаче/ проекту или файла в Общие документы падала с обманчивой ошибкой «превышена квота»; вкладка «Участники» проекта считала людей по одному (в счётчике вкладки), но выводила по строке на каждую пару отдел×человек (в таблице) — исправлено группировкой таблицы в одну строку на человека. Пока не исправлено: реальный, ранее не обнаруженный баг в AlertDialogAction из reka-ui (это просто DialogClose без проверки defaultPrevented), который незаметно ломает паттерн «оставить диалог открытым, показать ошибку сервера прямо в нём» в нескольких диалогах удаления/открепления в этом модуле и в IAM — собственное воспроизведение этого бага на вкладке «Роли» отдела больше не существует (вся вкладка убрана 2026-08-14, см. Участники выше), но тот же класс бага по-прежнему воспроизводится на других диалогах удаления этого модуля; не исправлено, поскольку фикс затрагивает прод-код сразу во всех местах — это отдельная работа, не тестирование.
Не покрыто автоматизацией, стоит проверить руками — см. docs/MANUAL_TESTING.md: доступ руководителя отдела (и только его) к вкладке «Финансы» своего отдела, реальная публичная форма заявки в кадровый резерв (закрыта Turnstile, поэтому автотест создаёт заявку напрямую в БД, а не через форму), диалог настройки статусов задач, drag-and-drop на канбан-доске и закрытие read/manage/manage_own правами изменяющих элементов на каждой странице, не покрытых выше.