Skip to content

ТЗ: шаблоны, этапы и Гант, задачи с чек-листами, загрузка людей, причины проигрыша, автодействия ​

Редакция от 05.10.2026. Черновик на согласовании. Основа — разбор Аспро.Cloud (демо-портал, 05.10.2026) и текущего кода бэкенда и фронта. Работа ведётся локально: на staging не выкатываем, пока владелец не скажет.

1. Цель и принципы ​

Шесть доработок закрывают разницу в ежедневной работе с проектами между нами и Аспро. Аспро — универсальная система для любого бизнеса. Мы берём оттуда механику, но подстраиваем её под агентство мероприятий: у каждого проекта есть дата мероприятия, монтаж и демонтаж, и от них, а не от «начала проекта», считается всё остальное.

  1. Шаблоны проектов и копирование проекта. Типовое мероприятие создаётся в один клик: этапы, задачи с чек-листами, команда по ролям, смета.
  2. Задача становится полноценной: чек-лист, подзадачи, наблюдатели, дата начала, связь «после какой задачи».
  3. Этапы проекта с вехами и диаграмма Ганта.
  4. Загрузка людей по дням. Таблица «люди × дни»: кто свободен на дату мероприятия.
  5. Причина проигрыша и источник заявки плюс отчёт «Воронка продаж».
  6. Автодействия: при смене статуса проекта или за N дней до мероприятия система сама ставит задачу или шлёт уведомление. Правила настраиваются без программиста.

Принципы, общие для всех частей:

  • Предупреждать, а не запрещать. Незакрытый чек-лист, открытые подзадачи, невыполненная предыдущая задача, перегруз исполнителя — система показывает это в подтверждении, но действие проходит. Так уже устроено закрытие проекта и табель.
  • Не плодить разделы. Этапы и Гант — виды внутри вкладки «Задачи» проекта. Шаблоны — рядом со списком проектов. Причины и источники — поля в существующих формах. Новые пункты меню всего два: «Загрузка людей» в группе «Ресурсы» и «Автодействия» в настройках.
  • Даты от мероприятия. В шаблонах и автодействиях сроки задаются как «за 10 дней до мероприятия», «в день монтажа», «через 2 дня после окончания», а не абсолютными датами.
  • Одна механика копирования. Копия проекта — это шаблон, который не сохраняется: снять с проекта, применить к новому. Создание из шаблона и копирование используют один и тот же код.
  • ИИ только там, где он убирает ручной ввод. «Сформулировать задачу» начинает заполнять настоящий чек-лист, а не вклеивать шаги в описание. Новых ИИ-виджетов не добавляем.

Что не входит: Agile-доски, конструктор бизнес-процессов с ветвлениями, вебхуки и внешние интеграции, заявки с сайта и из Telegram, почта в карточке, кабинет клиента. Это отдельные ТЗ позже.

2. Как устроено сейчас ​

ЧтоКак сейчасЧто это значит для ТЗ
Даты проектаstart_planned / end_planned (TIMESTAMPTZ) — мероприятие, mount_date (DATE) — монтаж, фактические даты. Отдельной даты демонтажа нет, end_planned играет её роль. Дедлайн контрактации вычисляется: начало минус 1,5 месяцаЭто «якоря» для относительных сроков в шаблонах, на Ганте и в автодействиях
Статусы проектаПресейл (planned … estimating) свободно туда-обратно, затем approved → in_progress → done → closed, плюс lost (можно вернуть в пресейл) и cancelled (только из done). Граф в projects/status.go, дублируется на фронтеНовые статусы не вводим. Переход в lost получает обязательную причину
История статусовТаблицы нет. Есть status_changed_at и событие аудита project.status_changed, которое пишется не всегда (зависит от cfg.Audit.Enabled, не в транзакции, при смене через PUT отдельного события нет)Нужна таблица истории: без неё нет конверсии по ступеням, срока сделки и надёжного триггера для автодействий
Хуки на смену статусаНет. UpdateStatus пишет только аудит. Шины событий нет, автоматизации — прямые вызовы через адаптеры в internal/appАвтодействиям нужна точка расширения: запись в историю + очередь запусков
Создание проектаPOST /projects, без транзакции. Побочно: дивизионы, kickoff-задача менеджеру (флаг в env), аудит, чат (из транспорта), папки (триггер БД). Нумерации нетСоздание из шаблона должно идти в одной транзакции; kickoff-задача переезжает в автодействие «при создании»
КопированиеЕсть только копирование версии сметы внутри одного проекта (estimates CopyContent)Переносим логику копирования разделов и строк на копирование между проектами
ЗадачаПоля: проект, отдел, название, описание, примечание, ответственный (обязателен), соисполнители (task_co_assignees), статус, внутренняя, план/факт часов, обязательность учёта времени, только срок due_date, дата завершения. Нет даты начала, приоритета, тегов. Статусы todo/in_progress/blocked/done/cancelled, на фронте blocked не показываетсяДобавляем дату начала, родителя, этап, чек-лист, наблюдателей, связи
Проверка срока задачиСрок не в прошлом и не раньше начала проектаМешает создавать задачи по шаблону для уже идущих проектов — нужен обход для создания по шаблону
Уведомления по задачамТолько task.assigned (ответственный и соисполнители). О комментариях, смене статуса, сроке — ничегоНаблюдатели без уведомлений бессмысленны: добавляем уведомления о статусе и комментарии
Карточка задачи (фронт)TaskDetailsPage.vue: шапка, «Кратко», «Суть», «Кто и когда», «Время», «Файлы», «Комментарии»; вкладки «Задача / Чат / История»Чек-лист и подзадачи — новые блоки после «Сути», наблюдатели — в «Кто и когда», связи — блок «Порядок»
Доски и лентыКанбан на нативном HTML5 DnD. Лента «Расписание» (ScheduleWidget.vue) и календарь отсутствий (AbsenceCalendar.vue) — самописные, с выходными из календаря компании. Библиотек для Ганта нетГант пишем сами на той же основе, без новой зависимости
Загрузка людейВиджет на главной: часы за текущий месяц / личная норма (168 ч минус отсутствия). По дням нет, плановые часы задач не учитываютсяНужна загрузка по дням с планом из задач
Сетка «люди × дни»GET /absences/calendar — сотрудники × дни, отсутствия, командировки, праздники, до 100 днейОснова для загрузки: тот же каркас ответа и тот же компонент
Занятость вне задачКомандировки: один сотрудник, плановые даты. Логистика: ответственный и водитель, плановые даты. Команда проекта: без дат, только роль и активностьДни мероприятия считаем занятостью для «выездных» ролей команды
КлиентыКомпании с менеджером. Источника клиента или заявки нет нигдеИсточник — поле проекта (каждая заявка), не компании
СправочникиОбщего механизма нет. Категории мероприятий зашиты в кодЗаводим одну таблицу справочников с видом записи
Воронка на главнойFunnelWidget: группировка проектов по статусу, lost/cancelled строкой снизуОстаётся. Подробная аналитика — новый отчёт
ОтчётыСтатусы, финансы, затраты, незапланированные, операции, помощник. CSV на клиентеНовая вкладка «Воронка продаж»
ПраваМатрица ролей (internal/permissions/matrix.go) + capabilities для админских разделов (absences_manage)Новые capability: project_templates_manage, automations_manage, sales_dictionaries_manage
Realtime, контрактыПравила в internal/realtime/rules.go, контракты в internal/contractspecКаждый новый маршрут — правило realtime и описание в контрактах

3. Задачи: дата начала, чек-лист, подзадачи, наблюдатели, связи ​

3.1. Дата начала ​

Новое необязательное поле start_date. Правила:

  • Начало не позже срока. Если указан только срок — задача точечная (на Ганте ромбик срока, в загрузке все плановые часы ложатся на рабочие дни перед сроком, см. 6.2).
  • Начало может быть в прошлом (задача уже идёт). Проверка «срок не в прошлом» остаётся только для ручного создания.
  • В форме задачи «Начало» стоит рядом со «Сроком» в блоке «Кто и когда». На карточке доски показывается диапазон «12–15 окт», если начало задано.

3.2. Чек-лист ​

Один список пунктов в задаче. Пункт: текст, отметка «сделано», кто и когда отметил, порядок. Ответственного и срока у пункта нет: если пункту нужен свой исполнитель — это подзадача.

  • Отмечать пункты могут все, кто может работать с задачей (ответственный, соисполнители, управляющие). Добавлять, править, удалять, менять порядок — так же.
  • На карточке доски и в списке — счётчик «3/7». В карточке задачи — блок «Чек-лист» сразу после «Сути»: пункты с галочками, поле «Добавить пункт» (Enter — следующий), перетаскивание для порядка.
  • Вставка многострочного текста в поле «Добавить пункт» создаёт по пункту на строку.
  • Завершение задачи с неотмеченными пунктами: подтверждение «Не отмечено 2 пункта: …. Завершить всё равно?».
  • «Сформулировать» (ИИ в форме задачи) раскладывает checklist[] в настоящий чек-лист, а не в описание.
  • Отметка пункта пишется в историю задачи, уведомлений не шлёт.

3.3. Подзадачи ​

Подзадача — обычная задача со ссылкой на родителя parent_task_id. Один уровень: у подзадачи не может быть своих подзадач.

  • Подзадача всегда в том же проекте, что родитель (или обе без проекта). Этап по умолчанию — этап родителя.
  • У подзадачи свой ответственный, срок, часы, чек-лист, статус. Часы подзадач в родителя не суммируются: каждая задача отвечает за свои.
  • Создать подзадачу может тот, кто может создавать задачи в проекте. В карточке родителя блок «Подзадачи»: строка «Добавить подзадачу» (название + ответственный + срок прямо в строке), список с исполнителем, сроком, статусом, общий прогресс «2 из 5».
  • Срок подзадачи позже срока родителя — предупреждение в форме, не запрет.
  • Завершение родителя с открытыми подзадачами — подтверждение со списком. Открытые подзадачи при этом не закрываются.
  • Удаление родителя — подтверждение «Удалить вместе с N подзадачами». Подзадачи удаляются.
  • На доске подзадачи — отдельные карточки с подписью «↳ название родителя». Фильтр «Скрыть подзадачи» (запоминается). В списке — группировка под родителем со сворачиванием.
  • Видимость не наследуется: подзадачу видят её участники и все, кто видит проект, как и обычную задачу. Список подзадач в карточке родителя видит каждый, кто видит родителя. Родитель показывается подписью даже тому, кто сам родителя не видит, — только название, без перехода.

3.4. Наблюдатели ​

Наблюдатель видит задачу и получает уведомления о её ходе, но не работает с ней и не меняет её.

  • Таблица task_watchers(task_id, user_id, added_by, created_at).
  • Кнопка «Следить» в шапке задачи — для любого, кто видит задачу; «Перестать следить». Добавить другого человека может тот, кто управляет задачей. Автор задачи становится наблюдателем автоматически, если он не ответственный и не соисполнитель (сейчас автор теряет задачу из виду, когда отдаёт её).
  • Наблюдатель получает право чтения задачи (canViewTask) и попадает в чат задачи как участник с правом писать — так проще, чем вводить «чтение без записи» в чатах.
  • Блок «Кто и когда» показывает наблюдателей аватарами после соисполнителей.

3.5. Связи «после какой задачи» ​

Связь «Б начинается после окончания А», с запасом в днях (может быть отрицательным: «за 2 дня до окончания А»). Других типов связей (начало–начало и т. п.) в первой версии нет: в Аспро они есть, но для мероприятий хватает одного.

  • Только между задачами одного проекта. Циклы запрещены (проверка на сервере).
  • В карточке задачи блок «Порядок»: «Ждёт: Согласовать макет (до 12 окт)», «Следом: Печать баннеров». Добавить связь — выбор задачи проекта поиском.
  • Начать задачу, у которой предыдущая не завершена, можно — с подтверждением «Ещё не готово: …. Начать всё равно?».
  • Когда предыдущая задача завершена, ответственному следующей приходит уведомление task.predecessor_done «Можно начинать: …».
  • Сдвиг срока задачи, у которой есть последующие: после сохранения предложение «Сдвинуть 3 следующие задачи на +2 дня?» со списком. Автоматически ничего не двигается.

3.6. Уведомления по задачам ​

ТипКомуКогда
task.assigned (есть)Новый ответственный, новые соисполнителиКак сейчас
task.status_changedАвтор и наблюдатели, кроме того, кто сменилЗадача завершена, отложена или возвращена в работу. Переход «Планируется → В работе» не шлётся — это шум
task.commentОтветственный, соисполнители, автор, наблюдатели, кроме автора комментарияНовый комментарий
task.predecessor_doneОтветственный следующей задачиПредыдущая завершена

Все новые типы управляются общими настройками уведомлений пользователя (в системе / на почту), ключ от повторов — тип + задача + событие.

4. Этапы проекта, вехи и диаграмма Ганта ​

4.1. Этапы ​

Этап — именованная фаза работ внутри проекта: «Подготовка», «Производство», «Монтаж», «Мероприятие», «Демонтаж и закрытие». Этапы не заменяют статусы проекта: статус — где проект в воронке и производстве, этап — как разбита работа.

  • Таблица project_stages(id, project_id, name, position, color, created_at). У задачи поле stage_id (необязательное).
  • Даты этапа не вводятся, а считаются: от самого раннего начала до самого позднего срока его задач и вех. Пустой этап дат не имеет.
  • Прогресс этапа — доля завершённых задач (отменённые не считаются). Текущий этап — первый по порядку, где есть незавершённые задачи.
  • Управляют этапами те, кто управляет проектом (canManageProject). Удаление этапа: задачи остаются в проекте без этапа.
  • Проект без этапов работает как сейчас: все задачи в группе «Без этапа».

4.2. Вехи ​

Веха — контрольная дата без длительности: «Договор подписан», «Макеты согласованы», «Техника на площадке». Отметка «достигнута».

  • Таблица project_milestones(id, project_id, stage_id, title, date, done_at, done_by, position).
  • Вехи системные — показываются всегда, из полей проекта, только чтение: дедлайн контрактации, монтаж, начало мероприятия, окончание мероприятия. Правятся в карточке проекта, как сейчас.
  • Отметить веху может тот, кто управляет проектом. Просроченная неотмеченная веха подсвечивается красным на Ганте и в «Ходе работ», в «Что дальше» появляется подсказка.

4.3. Где это видно ​

Во вкладке «Задачи» проекта переключатель вида: Доска (как сейчас) / Ход работ / Гант. Выбор запоминается.

Ход работ — аналог «Порядка работ» в Аспро. Полоса этапов сверху с прогрессом, ниже этапы по порядку: задачи этапа (галочка, название, исполнитель, срок), вехи этапа (ромбик, дата, отметка), строки «Добавить задачу» и «Добавить веху». Этапы сворачиваются, перетаскиваются для смены порядка; задачу можно перетащить в другой этап. Внизу — «Без этапа».

4.4. Диаграмма Ганта ​

Пишем сами на основе ScheduleWidget/AbsenceCalendar, без новой библиотеки.

  • Строки: этапы (сворачиваются) → задачи → подзадачи. Слева колонки «Задача», «Исполнитель», «Начало», «Срок».
  • Полосы: задача с началом и сроком — полоса; только со сроком — ромбик на сроке с подсказкой «нет даты начала»; этап — тонкая сводная полоса по своим задачам; вехи — ромбики; завершённые задачи приглушены, просроченные — красные.
  • Фон: выходные и праздники из календаря компании затенены; вертикальные линии «Сегодня», «Монтаж», «Мероприятие» (полоса на все дни мероприятия), «Окончание».
  • Связи: стрелки от конца предыдущей задачи к началу следующей. Нарушенная связь (следующая начинается раньше, чем кончается предыдущая с запасом) — стрелка красная.
  • Масштаб: дни / недели; кнопки «К сегодня», «Весь проект».
  • Правка (для тех, кто управляет задачей): перетаскивание полосы двигает начало и срок вместе, перетаскивание края меняет одну дату, протягивание от края полосы к другой полосе создаёт связь. После сдвига с последующими задачами — то же предложение «Сдвинуть следующие?», что в карточке. Каждое изменение можно отменить (тост с «Отменить», как на доске).
  • Клик по полосе открывает карточку задачи в боковой панели.
  • Телефон: Гант только для чтения с горизонтальной прокруткой; править — в «Ходе работ».
  • Экспорт: PNG картинки диаграммы (для отправки клиенту) — кнопка в углу.

4.5. Лента проектов ​

В списке проектов к видам «Таблица / Доска» добавляется «Лента»: строка на проект, по горизонтали дни. На строке — точка дедлайна контрактации, полоса монтажа, полоса мероприятия, конец. Цвет — статус проекта. Фильтры списка проектов действуют и здесь. Это ответ на вопрос «что у нас на какие даты» без открытия каждого проекта. Правки на ленте нет.

5. Шаблоны проектов и копирование проекта ​

5.1. Что лежит в шаблоне ​

ЧастьКак хранится в шаблонеЧто происходит при создании проекта
ОсновноеНазвание шаблона, описание, категория мероприятия, дивизион по умолчанию, текст описания проектаПодставляется в форму, можно поменять
ЭтапыНазвание, порядок, цветСоздаются как есть
ЗадачиНазвание, описание, этап, родитель (подзадачи), роль исполнителя (из ролей проекта: менеджер, ведущий, инженер, техник, логист…), план часов, внутренняя, обязательность учёта времени, начало и срок относительно якоря, чек-листИсполнитель — участник команды с этой ролью (первый по списку), если такого нет — менеджер проекта. Даты считаются от якоря
Связи задачПары задач шаблона с запасомВосстанавливаются между созданными задачами
ВехиНазвание, этап, дата относительно якоряСоздаются
КомандаРоли (и при желании конкретные люди по умолчанию)Заполняется команда людьми по умолчанию; роль без человека в команду не добавляется, её задачи уходят менеджеру
СметаРазделы и строки действующей версии; все строки становятся ручными с теми же суммами (привязки к старому проекту не переносятся)Создаётся черновик сметы версии 1

Якоря дат: начало мероприятия (по умолчанию), монтаж, окончание мероприятия, создание проекта. Смещение — в календарных днях, со знаком: «−10 от мероприятия», «0 от монтажа», «+2 от окончания». Опция «только рабочие дни» на уровне шаблона: если включена, смещение считается в рабочих днях по календарю компании, а дата, попавшая на выходной, сдвигается на ближайший рабочий день раньше.

Не входит в шаблон: файлы, ТЗ, документы, платежи, бюджет и факт, логистика, командировки, обязательства, часы, чат.

5.2. Создание проекта из шаблона ​

  1. В диалоге «Новый проект» сверху выбор «С нуля / Из шаблона». Список шаблонов с описанием и составом («5 этапов, 34 задачи, смета на 1,2 млн»).
  2. После выбора форма заполняется данными шаблона. Обязательны даты, от которых зависят задачи шаблона (если в шаблоне есть привязки к монтажу — монтаж обязателен).
  3. Перед кнопкой «Создать» — сводка: что будет создано, сколько задач получат исполнителя по роли, сколько уйдут менеджеру. Задачи, чьи сроки при этих датах уже в прошлом, переносятся на сегодня — сводка показывает их число.
  4. Всё создаётся в одной транзакции: проект, дивизионы, команда, этапы, задачи, чек-листы, связи, вехи, смета. Чат и папки — как сейчас, после фиксации. Ошибка любой части — проект не создаётся.
  5. В карточке проекта в «Обзоре» строка «Создан по шаблону «…»».

Изменение шаблона потом на созданные проекты не влияет.

5.3. Сохранить проект как шаблон ​

В меню карточки проекта «Сохранить как шаблон». Диалог: название шаблона, якорь по умолчанию, галочки состава (этапы и задачи, вехи, команда, смета). Даты задач пересчитываются в смещения от выбранного якоря проекта. Исполнители превращаются в роли по их роли в команде проекта; если человек не в команде — роль «менеджер». Статусы и отметки сбрасываются. Отменённые задачи не берутся.

5.4. Копирование проекта ​

В меню карточки проекта «Копировать». Диалог: название (по умолчанию «… (копия)»), клиент (по умолчанию тот же), новые даты мероприятия и монтажа, галочки: этапы и задачи, вехи, команда (те же люди), смета, требования к оборудованию, описание. Даты задач сдвигаются на разницу между старым и новым началом мероприятия. Новый проект — в статусе «Запланирован».

Технически это «снять шаблон в памяти» + «создать из шаблона», с отличием: команда копируется людьми, а не ролями.

5.5. Управление шаблонами ​

Страница «Проекты → Шаблоны» (кнопка рядом с «Новый проект» в списке проектов, отдельного пункта меню нет).

  • Таблица: название, категория, состав, сколько проектов создано, активен, кто изменил.
  • Редактор шаблона: основное; этапы со списком задач в виде «Хода работ», где вместо дат — смещения («за 10 дн. до мероприятия»); вехи; команда по ролям; смета (просмотр и замена из проекта — смету в шаблоне руками не правим, её берут из удачного проекта).
  • Ниже редактора — предпросмотр: «Если мероприятие 20 ноября, задачи лягут так» в виде Ганта.
  • Неактивный шаблон не предлагается при создании, но не удаляется. Удаление — только если по шаблону ничего не создано, иначе только деактивация.
  • Создавать и править шаблоны: capability project_templates_manage (администратор, генеральный директор, руководители дивизионов). Пользоваться — все, кто может создавать проекты.

6. Загрузка людей по дням ​

6.1. Экран ​

Новый пункт меню «Загрузка людей» в группе «Ресурсы». Строка — сотрудник, колонка — день (2 недели / месяц, листание). Сверху фильтры: дивизион, отдел, роль в проектах, проект (только люди его команды), поиск по имени. Переключатель План / Факт.

Ячейка:

  • План — процент дневной нормы по плановым часам задач (см. 6.2). Цвет: до 50 % — светлый, 50–100 % — обычный, больше 100 % — красный.
  • Факт (прошедшие дни) — отмеченные часы из учёта времени.
  • Значки поверх: отпуск/больничный/отгул (ячейка заштрихована, норма 0 или 4 ч), командировка, рейс логистики (водитель или ответственный), мероприятие проекта (для «выездных» ролей, см. 6.2).
  • Выходные и праздники затенены.

Клик по ячейке — всплывающая панель: задачи дня с часами, командировка, перевозка, мероприятия; ссылки в карточки. Справа от имени — итог периода: план / норма.

6.2. Как считается план ​

  • Норма дня — 8 ч в рабочий день по календарю компании, 4 ч в день с половиной отсутствия, 0 в выходной, праздник и полный день отсутствия.
  • Плановые часы задачи распределяются поровну по рабочим дням от начала до срока. Нет начала — часы ложатся на рабочие дни перед сроком из расчёта 8 ч в день (40 часов → 5 рабочих дней до срока). Нет плановых часов — задача в процент не входит, но видна в панели дня.
  • Учитываются задачи в статусах «Планируется» и «В работе» (и «Заблокирована»), где человек ответственный. Соисполнитель получает те же часы (часы задачи — оценка на каждого участника; так проще и понятнее, чем делить).
  • Мероприятия: дни от монтажа до окончания мероприятия у проектов в статусах «Подтверждён» и «В работе» отмечаются значком у участников команды с «выездными» ролями (ведущий, инженер, техник, логист). Процент не меняют: время на площадке и так должно быть задачами.
  • Командировка и рейс — значок и отметка «в отъезде», процент не меняют.

6.3. Подсказка при назначении ​

В форме задачи при выборе ответственного и соисполнителей рядом с именем — короткая сводка на даты задачи: «120 % в эти дни», «в отпуске 12–14 окт», «в командировке». То же в одобрении заявки на людей в команду проекта. Это подсказка, не запрет.

6.4. Кто что видит ​

КтоЧто видит
СотрудникСвою строку целиком
Руководитель отдела, дивизионаСвоих людей целиком
Генеральный директор, администраторВсех целиком
Менеджер проектаЛюдей своих проектов и людей из отделов, куда можно подать заявку, — только процент и занятость (отпуск, отъезд, мероприятие), без названий чужих задач и проектов

Права берутся из существующих объектов: «чужие табели» (others_timesheets) для полного доступа, менеджер проекта — по роли в проекте.

Виджет «Загрузка сотрудников» на главной остаётся месячным и получает ссылку «По дням →».

7. Причина проигрыша, источник заявки и отчёт «Воронка продаж» ​

7.1. Справочники ​

Таблица sales_dictionary_items(id, kind, name, position, is_active), вид lost_reason или lead_source. Правка в «Настройки → Компания → Справочники продаж» (capability sales_dictionaries_manage: администратор, генеральный директор, руководитель отдела продаж). Записи не удаляются, если использованы, — только скрываются.

Начальные значения:

  • Причины проигрыша: Дорого; Выбрали другого подрядчика; Мероприятие отменено или перенесено; Не успеваем по срокам; Нет нужного оборудования или людей; Клиент пропал; Не наш формат; Другое.
  • Источники заявки: Повторный клиент; Рекомендация; Сайт; Тендер или площадка закупок; Входящий звонок или письмо; Выставка или мероприятие; Холодный контакт; Другое.

7.2. Источник заявки ​

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

7.3. Причина проигрыша ​

  • При переводе в «Проигран» (из карточки, из быстрого меню в списке, с доски) открывается диалог: причина (обязательно), комментарий, кому ушли (свободный текст, необязательно). Без причины перевести нельзя — это единственное жёсткое требование в ТЗ, потому что без него отчёт бесполезен.
  • Поля проекта: lost_reason_id, lost_comment, lost_competitor. При возврате из «Проигран» в пресейл поля очищаются, но остаются в истории статусов.
  • В быстром меню списка «Проигран» больше не меняется сразу с «Отменить», а открывает диалог.
  • Перевод в «Отменён» получает необязательный комментарий.
  • Уже проигранные проекты без причины показываются в отчёте как «Не указана».

7.4. История статусов ​

Таблица project_status_history(id, project_id, from_status, to_status, changed_by, changed_at, lost_reason_id, comment). Запись — в той же транзакции, что смена статуса, и через PATCH /status, и через PUT /projects/:id, и при создании проекта (from_status пустой). Однократное заполнение из журнала аудита там, где он есть. Вкладка «История» проекта показывает смены статуса из этой таблицы. Эта же запись — триггер для автодействий (раздел 8).

7.5. Отчёт «Воронка продаж» ​

Новая вкладка в «Отчёты». Фильтры: период, дивизион, менеджер, источник, категория мероприятия. Доступ — как у остальных отчётов (reports_dashboards), денежные суммы — по праву видеть бюджет клиента.

  • Плитки: новых заявок за период; выиграно (дошли до «Подтверждён») — штук и сумма; проиграно — штук и сумма; конверсия = выиграно / (выиграно + проиграно); средний срок от заявки до подтверждения, дней.
  • Воронка по ступеням: сколько заявок периода дошло до каждой пресейл-ступени и до «Подтверждён», процент перехода между ступенями. Считается по истории статусов.
  • Причины проигрыша: столбцы по числу и сумме, клик — список проектов.
  • Источники: таблица источник → заявок, выиграно, конверсия, сумма выигранного.
  • Менеджеры: таблица менеджер → заявок, выиграно, проиграно, конверсия, сумма, средний срок.
  • Экспорт CSV, как у остальных отчётов.

8. Автодействия ​

8.1. Что такое правило ​

Правило = когда + для каких проектов + что сделать.

Когда (триггер):

  • Проект создан.
  • Проект перешёл в статус X (любой из статусов проекта).
  • За N дней до / через N дней после даты проекта: монтаж, начало мероприятия, окончание мероприятия. Срабатывает раз в сутки утром по часовому поясу компании, только для проектов в статусах «Подтверждён» и «В работе».

Для каких проектов (условия, все необязательные): дивизион, категория мероприятия, создан по шаблону X, источник заявки.

Что сделать (действие):

ДействиеПараметры
Поставить задачуНазвание (можно вставлять {проект}, {клиент}, {дата мероприятия}), описание, исполнитель — роль в проекте / менеджер проекта / конкретный сотрудник, срок — через N дней от срабатывания или относительно даты проекта, план часов, чек-лист, этап (по названию, если в проекте есть такой)
Добавить задачи из шаблонаШаблон проекта: из него берутся этапы, задачи и вехи (без команды и сметы). Пример: при «Подтверждён» добавить пакет задач подготовки
УведомитьКому — роли в проекте / менеджер / руководитель дивизиона / конкретные люди; текст с подстановками; ссылка на проект
Написать в чат проектаСистемное сообщение с подстановками («Проект подтверждён, монтаж 12 ноября»)

Правило может содержать несколько действий по порядку. Действия, которые меняют статус проекта, в первой версии не делаем — так исключаются циклы.

8.2. Как выполняется ​

  • Смена статуса или создание проекта в той же транзакции пишет запись в историю статусов и ставит подходящие правила в очередь automation_runs. Воркер выполняет их в течение нескольких секунд: пользователь не ждёт и ошибка автодействия не ломает смену статуса.
  • Один раз: правило срабатывает для проекта один раз на каждое событие. Для «перешёл в статус» — один раз за жизнь проекта, если в правиле не включено «при каждом входе в статус» (проект может вернуться из «Проигран» и снова пройти пресейл). Ключ от повторов — правило + проект + событие.
  • Каждое выполненное действие видно во вкладке «История» проекта: «Автодействие «Подготовка к монтажу» поставило задачу «Проверить технику» (Петров)». Ошибка — там же и в журнале автодействий для администратора.
  • Задача, поставленная автодействием, помечена «Создано автоматически» и ссылкой на правило.

8.3. Настройка ​

«Настройки → Система → Автодействия» (capability automations_manage: администратор, генеральный директор).

  • Экран — колонки по триггерам, как в Аспро: «Создан», статусы проекта по порядку, «Даты проекта». В колонке — карточки правил с кратким текстом «Сразу → задача логисту «Заказать транспорт»». Переключатель «Вкл/выкл» на карточке.
  • Редактор правила в боковой панели. Внизу — «Проверить на проекте»: выбор проекта, система показывает, что бы создала (задачи с исполнителями и сроками, получателей), ничего не создавая.
  • Журнал запусков: дата, правило, проект, результат, ошибка.

8.4. Что переезжает в автодействия ​

  • Kickoff-задача менеджеру при создании проекта пока остаётся прежней (настройка в env); перенести её в правило «Проект создан → задача менеджеру» можно, выключив флаг. Решение реализации: не менять поведение без отдельного согласия.
  • Автоматизации командировок, логистики, затрат, финансовые ворота и «Что дальше» остаются в коде: они завязаны на деньги и документы, настраивать их не нужно.

8.5. Начальный набор правил (выключены, кроме kickoff) ​

  • Подтверждён → задача менеджеру «Подписать договор» на 3 дня; уведомление руководителю дивизиона.
  • Подтверждён → задача логисту «Заказать транспорт» за 7 дней до монтажа.
  • За 3 дня до монтажа → задача ведущему «Проверить готовность оборудования» с чек-листом.
  • Через 2 дня после окончания мероприятия → задача менеджеру «Собрать фотоотчёт и закрывающие документы».
  • Проигран → уведомление руководителю отдела продаж с причиной.

9. Данные, API, права, уведомления ​

9.1. Схема (миграции с 0187, порядок по этапам) ​

МиграцияЧто
tasks_start_parent_stagetasks.start_date TIMESTAMPTZ NULL, tasks.parent_task_id BIGINT NULL REFERENCES tasks ON DELETE CASCADE, tasks.stage_id BIGINT NULL, tasks.automation_rule_id BIGINT NULL; индексы по parent_task_id, stage_id и (assignee_id, due_date)
task_checklisttask_checklist_items(id, task_id, title, is_done, done_by, done_at, position, created_at), индекс (task_id, position)
task_watcherstask_watchers(task_id, user_id, added_by, created_at), PK (task_id, user_id), индекс по user_id
task_dependenciestask_dependencies(predecessor_id, successor_id, lag_days INT NOT NULL DEFAULT 0), PK по паре, индекс по successor_id
project_stages_milestonesproject_stages, project_milestones; FK tasks.stage_id → project_stages ON DELETE SET NULL
project_templatesproject_templates(id, name, description, event_category, department_id, project_description, workdays_only, is_active, created_by, updated_by, timestamps), project_template_items (этапы, задачи, вехи — одна таблица с видом и parent_item_id, или три таблицы — решить при реализации), project_template_dependencies, project_template_team, project_template_estimate (снимок сметы JSONB); projects.template_id NULL
sales_dictionariessales_dictionary_items; projects.lead_source_id, lost_reason_id, lost_comment, lost_competitor (все NULL); начальные значения
project_status_historyТаблица истории, индексы (project_id, changed_at) и (to_status, changed_at); заполнение из audit_events
automationsautomation_rules(id, name, is_active, trigger_kind, trigger_status, anchor, offset_days, repeat_each_entry, conditions JSONB, actions JSONB, created_by, timestamps), automation_runs(id, rule_id, project_id, event_key, status, result JSONB, error, created_at, done_at), уникальный (rule_id, project_id, event_key); начальные правила

Все ADD COLUMN — с NULL или DEFAULT. Деньги в снимке сметы шаблона — строками с двумя знаками, читаются в money.Money.

9.2. API (новое и изменённое) ​

Задачи:

  • POST/PUT /tasks — новые поля start_date, parent_task_id, stage_id, watcher_ids; в ответе checklist_total/done, subtask_total/done, parent (id, название), watcher_ids, predecessors[], successors[].
  • GET /tasks/:id/checklist, POST /tasks/:id/checklist (в т. ч. массивом строк), PATCH /tasks/:id/checklist/:item_id, DELETE …, PUT /tasks/:id/checklist/order.
  • GET /tasks/:id/subtasks.
  • POST /tasks/:id/watch, DELETE /tasks/:id/watch, PUT /tasks/:id/watchers.
  • POST /tasks/:id/dependencies, DELETE /tasks/:id/dependencies/:predecessor_id.
  • POST /tasks/shift — сдвиг набора задач на N дней (для «Сдвинуть следующие?» и Ганта), одной транзакцией.
  • GET /tasks — фильтры parent_task_id, stage_id, without_subtasks, from/to по датам.

Проекты:

  • GET/POST /projects/:id/stages, PUT/DELETE /projects/:id/stages/:stage_id, PUT /projects/:id/stages/order.
  • GET/POST /projects/:id/milestones, PUT/DELETE …/:milestone_id.
  • GET /projects/:id/plan — этапы, задачи с датами и связями, вехи, системные даты одним ответом (для «Хода работ» и Ганта; праздники — из GET /calendar).
  • Лента проектов строится из обычного GET /projects — отдельного маршрута нет.
  • POST /projects/:id/copy, POST /projects/:id/save-as-template.
  • POST /projects — template_id и lead_source_id; GET /projects/template-preview?template_id&dates… — сводка перед созданием.
  • PATCH /projects/:id/status — {status, lost_reason_id, lost_comment, lost_competitor, comment}; 400 lost_reason_required без причины.
  • GET /projects/:id/status-history.

Шаблоны: GET/POST /project-templates, GET/PUT/DELETE /project-templates/:id, POST /project-templates/:id/preview.

Загрузка: GET /workload?from&to&department_id&project_id&role&mode=plan|fact (до 62 дней), GET /workload/users?user_ids&from&to — краткая сводка для подсказки в форме.

Продажи: GET/POST /sales-dictionaries?kind, PUT /sales-dictionaries/:id; GET /reports/sales-funnel?….

Автодействия: GET/POST /automations, GET/PUT/DELETE /automations/:id, POST /automations/:id/dry-run {project_id}, GET /automations/runs?….

Все списки — через transport.RespondList. Каждый маршрут — правило в internal/realtime/rules.go (новые части проекта stages, schedule; сущность task для чек-листа, подзадач, наблюдателей) и описание в internal/contractspec; после каждого этапа — перегенерация контрактов.

9.3. Права ​

ДействиеКто
Чек-лист, подзадачи, связи задачиКто может работать с задачей (чек-лист) или управлять ею (подзадачи, связи) — существующие проверки
Следить за задачейКто видит задачу; добавлять других — кто управляет
Этапы, вехи, правка на ГантеcanManageProject / управление задачей
Создать проект из шаблона, копироватьКто может создавать проекты; копирование — ещё и видеть исходный
Шаблоны: создать, правитьproject_templates_manage
Загрузка людейРаздел 6.4
Справочники продажsales_dictionaries_manage
Отчёт «Воронка продаж»reports_dashboards
Автодействияautomations_manage

Capability добавляются тем же способом, что absences_manage (WithCapabilities, тип AppCapability на фронте, routeAccess.ts). docs/rbac_matrix.md и docs/concepts/permissions-matrix.md обновляются.

9.4. Уведомления ​

Новые типы: task.status_changed, task.comment, task.predecessor_done, automation.notify (текст правила), automation.failed (администратору, раз в сутки сводкой). Маршрутизация на фронте — по entityType задачи/проекта, как сейчас.

9.5. Помощник ​

  • get_task и list_tasks отдают чек-лист, подзадачи, этап, наблюдателей.
  • «Сформулировать задачу» заполняет чек-лист.
  • Новый инструмент чтения workload — «кто свободен 12–14 ноября среди техников» — с теми же правами, что экран.
  • Новых ИИ-кнопок нет.

10. Этапы работ и приёмка ​

Порядок выбран так, чтобы каждый этап опирался на предыдущий: шаблонам нужны этапы, чек-листы и подзадачи; Ганту — дата начала и связи; автодействиям — история статусов.

ЭтапСоставОриентир
1. ЗадачиДата начала, чек-лист, подзадачи, наблюдатели, связи, «сдвинуть следующие», новые уведомления, «Сформулировать» → чек-лист; доска и список с подзадачами; показ статуса blocked на фронте3–4 дня
2. Этапы и ГантЭтапы, вехи, системные вехи, «Ход работ», Гант с правкой и связями, лента проектов, PNG4–5 дней
3. Шаблоны и копированиеШаблоны (хранение, редактор, предпросмотр), создание из шаблона в транзакции, «Сохранить как шаблон», «Копировать проект»4–5 дней
4. Загрузка людейЭкран «люди × дни» план/факт, панель дня, подсказка при назначении и в заявке на людей, права, ссылка с главной, инструмент помощника2–3 дня
5. ПродажиСправочники, источник, обязательная причина проигрыша, история статусов с заполнением из аудита, отчёт «Воронка продаж»2–3 дня
6. АвтодействияПравила, очередь и воркер, триггеры статуса и дат, четыре действия, проверка на проекте, журнал, перенос kickoff, начальный набор4–5 дней

Приёмочный сценарий (сквозной, на локальной базе) ​

  1. Администратор создаёт шаблон «Выставочный стенд» из прошлого проекта: 5 этапов, 30 задач с чек-листами и связями, вехи, команда по ролям, смета.
  2. Менеджер создаёт проект из шаблона: источник «Рекомендация», мероприятие через 20 дней, монтаж за 2 дня до него. Сводка показывает, кому уйдут задачи; после создания задачи стоят на правильных датах, у ролей — нужные люди.
  3. На Ганте менеджер сдвигает «Согласование макета» на 2 дня, соглашается сдвинуть следующие; стрелки связей остаются целыми.
  4. Ведущий отмечает пункты чек-листа, добавляет подзадачу технику; автор задачи как наблюдатель получает уведомление о завершении.
  5. В «Загрузке людей» видно, что техник на дни монтажа перегружен (красный) и что у второго техника отпуск; менеджер переназначает задачу, подсказка в форме это подтверждает.
  6. Проект переводится в «Подтверждён» — автодействие ставит логисту «Заказать транспорт» со сроком за 7 дней до монтажа, в чат проекта приходит сообщение, в «Истории» видна запись.
  7. Второй проект переводится в «Проигран» — без причины не даёт, с причиной «Дорого» проходит; в отчёте «Воронка продаж» видна причина, источник и конверсия.
  8. Проект копируется на новую дату — задачи сдвинуты, файлов, денег и логистики в копии нет.
  9. Каждый шаг сверяется с базой (записи в project_status_history, automation_runs, task_checklist_items и т. д.).

Готовность каждого этапа ​

  • Бэкенд: миграции на локальной scratch-базе вверх и вниз, тесты сервисов и HTTP, go vet, go test ./..., контракты перегенерированы, go test ./internal/contractcheck/... зелёный.
  • Фронт: типы, линтер, сборка, e2e на сценарий этапа, проверка в браузере на локальном стенде (Docker, шлюз 8088), телефонная ширина.
  • Документация: docs/concepts/ (новые страницы: task-structure.md, project-stages-gantt.md, project-templates.md, workload.md, sales-funnel.md, automations.md), справка «Как сделать» для сотрудников, docs/rbac_matrix.md.
  • Коммиты в ветку staging локально. Не пушим и не выкатываем, пока владелец не скажет.

11. Решения, которые нужно подтвердить ​

Ниже — что выбрано по умолчанию. Если ответ другой, ТЗ правится до начала соответствующего этапа.

  1. Подзадачи — один уровень. В Аспро глубже, но больше одного уровня на доске и в загрузке читается плохо.
  2. Связи — только «после окончания» с запасом в днях. Остальные три типа из Аспро не делаем.
  3. Соисполнитель в загрузке получает те же плановые часы, что и ответственный. Альтернатива — делить часы поровну.
  4. «Выездные» роли для отметки дней мероприятия: ведущий, инженер, техник, логист. Список можно расширить.
  5. Причина проигрыша обязательна. Источник заявки — нет.
  6. Источник — у проекта (каждой заявки), не у компании.
  7. Задачи из шаблона со сроком в прошлом переносятся на сегодня. Альтернатива — создавать просроченными.
  8. Смета в шаблоне не правится руками — только берётся из проекта.
  9. Автодействия «перешёл в статус» срабатывают один раз за жизнь проекта, если не отмечено «при каждом входе».
  10. Шаблоны создают руководители дивизионов и выше, а не каждый менеджер.
  11. Работа только локально: коммиты в staging без пуша. Пушить в GitHub (без выката на сервер) можно? По умолчанию — нет.

Загружаем документацию…