Skip to content

Дашборд руководства ​

Главная страница для руководителей: состояние проектов, денег, оборудования, логистики и дисциплины учёта времени одним экраном (ТЗ: MVP, раздел 9; «Единая панель управления» финансового ядра; дашборд «Финансовые риски проектов»).


Что на главной (с 2026-09-30) ​

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

ВиджетЧто показываетДанные
Воронка проектовступени от лида до сдачи; ширина — сколько проектов дошли до стадии (она и дальше, включая закрытые), число — сколько на ней сейчас, рядом плановый бюджет; «Ждём …» сведены в «Обсуждаем», потерянные и отменённые — строкой ниже; ступень ведёт в список проектовfunnel
Прибыль по проектамстолбики от нуля: прибыль вправо, убыток влево — пять лучших и пять худших проектов, от лучшего к худшему; подсказка — выручка и затратыprofit
Деньги по месяцамприход и расход проведённых платежей столбиками, сальдо линией, за полгода; месяц без платежей — нули; ролям без отчёта о движении денег (403) виджет не показываетсяGET /reports/cashflow
Перевозки и командировкилента на 7/30 дней: полоса — от отправления до прибытия, выходные затенены, черта — сейчас; оборудование в пути — штрихованная полоса с числом единиц, прошедшие сроки — метка «сроки прошли»logistics, equipment_in_transit

Остальные блоки — заполняемость часов по отделам, загрузка людей, склады, логистика план/факт, оборудование в пути списком, риск недостоверности данных — во вкладке «Отчёты» → «Операции» (тот же GET /dashboard/executive). Графики нарисованы SVG и CSS на токенах цвета — тёмная тема без отдельной настройки.


Один запрос ​

GET /api/v1/dashboard/executive?horizon_days=7|30 — все блоки в одном ответе, чтобы главная загружалась одним запросом. horizon_days задаёт окно для логистики и командировок (по умолчанию 7, другое значение — 400).

Маршрут закрыт объектом reports_dashboards матрицы прав. Охват:

Охват reports_dashboards.readЧто попадает в выборку
«все» (OWNER, OPS, FIN_DIR, FIN_ASSIST)Вся компания, scope: "all"
«свой» (TECH_DIR, DIV_HEAD, MANAGER)Проекты своих дивизионов (основной отдел или project_departments), их логистика и командировки, сотрудники своих отделов; scope: "own"

Склады не сужаются: остатки — общий ресурс компании.

Блоки и права ​

Блок, закрытый матрицей, не отдаётся, а его ключ попадает в hidden. Ограничение действует на сервере, а не только в интерфейсе (спец. п.11).

БлокЧто считаетНужен доступКлюч в hidden
funnel.by_statusПроекты по статусам (без архивных)——
funnel.by_status[].planned_budgetСумма бюджетов по статусуclient_budgetbudgets
funnel.by_cityОткрытые проекты по городу площадки (locations.city, иначе название)——
portfolio.active_countПроекты в approved, in_progress——
portfolio.active_budget_totalСумма planned_budget активных проектовclient_budgetbudgets
portfolio.weighted_pipelineБюджет пресейла × вероятность закрытия (ручная или по статусу)probability_weightedweighted_pipeline
profit.top / profit.bottom5 самых прибыльных и убыточных проектов в работе и после неё: фактическая выручка − фактические затратыearnings_marginprofit
equipment_in_transitОперации в статусе in_transit: маршрут, плановое прибытие, количествоequipment_stockequipment
warehousesСклады (locations.type = warehouse): позиции и количество оборудования по статусамequipment_stockequipment
logistics.operationsОткрытые операции в пути или с отправкой/прибытием в окне——
logistics.tripsКомандировки в работе или с выездом в окне; в охвате «свой» — поездки своих отделов и собственные поездки пользователя——
logistics_costsПлан/факт логистики за текущий месяц: операции по плановой отправке (только согласованные финансами, finance_status = approved — на проверке и отклонённые в бюджет не попадают), командировки по плановому выездуcostslogistics_costs
staff_load10 самых загруженных сотрудников месяца: часы / норма (APP_LABOR_MONTHLY_NORM_HOURS)others_timesheetsstaff_load
time_fillЗаполняемость времени по отделам за прошлый месяц (пусто — за текущий по сегодня), светофор; период — в time_fill_period (from, to)——
data_riskТОП-5 проектов с риском недостоверности данных——

Заполняемость времени ​

Берётся из снимков KPI (kpi.ListDepartmentKPI, период — прошлый календарный месяц по часовому поясу компании APP_TIMEZONE). Если за прошлый месяц ни плана, ни часов (например, в первый месяц работы), блок берёт текущий месяц с первого числа по сегодня (period=current_month); какой период показан — в time_fill_period. Снимок не замораживается: при чтении он пересчитывается, если старше часа, а воркер KPI каждую ночь (в 01:00 по времени компании) заново считает вчера, 7 дней и прошлый месяц — часы, внесённые задним числом, попадают в показатель. Пересчёт заменяет снимки периода целиком.

С 2026-09-30 заполняемость считается по задачам, закрытым в периоде (tasks.completed_at, миграция 0163): план — их плановые часы, факт — все часы по этим задачам (в том числе соисполнителей и записанные раньше периода). План и факт относятся к исполнителю задачи и его отделу, поэтому строка отдела равна сумме строк его сотрудников. Раньше план брался по сроку задачи в периоде, а факт — по всем записям времени, и показатель сравнивал разные задачи: у задач без срока план пропадал, заполняемость выходила «—». Часы периода по задачам без плана и без задачи — отдельное поле unplanned_hours («Работа без плана»). completed_at ставит триггер при переходе в «Завершено» и снимает при выходе из него; старые завершённые задачи получили дату из журнала действий (последний переход в «Завершено»); без записи в журнале дата пустая и такая задача в KPI не входит. Заполняемость ограничена 9999,99 % (колонка NUMERIC(6,2)). Уровни светофора: зелёный > 95 %, жёлтый 85–95 %, красный < 85 %, none — нет закрытых задач с планом.

Риск недостоверности данных ​

Для проектов в approved, in_progress, done:

  • without_hours_percent — доля закрытых задач, по которым нет ни одной записи времени;
  • unplanned_percent — доля задач без плановых часов (работа вне плана);
  • score — среднее двух долей; проекты сортируются по нему.

Эти проекты — первые кандидаты на разбор на еженедельной встрече (ТЗ, «Финансовые риски»).


Динамика бюджета проекта ​

GET /api/v1/projects/:id/budget/dynamics — виджет «Динамика бюджета» в карточке проекта: план, накопленный факт по неделям и отклонение.

json
{
  "project_id": 1,
  "planned_revenue": 2500000.00,
  "planned_costs": 2095000.00,
  "actual_costs": 1395000.00,
  "deviation": -700000.00,
  "weeks": [{ "week_start": "2026-09-21", "actual_costs": 1395000.00, "cumulative_actual": 1395000.00 }]
}
  • planned_costs / actual_costs — суммы плана и факта по статьям затрат проекта; deviation = actual − planned (положительное — перерасход).
  • Неделя статьи определяется по источнику: запись времени — дата записи; логистика — фактическое или плановое прибытие; командировка — фактическое возвращение или плановый выезд; ручная статья — дата создания.
  • Доступ — как у сводки бюджета (раздел «Финансы» проекта); planned_revenue скрывается без client_budget.

Деньги ​

Все суммы дашборда, сводки GET /dashboard/overview и отчётов /reports/* — точный денежный тип money.Money, в JSON — число с копейками.

Архивные проекты в сводке GET /dashboard/overview и в отчётах /reports/* не участвуют (как в списке проектов по умолчанию). Плановая выручка, плановые затраты и плановая прибыль не учитывают проигранные (lost) и отменённые (cancelled) проекты; фактические суммы — по всем неархивным.

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