Перейти к основному содержимому

Методология расчёта стоимости проектов и задач

Наша платформа автоматизирует финансовую аналитику, объединяя данные о реальной активности сотрудников. Мы собираем информацию через специальные плагины, которые отслеживают активность в IDE, браузере, терминале (CLI), клиентах БД и AI-ассистентах, и сопоставляем её с задачами из поддерживаемых трекеров (Jira, GitHub и др.). На основе этих данных система формирует честную и прозрачную себестоимость разработки.

Схема ниже показывает сквозной поток — от сырой активности до итоговой стоимости проекта:

Сквозной поток расчёта стоимости

1. Прямые затраты (Direct Costs)

Прямые затраты — фундамент всех расчётов, фактическая стоимость времени, зафиксированного за конкретным сотрудником.

Как считаем

Для каждого сотрудника берётся последняя активная ставка, действующая в периоде, и применяется одна из двух формул:

  • Почасовая ставка (HOURLY):
    cost = (seconds / 3600) × hourly_rate
  • Месячная ставка (MONTHLY):
    cost = (seconds / 3600) × (monthly_rate / 160)
    где 160 ч — стандартный рабочий месяц (8 ч × 20 дней).

Источники активности

Активность собирается по пяти категориям ActivityType: CODING, BROWSING, DATABASE, CLI и AI_CODING. Данные агрегируются через материализованные представления:

  • mv_activity_total_user_project_daily
  • mv_activity_total_user_issue_daily
  • mv_activity_total_user_daily

Task-mapped vs. non-task активность и размазывание non-task

Активность сотрудника делится на два типа:

  • Task-mapped — активность, сопоставленная с конкретной задачей (issue_key из ветки Git или контекста плагина совпал с задачей трекера).
  • Non-task — активность без привязки к задаче (митинги, ревью, планирование, обучение и т. п.).

:::important Как non-task время попадает на задачи Non-task время — не отдельный overhead-пул. Для каждого сотрудника, у которого в периоде есть и task-, и non-task активность, его non-task стоимость размазывается по его же задачам в той же пропорции, что и прямые task-затраты.

Пример: у сотрудника 2 000 на Задаче A и 1 000 на Задаче B (2:1), плюс 300 non-task. После размазывания Задача A получает +200, Задача B +100 — пропорция 2:1 сохраняется.

Поэтому direct_total задачи — это сумма её прямых task-затрат и размазанной доли non-task. Все дальнейшие формулы работают с этим «обогащённым» direct_total. :::

2. Косвенные расходы (Overhead)

В overhead попадают затраты, которые невозможно привязать ни к одному сотруднику с активностью.

  • Management / Admin Salary — месячная зарплата сотрудников с MONTHLY-ставкой, у которых нет никакой зафиксированной активности в отчётном месяце (типично — PM, CTO, HR). Зарплата распределяется пропорционально количеству дней действия ставки внутри месяца.

Non-task время сотрудников, у которых активность есть, в этот пул не попадает — оно уже «впитано» в direct_total через размазывание.

Схема ниже суммирует, как каждый тип затрат добирается до проекта:

Куда попадает каждый тип затрат

3. Метод распределения (Коэффициент накладных расходов)

Overhead распределяется пропорционально объёму прямых затрат по следующей формуле:

:::tip Формула расчёта

K = admin_salary / direct_total

Где:

  • admin_salary — сумма пропорциональных зарплат сотрудников без активности за месяц;
  • direct_total — суммарные прямые затраты департамента (task-mapped активность плюс размазанная non-task часть активных сотрудников).

:::

Ключевые свойства

  • Гранулярность: K рассчитывается по каждому департаменту и каждому месяцу отдельно (обеспечивается unique-constraint department_id + year + month в таблице overhead_coefficient).
  • Произвольные периоды: для диапазонов из нескольких месяцев применяется взвешенное среднее с весом = direct_total соответствующего месяца:
    K_eff = Σ(K_m × direct_total_m) / Σ(direct_total_m)
  • Применение: итоговая стоимость считается помесячно и суммируется:
    total = Σ(direct_m × (1 + K_m))
  • Хранение и пересчёт: значения живут в таблице overhead_coefficient и обновляются двумя cron-джобами — ежемесячным для текущего месяца и полным пересчётом на старте сервиса и первого числа каждого месяца в 03:00.

Фильтры и исключения

  • Деактивированные пользователи (users.is_active = false) исключаются из прямых затрат (bugfix PDM-3369).

  • Неактивные членства в департаменте (user_departments.is_active = false) не учитываются.

  • Флаг overhead warning выставляется, если обнаружены:

    • MONTHLY-ставки выше $50 000 у сотрудников без активности, либо
    • сотрудники с активностью, но без настроенной ставки.

    Оба случая сигнализируют о загрязнении коэффициента K и требуют внимания.

4. Живой пример расчёта

Представим отчётный месяц в департаменте, где велась работа над двумя проектами. Все цифры ниже уже отражают шаг размазывания из §1 — non-task время активных сотрудников уже вложено в прямые затраты каждого проекта:

  • Проект Альфа — прямые затраты (с размазанным non-task): 100 000
  • Проект Бета — прямые затраты (с размазанным non-task): 50 000
  • Зарплата менеджмента без активности (admin_salary): 30 000

То есть direct_total = 150 000.

Шаг 1. Находим коэффициент:

K = 30 000 / 150 000 = 0.2 (20%)

Шаг 2. Применяем:

  • Итоговая стоимость Альфа: 100 000 × (1 + 0.2) = 120 000
  • Итоговая стоимость Бета: 50 000 × (1 + 0.2) = 60 000
примечание

100 000 и 50 000 — это уже «полные» прямые затраты по каждому проекту. Если команда залогировала, скажем, 20 000 non-task времени за период, оно уже пропорционально распределено внутри этих двух цифр, а не добавляется отдельной строкой.

Почему это важно

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


примечание

Данные обновляются автоматически при синхронизации с вашими инструментами разработки.