Ресурсное планирование · analysis

Эталон 5213150; дополнение имеет приоритет. Исторические материалы отмечены отдельно; spec и архитектура утверждены 15.10.2026, рабочие подключения ждут ответов на вопросы.

analysis/addendum-2026-10-13.md

Дополнение от 13.10.2026 — уточнённая редакция

Источник редакции — последний отчёт Аналитика в задача №233. Правила сверены с реализацией 5213150; принята P = FTE × персональная H. Все NEW-01–09 реализованы принятыми пакетами; общая QA и риск-ревью ещё предстоят. Матрица NEW → код → проверка → документ и расчётный контракт описывают фактическую реализацию.

Приоритет. Дополнение от 13.10.2026 (NEW-01–09) главнее противоречащих ему пунктов ТЗ v1.7: §6 «праздники и сокращённые дни пока не учитываются», FR 37/FR 24 «× 8», FR 60 «N = число сотрудников × H», §26 «Nбез = N − V». Главнее оно и допущения от 12.10 «будни × 8», и критериев задача №227 (неизменная «Σ ч») и задача №230 (N/Nбез). Ограничение задача №231 «calc.js как есть» на NEW-03 не распространяется. Не входят в редакцию: интеграции, прогноз больничных, замещение и перенос работ, пересогласование денег, политика исторического пересчёта сервиса.

Правила, выведенные из документов (вопросами к автору не являются)

Правило Источник
Hкал(месяц) — часы производственного календаря РФ для 40-часовой пятидневки. Праздники и переносы исключены, предпраздничный день на 1 ч короче, рабочие субботы по переносу считаются. Праздники повторно не вычитаются DOCX п.3; ТЗ tz.md:14 («праздники и отпуска должны быть учтены»); tz.md:726 («норма часов с праздниками и сокращёнными днями»)
H сотрудника = Hкал − часы отпуска − часы больничного за месяц. Отсутствия вводятся только в рабочих часах (≤ Hкал), день, в который совпали оба вида, учитывается один раз. Больничные не прогнозируются: только введённые значения DOCX п.3; границы задачи
Часы дня в дневном плане: P = Σ(доступные часы дня сотрудника × дневной FTE). «× 8» из FR 37/FR 24 — это частный случай дня по 8 ч FR 34, FR 37 с календарём tz.md:726
N = ΣH выбранных сотрудников. N − V не считается: отпуск уже внутри H. Колонки «без отпусков» объединяются с «по норме», доля каждого вида отсутствия считается от ΣHкал; общую долю считают по объединению дат, не по V + B DOCX п.3; формулы FR 60/§26 при новой H
Пустое значение отсутствия не равно 0. Если у выбранного сотрудника за месяц нет записи об отпуске или больничном, его H, N группы и проценты по N показываются прочерком. ΣHкал («норма по календарю») и явно введённые часы факта остаются видимыми; зависимые плановые часы неизвестны. После ввода 0 значение становится известным. В демо явно заполнены подтверждённые значения, включая нули FR 62, AC 61 (видимая величина — календарная норма, как раньше видимой была N)
Накопительно и за период: сначала сумма часов, сумма норм, затем процент tz.md:41, FR 60, AC 60
Σ в плане: FTE — сумма месячных FTE, % — ΣP / ΣH × 100, часы — ΣP Глоссарий Σ tz.md:32; tz.md:41
«Итог» плана — сумма строк сотрудников (строки проектов — их расшифровка, повторно не прибавляются). По FTE — сумма, по % — ΣP / ΣH. При поиске по проекту строки сотрудников, как и сейчас, показывают полную загрузку, Итог — их сумма DOCX п.6 «суммируются значения по строкам»; текущее поведение plan.js
NEW-08 — плановые часы проектов группы «Коммерческий» (категория или общий тип commercial) / N DOCX п.8 «по форме плановой утилизации»; AC 64; FR 36
NEW-09 — A / N × 100; при неполном факте прочерк, при N = 0 прочерк DOCX п.9; FR 61, AC 62
Финансы: расход = P × C, разница = I − расход. Неизвестная C — прочерк, не 0. Цвета: в форме и карточке отрицательная разница красная, остальное зелёное; в таблицах при отрицательной разнице расход красный, иначе без цвета DOCX п.1, 2, 7; FR 35

Календарь в данных прототипа (часы на 40-часовую неделю)

янв фев мар апр май июн июл авг сен окт ноя дек год
2026 120 152 168 175 151 167 184 168 176 176 159 176 1972
2027 120 151 176 175 152 167 176 176 176 168 159 176 1972

Ловушки реализации:

Принятая формула P и денег

Действующая постановка: P = FTE × H сотрудника после вычета отсутствий; доход = P × R, расход = P × C. Повторного согласования не требуется. При дневных изменениях используется сумма дневного FTE × доступные часы дня, исходные месячные ставки сохраняются. Отдельной нормы продажи нет; новый процесс пересогласования не вводится.

Анна, октябрь 2026: календарь 176 ч, отпуск 16 ч, больничный 0 → H = 160. При 0,5 FTE и R/C = 3500/2800: P = 80 ч, доход 280 000, расход 224 000 ₽, утилизация 50 %. Больничный 8 ч → H = 152, P = 76 ч, доход 266 000, расход 212 800 ₽. Изменение введённых отсутствий меняет расчёты прототипа во всех представлениях.

У назначенного сотрудника пустой отпуск или больничный означает неизвестную H: зависимые P, деньги и проценты — прочерк. Явно введённые фактические часы остаются видимыми. Для строки «На подбор» персональной нормы ещё нет: до назначения используется календарь; после выбора сотрудника расчёт использует его H.

Отпуск/больничный: запись {employee, month, hours} — подтверждённые рабочие часы без пересечений; {employee, month, dates} — полные дни с точным объединением дат. Даты праздников/выходных дают 0 ч, сокращённые — 7 ч. Для сводных часов без дат дневная доступность распределяется пропорционально календарным часам: это допущение демо, точные дни задаются датами. Положительные сводные часы и датированные отсутствия в одном месяце не смешиваются: API просит указать оба отсутствия датами. Пустое поле удаляет запись, 0 или пустой массив дат подтверждают отсутствие. API атомарно отклоняет сумму свыше календаря и неверные даты.

Мок принимает фактический fte либо явные hours (одно из двух). FTE преобразуется через персональную H; явные часы не теряются при неизвестных отсутствиях. При согласовании требуется подтверждённая H назначенных сотрудников; сохранение заявки с неизвестной H допускается. Проверка перегрузки использует рабочие дни, в том числе рабочую субботу, и исключает подтверждённые дни без доступных часов.

Источники календаря, проверенные 13.10.2026: 2026, 2027, постановление №1187. Федеральная пятидневка на 40 ч; региональные календари в демо не включены.

Критерии приёмки

Числа приведены для календаря выше и принятой персональной нормы.

Матрица NEW-01–09

Полная матрица находится в service/docs/addendum-coverage.md; код и проверки — база 5213150. Она связывает все девять NEW, отдельный дефект ЦФО, REQ-008/009/011/018/024/026/027, файлы, unit/browser и документы. Критерии выше сохранены как чек-лист будущей общей QA, а не галочки её завершения.

Фактические значения демо

Октябрь: N = 1040 ч, P = 432 ч, FTE группы = 2,5, коммерческий план = 256 ч → 24,615…%; факт группы неполный. Ноябрь: N = 954 ч, P = A = 477 ч, полный факт → 50 %. Деньги demo-1: 2446550/2388700 ₽; demo-2: 1548700/1246200 ₽; demo-3: 2176900/неизвестный расход. Все представления используют одну персональную H.

Двенадцатинедельное окно не требует нормы 2025: недели, захватывающие дату до 2026, целиком неизвестны. Для января–марта 2026 таких недель 8/4/0. Будущая рабочая интеграция calendar/absence остаётся в Q-06; принятую формулу P и необходимость отпусков/больничных не согласовывают заново. Изменение введённых отсутствий пересчитывает текущие P/деньги демо, новая политика истории рабочего сервиса вне объёма.

analysis/design-base.md

Дизайн-основа прототипа «Ресурсное планирование» в айдентике Лоции

База — brand/brand.md (снято с loodsen.ru). Здесь — как перенести его на плотный рабочий интерфейс ТЗ v1.7. Новые цвета, которых нет в brand.md, перечислены отдельно и названы — других hex в прототипе быть не должно.

1. Переменные

@font-face{font-family:"AeonikPro";src:url("brand/fonts/aeonikpro-regular.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"AeonikPro";src:url("brand/fonts/aeonikpro-medium.woff2") format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:"AeonikPro";src:url("brand/fonts/aeonikpro-semibold.woff2") format("woff2");font-weight:600;font-display:swap}
@font-face{font-family:"AeonikPro";src:url("brand/fonts/aeonikpro-bold.woff2") format("woff2");font-weight:700;font-display:swap}

:root{
  /* бренд — brand.md */
  --brand:#7B37F2;        /* действие, выбранное состояние, ссылка */
  --brand-hover:#B78FFD;
  --brand-soft:#C76BFC;   /* тег, акцент графика */
  --brand-on:#FAF7FE;     /* знак на фиолетовом */
  --ink:#120F18;          /* основной текст */
  --ink-muted:#999799;    /* подписи, единицы — только ≥ 14 px */
  --surface:#FFFFFF;      /* карточки, таблицы, модалки */
  --bg:#F3F1EE;           /* фон приложения, групповые строки */
  --bg-2:#E8E6E3;         /* secondary-кнопки, нейтральный бейдж */
  --line:#DCDAD8;         /* границы, разделители */
  --line-strong:#BDBBBB;  /* неактивное */
  --danger:#E0592E;       /* ошибка, превышение — рамки, иконки, заливка-маркер */
  --dark:#202020;

  /* расширение палитры — новые цвета, утверждаются этой постановкой */
  --brand-tint:#F1EAFE;   /* фон выделенной ячейки / активного фильтра, вместо заливки --brand */
  --ok:#2E7650;           /* успех: текст и иконка */
  --ok-soft:#E4F0E8;      /* успех: фон бейджа */
  --warn:#8A5A00;         /* ожидание/предупреждение: текст и иконка */
  --warn-soft:#F8EDD6;    /* ожидание: фон бейджа */
  --danger-ink:#B23F1A;   /* текст на --danger-soft (у --danger на белом контраст 3,5:1 — мал для 12–14 px) */
  --danger-soft:#FBE7DF;  /* фон строки/блока превышения */

  /* типографика */
  --f-ui:"AeonikPro",Inter,system-ui,sans-serif;
  --fs-xs:12px; --fs-s:14px; --fs-m:16px; --fs-l:20px; --fs-xl:28px; --fs-kpi:35px;

  /* геометрия */
  --r-card:24px; --r-ctl:12px; --r-pill:9999px;
  --h-ctl:40px;  --h-row:44px; --gap:16px;
}

Шрифты подключаются только из brand/fonts/ (коммерческие, наружу не выкладывать). Внешних запросов в прототипе нет: ни Google Fonts (сейчас они есть в iterations-prototype-v1.html), ни CDN.

2. Типографика интерфейса

Элемент Шрифт Размер / начертание Цвет
Заголовок страницы («Ресурсное планирование») AeonikPro 28 / 500 --ink
Надзаголовок режима («РЕСУРСНЫЙ МЕНЕДЖЕР») AeonikPro 12 / 600, uppercase, letter-spacing .04em --ink-muted
Заголовок карточки / таблицы AeonikPro 20 / 500 --ink
Текст, ячейки AeonikPro 14 / 400 --ink
Числа в таблицах и KPI AeonikPro 14 / 500 (KPI 35 / 500), font-variant-numeric: tabular-nums, выравнивание вправо --ink
Шапка таблицы AeonikPro 12 / 500 --ink-muted
Подписи, единицы («FTE», «₽/час», «в пуле») AeonikPro 14 / 400 --ink-muted
Пояснение под таблицей AeonikPro 14 / 400 --ink-muted

PP Right Grotesk в интерфейсе не используется (только плакатные надписи — их в прототипе нет). Числа: тысячи — неразрывный пробел (352 000 ₽), десятичная запятая (0,5 FTE), прочерк — для неизвестного (FR 35); ноль и прочерк визуально различаются.

3. Каркас и шапка

4. Таблица

5. Форма

6. Статусы

Бейдж-пилюля: высота 24, 12/500, padding 0 10 px. Фиолетовый для статусов не используется — он занят действием и выбором.

Заявки (раздел 5, внутренние значения — раздел 29)

Статус value Фон Текст
На согласовании pending --warn-soft --warn
Согласована approved --ok-soft --ok
На доработке returned --bg-2 --ink
Отклонена rejected --danger-soft --danger-ink

Заявка на изменение (kind = change) — тот же статус + серый тег типа («Вывод с 16.11», «Замена с 01.12») фон --bg, текст --ink-muted.

Назначения (раздел 13, FR 21)

Состояние Фон Текст
Действует (изменений нет) — (без бейджа) —
Изменение на согласовании --warn-soft --warn
Участие завершено --bg-2 --ink-muted

Состояние в «Распределении сотрудников» (FR 43)

Состояние Фон Текст
Свободен в плане --bg-2 --ink
Частичная загрузка --warn-soft --warn
Полная загрузка --ok-soft --ok
Перегрузка --danger-soft --danger-ink

«Нет полного факта» (FR 49) — текст --ink-muted курсивом, без заливки: это отсутствие данных, а не ошибка.

7. Превышение расходов (раздел 6, FR 13, FR 41)

8. Графики (раздел 17)

9. Исторический образец design-sample.html (v1.7)

Собран: analysis/design-sample.html, скриншот analysis/design-sample.png. Шрифты — ../brand/fonts/, знак — ../brand/favicon.svg. Состав — экран «Заявки» режима ресурсного менеджера из media/image3.png в новой айдентике:

Проверка: grep -oiE '#[0-9a-f]{6}' analysis/design-sample.html | sort -u даёт только цвета из §1; в DevTools → Network нет запросов, кроме brand/fonts/*.

Дополнение 13.10 к §7: финансы заявки

Под «Плановым доходом за период» — строки «Плановый расход за период» и «Разница». Отрицательная разница — --danger-ink, нулевая и положительная — существующий токен --ok (зелёный). В месячной таблице и списке заявок «Расход» сразу после «Доход», при I − расход < 0 — .cell.loss, иначе без цвета. Неизвестная C — прочерк без цвета. Формулы: расход = P × C, разница = I − расход; P = FTE × персональная H по принятому дополнению; неизвестная H делает зависимые часы/деньги неизвестными. Календарная Hкал отображается отдельно, повторного вычета отпуска нет. Суммы образца §9 исторические; действующие примеры — addendum-2026-10-13.md.

Редакция реализации

Сверено с 5213150. В форме отсутствий рядом с отпуском больничный и персональная H, запись — часы либо полные dates. Пусто удаляет запись, 0 подтверждает отсутствие. Сводные часы распределяются пропорционально календарю; пересечения требуют дат обоих видов. Подробности и границы — расчётный контракт. Общая QA всех NEW ещё предстоит.

analysis/design-sample-history.md

design-sample.html и design-sample.png — исторические образцы по ТЗ v1.7; заменены задача №231 и addendum-2026-10-13.md. Исходное изображение не переписано.

analysis/gap.md

История: содержание ниже фиксирует старую редакцию и результаты на её дату, не действующие формулы и не новую приёмку. Приоритет у дополнения 13.10, контракта и матрицы 5213150. Старые пакеты не возобновляются; общая QA всех NEW ещё предстоит.

Исторический документ по ТЗ v1.7; заменён задача №231 и addendum-2026-10-13.md.

Матрица покрытия ТЗ v1.7 ↔ прототип

Источник строк — все заголовки tz-v1.7/tz.md (grep -c '^#' = 79), строка матрицы = заголовок, 1:1, заголовки «Макет …» оставлены отдельными строками (79 строк).

Колонки:

Главный вывод: «Итерации» — другой продукт (задачи, итерации, оценки в часах, синк со Сферой). С ТЗ пересекаются только норма месяца, FTE по месяцам, отпуска и тепловая карта загрузки. Всё, что описано в ТЗ, уже реализовано в Базовой версии — ТЗ описывает её как есть.

# Раздел ТЗ Требование кратко Итерации База Что сделать Размер Пакет
1 ## 1 Обозначения в формулах H, P, R, C, I, Δ, Rср, Cср; H = будни × 8 частично: норма месяца есть (workdays, с праздниками HOL), ставок нет да Общий расчётный модуль calc (H, P, I, Δ, средневзвешенные ставки), все экраны берут формулы только из него M П1
2 ## Обозначения норм факта и математических операций A, N, V, Nбез, накопительные суммы частично: отпуска периодами дат, факта нет да Добавить в calc A, N, V, Nбез, накопительный процент (сумма часов / сумма норм) S П1
3 ### Единые названия показателей Словарь названий; план и факт раздельно нет частично (в UI ещё «Аллокация», «Списано») Словарь подписей одной константой; на экранах — полные названия из словаря S П1
4 ### 2 Назначение и границы РП запрашивает, РМ назначает; граница прототипа нет да Плашка «Демонстрационные данные · Bitrix24 не подключён» в шапке S П1
5 ### 3 Участники Демо-режимы РМ / РП, выбор РП вручную нет (роли команды lead/member/viewer) да Переключатель «Ресурсный менеджер / Руководитель проекта» + выбор РП и проекта S П1
6 ## 4 Создание заявки на ресурсы FR 01–04: форма, строки ресурсов, помесячные FTE, ставки нет да Модалка «Новая заявка»: проект, РП, период 1–12 мес., строки ролей, желаемый сотрудник, доходная ставка, FTE по месяцам, валидация L П2
7 ### Макет создания заявки media/image1.png нет да Входит в строку 6 — П2
8 ## 5 Согласование и статусы FR 05, переходы статусов нет да Карточка рассмотрения, действия Согласовать / На доработку / Отклонить, «Создать исправленную заявку» L П2
9 ### Проверки согласования FR 06–10: сотрудник обязателен, загрузка ≤ 1 FTE по дням, подтверждение превышения, причина нет да Проверки в мок-слое; проверка по дням через calc M П2
10 ### Сохранение решения Сохранение назначений, lossAccepted; FR 11 нет да Мок-слой сохраняет решение, план пересчитывается; при ошибке форма не закрывается S П2
11 ### Макет согласования заявки media/image2.png нет да Входит в 8–9 — П2
12 ### Макет списка заявок media/image3.png: список, фильтр статуса нет да Вкладка «Заявки»: проект и РП, период, доход, статус, «Рассмотреть» / «Открыть» M П2
13 ## 6 Ставки и финансовые расчёты FR 12: ставки рядом, месячная таблица нет да Блок ставок и месячная таблица в форме и карточке M П3
14 ### Подсветка превышения расходов FR 13: красный, «Выше доходной», Δ и сумма нет да Компонент «превышение» по design-base.md S П3
15 ### Совместимость и округление Усреднение старых помесячных ставок, округление нет да Одна демо-заявка в старом формате + уведомление об усреднении; форматтеры ₽/ч/FTE S П3
16 ## 7 Ресурсный план и режим руководителя проекта FR 14–15: сотрудник → проекты, План/Факт, 6 месяцев, FTE/ч/% частично: «Загрузка» — тепловая карта сотрудник × месяц, «Ресурсы и отпуска» — FTE × 6 месяцев; без раскрытия по проектам и без План/Факт да Таблица плана с раскрытием, Σ ч, выбор месяца, единицы, поиск L П4
17 ### Ресурсный менеджер KPI: сотрудники, загрузка, на согласовании, свободный ресурс нет да Четыре KPI-карточки S П4
18 ### Руководитель проекта FR 16: выбор РП и проекта, только его назначения нет да Фильтр области РП во всех вычислениях (одна функция scope) M П4
19 ### Фильтр свободных ресурсов FR 17–18: клик по KPI, < 1 FTE; факт — прочерк нет да Фильтр по клику, подпись, «Сбросить фильтр» S П4
20 ### Макет ресурсного плана менеджера media/image4.png частично (тепловая карта) да Входит в 16–19 — П4
21 ### Макет загрузки проектов руководителя media/image5.png нет да Входит в 18 — П4
22 ## 13 Изменение и завершение назначений Изменение через отдельное согласование нет да Вкладка «Назначения» M П5
23 ### Доступ к назначениям FR 20–21: кнопка «Изменить назначения», список, состояния нет да Список назначений, блокировка кнопок, «Участие завершено» M П5
24 ### Типы изменения Вывод / уменьшение / замена нет да Режимы release / reduce / replace в calc по дням M П5
25 ### Обязательные сведения FR 22–23: дата ≥ сегодня (МСК), причина, FTE нет да Валидация формы изменения S П5
26 ### Макет списка назначений media/image6.png нет да Входит в 23 — П5
27 ### Макет запроса изменения media/image7.png нет да Входит в 24–25 — П5
28 ## 14 Пересчёт и согласование изменения Раздел-контейнер нет да — — П5
29 ### Предварительный расчёт FR 24: текущий / новый FTE, дневные значения нет да Превью нового плана; Month.days M П5
30 ### Жизненный цикл FR 25–28: kind = change, решение, «Исправить и отправить» нет да Заявка-изменение в списке заявок, решение, применение к исходной строке M П5
31 ### Проверки решения и ставок FR 29–30: снимок, revision, загрузка по дням, allowLoss нет да Проверки в мок-слое S П5
32 ### Макет согласования изменения media/image8.png нет да Входит в 30–31 — П5
33 ## 15 История и данные изменения назначения Раздел-контейнер нет да — — П5
34 ### История согласованных изменений FR 31: history before/after в карточке нет да Блок «История изменений» в карточке заявки S П5
35 ### Пример запроса изменения Формат action: change нет да Мок-слой принимает этот формат буквально S П8
36 ### Границы текущей реализации Демо-роли, одно ограничение FTE нет да Только учесть; реализации не требует — —
37 ## 16 Отчётность: общие правила Вкладки «Отчёты», «Некоммерческие», «Статистика» нет да Навигация отчётов S П6
38 ### Область просмотра и исходные данные FR 32–35: только approved, days приоритетнее, прочерк ≠ 0 нет да Общий отбор назначений для отчётов в calc S П6
39 ## 17 Отчёт по утилизации сотрудников FR 36: фильтры, KPI, 12 недель, кольцо, сравнение, таблица частично: «Ёмкость и загрузка» — полосы load / capacity по людям да Экран «Утилизация»: KPI, линейный график 12 недель, кольцо, горизонтальные бары, таблица L П6
40 ### Формулы FR 37 частично: другая формула (ёмкость минус отпуск) да Формулы из calc S П6
41 ### Особенности области РП и выгрузка FR 38: CSV UTF-8 BOM, «;», русская локаль нет (выгрузка Excel реестра задач) да Общий экспорт CSV (одна функция на все отчёты) S П6
42 ### Макет отчёта по утилизации сотрудников media/image9.png нет да Входит в 39 — П6
43 ## 18 Финансы по сотрудникам FR 39: KPI, строки сотрудников и назначений нет да Отчёт «Финансы по сотрудникам» с раскрытием M П6
44 ### Расчёт и предупреждения FR 40–41: средневзвешенные ставки, красные строки, счётчик нет да Через calc + компонент превышения S П6
45 ### Область просмотра и CSV CSV по назначениям нет да Через общий CSV S П6
46 ### Макет финансового отчёта по сотрудникам media/image10.png нет да Входит в 43–45 — П6
47 ## 19 Распределение сотрудников по проектам FR 42: строка сотрудника + блоки проектов нет да Отчёт «Распределение сотрудников» M П6
48 ### Плановая утилизация на проекте состояние и дата FR 43–45: состояние, дата освобождения, CSV нет да Состояния (цвета в design-base.md), дата освобождения по всему плану S П6
49 ### Макет распределения сотрудников по проектам media/image11.png нет да Входит в 47–48 — П6
50 ## 20 Некоммерческие проекты: план и факт FTE FR 46: две таблицы, группировка по подразделениям нет да Вкладка «Некоммерческие проекты», синхронное раскрытие M П7
51 ### Плановые и фактические значения FR 47–49: «Нет полного факта» нет да Правила полноты факта в calc S П7
52 ### Макет плановой и фактической загрузки некоммерческих проектов media/image12.png нет да Входит в 50–51 — П7
53 ## 21 Статистика численности сотрудников FR 50: шесть сводных таблиц нет (в «Команде» — подразделения Сферы при заведении) да Вкладка «Статистика» M П7
54 ### Фильтры и состав выборки FR 51–53: уникальные сотрудники, «Не указано» нет да Фильтры и KPI S П7
55 ### Макет статистики по должностям и подразделениям media/image13.png нет да Входит в 53 — П7
56 ### Макет статистики по навыкам и категориям ставок media/image14.png нет да Входит в 53 — П7
57 ### Макет статистики по дате выхода проектам и ЦФО media/image15.png нет да Входит в 53 — П7
58 ## 22 Настройка данных отчётности и сохранение FR 54–55: «Настроить данные / ввести факт», «Данные сотрудников» частично: «Ресурсы и отпуска» — ручной ввод FTE и отпусков в таблице да Две модалки ввода reportData; в режиме РП скрыты M П7
59 ### Контракт и совместимость FR 56–57: action report-data, 400 / 409 нет да Мок-слой: валидация reportData, revision S П8
60 ## 23 Приёмочные сценарии новых отчётов AC 41–48 нет да (данные демо) Демо-данные, на которых воспроизводятся AC 41–48 S П6
61 ## 24 Приёмка некоммерческой отчётности и статистики AC 49–58 нет да Демо-данные под AC 49–58 S П7
62 ## 25 Утилизация по типам проектов: норма, план и факт FR 58: две таблицы, два периода нет да Таблицы «Плановая / Фактическая утилизация по типам проектов» под «Утилизацией» L П7
63 ### Тип проекта и подразделение FR 59: projectCategories приоритетнее projectTypes нет да Классификация в calc S П7
64 ### Макет плановой утилизации по типам проектов media/image16.png нет да Входит в 62 — П7
65 ### Макет фактической утилизации по типам проектов media/image17.png нет да Входит в 62 — П7
66 ## 26 Формулы, фактические часы и отпуска FR 60: N, A, V, Nбез, накопительно частично: отпуска есть, но датами, а не часами за месяц да Отпуск — часы на сотрудника и месяц (vacations) M П7
67 ### Полнота данных и ручной ввод FR 61–63: «Типы проектов, факт и отпуска» нет да Модалка ввода; actuals.fte = часы / H M П7
68 ## 27 Данные и приёмка таблиц утилизации FR 64, AC 59–66 нет да Валидация vacations / projectCategories в мок-слое, демо-данные под AC S П7
69 ## 28 Данные и хранение Сотрудник, Проект, RequestItem, Line, Month, State частично: данные в JSON-блоке страницы + localStorage, модель другая да Модель State в мок-слое M П8
70 ### Хранилище D1 planning_state, revision; FR 19 нет да В прототипе — localStorage + revision; «Сбросить демо-данные» S П8
71 ### Расходная ставка при согласовании costRate только из справочника, снимок нет да Мок-слой игнорирует costRate клиента S П8
72 ## 29 Техническая архитектура и интерфейс API GET / POST /api/planning, 503 / 409 / 400 нет да Мок-функция api(action, payload) с теми же кодами ошибок M П8
73 ### Статусы и обязательность pending / approved / returned / rejected нет да Константы статусов + цвета S П1
74 ### Контракт действий create / approve / return / reject / change нет да Мок-слой — П8
75 ### Пример строки новой заявки JSON строки нет да Демо-данные в этом формате — П8
76 ### Границы текущего API Нет прав; «данные из Сферы: Bitrix 24» нет да Только учесть — —
77 ## 30 Интеграции и требования к рабочему контуру Bitrix24 не подключён частично: синтетический синк со Сферой, OAuth-экран входа частично: плашка «Bitrix24 · подключение не настроено» Плашка в шапке; интеграция — вне этапа 2 S П1
78 ### Условия интеграции с Bitrix24 INT 01–04 частично: в задача №215 описан SphereClient (люди, подразделения, группы) нет Вне этапа 2; переиспользовать SphereClient из задача №215 при рабочей реализации — —
79 ### Рабочие права и надёжность NFR 01–03 нет нет Вне этапа 2 — —

Сводка

Покрытие Итерации База (предварительно, статически)
да 0 75
частично 11 2
нет 68 2

Строки «частично» в Итерациях: 1, 2, 16, 20, 39, 40, 58, 66, 69, 77, 78 — все про норму, FTE, отпуска, загрузку и Сферу; доменной модели «заявка → назначение» там нет. В Базе «частично» — словарь показателей (3) и интеграция (77), «нет» — Bitrix24 и рабочие права (78–79), что ТЗ само относит к отдельной доработке.

analysis/plan.md

История: содержание ниже фиксирует старую редакцию и результаты на её дату, не действующие формулы и не новую приёмку. Приоритет у дополнения 13.10, контракта и матрицы 5213150. Старые пакеты не возобновляются; общая QA всех NEW ещё предстоит.

Исторический документ по ТЗ v1.7; заменён задача №231 и addendum-2026-10-13.md.

Постановка этапа 2: прототип «Ресурсное планирование» в айдентике Лоции

Номера разделов — по заголовкам tz.md (словарь сдвинутых ссылок — tz-issues.md, А3). Покрытие по строкам — gap.md, цвета и компоненты — design-base.md.

Решение: новый прототип, а не доработка iterations-prototype-v1.html

Рекомендация — собрать новый прототип. Причины:

  1. В «Итерациях» нет ни одного раздела ТЗ, закрытого полностью: 0 «да», 11 «частично», 68 «нет» из 79. Пересечение — только норма месяца, FTE по месяцам, отпуска и тепловая карта загрузки.
  2. Модели данных несовместимы: там задача → итерация → оценка в часах по людям; в ТЗ заявка → строка ресурса → помесячный FTE → назначение со ставками. Доработка = замена модели, всех шести вкладок и данных, то есть та же новая сборка, только с лишним кодом.
  3. «Итерации» — результат задача №215 со своей постановкой (Сфера, команды, стек Nuxt). Переделка под ресурсное планирование ломает этот артефакт.
  4. Эталон поведения уже есть — Базовая версия: по предварительной статической сверке 75 из 79 строк «да» (поведение экранов не проверялось). Новый прототип повторяет её поведение в айдентике Лоции, а не изобретает его.

Из «Итераций» переносим приёмы, а не код целиком: workdays() (рабочие дни, при необходимости с праздниками), тепловую раскраску ячеек загрузки, липкие шапки таблиц, формат «один HTML + JSON-данные + localStorage», публикацию на stand.

Развилка — допущение до решения автора (tz-issues.md, В1; одобрение плана — в задача №221): если доступен исходный код Базовой версии (React / TypeScript / Vinext / Radix / Shadcn), дешевле перекрасить её по design-base.md — пакеты П2–П7 тогда сводятся к рестайлингу (S–M вместо M–L). План ниже исходит из того, что кода нет.

Форма прототипа

Пакеты

Порядок: П1 → П8 → П2 → П3 → П4 → П5 → П6 → П7. П8 идёт вторым: мок-слой и расчёты нужны всем экранам. После П8 пакеты П6 и П7 можно делать параллельно с П4–П5 (зависят только от П1, П8 и демо-данных).

Исполнитель везде — Фронтенд (бэкенда нет: API — мок в браузере).

П1. Каркас, навигация, айдентика — S/M

П8. Данные, расчёты и мок API — M/L

П2. Заявки и согласование — L

П3. Ставки и финансовые расчёты в заявке — M

П4. Ресурсный план и режим РП — L

П5. Изменение назначений — L

П6. Отчёты 16–19 — L

П7. Некоммерческие проекты, статистика, утилизация по типам — L

Вне этапа 2

Интеграция с Bitrix24 / Сферой, производственный календарь из 1С, авторизация и серверные права (раздел 30, INT 01–04, NFR 01–03). Для будущей интеграции переиспользовать SphereClient из постановки задача №215.

Оценка

П1 S/M, П8 M/L, П2 L, П3 M, П4 L, П5 L, П6 L, П7 L. Узкое место — П8: ошибки в calc размножаются по всем отчётам, поэтому его приёмка — числовые примеры ТЗ до начала экранов.

analysis/requirements-audit-2026-10-13.md

История: содержание ниже фиксирует старую редакцию и результаты на её дату, не действующие формулы и не новую приёмку. Приоритет у дополнения 13.10, контракта и матрицы 5213150. Старые пакеты не возобновляются; общая QA всех NEW ещё предстоит.

Сверка ресурсного планирования с дополнением от 13.10.2026

Проверены все 12 постановок проекта задача №221–232 (задача №225–230 отменены), ключевые отчёты и решения в комментариях, ТЗ v1.7, analysis/gap.md, plan.md, tz-issues.md, design-base.md и образец, исходники prototype-v2, документы service/docs и прежние отчёты проверки. Исторические скриншоты и PDF сравнений отражают v1.7 и не являются приёмкой дополнения. Архивы опубликованных результатов остаются историческими копиями, а не актуализированными спецификациями.

Источник дополнения: «Требования к ресурсному планированию.docx», attachment 01a13501-b19d-7a25-92c0-8e8f2651a9d6. SHA-256 a96b9eababa88bdf000c2db14162984b909440e0b8693716a070d7aaeaebec27. Он побайтово совпадает с вложением задача №232 01a13446-14ce-7d44-8dff-3fceba42c110. В опубликованной спецификации дополнение не отражено.

Причина

Базой постановок и приёмки оставалась v1.7 с одобренным 12 октября допущением «будни × 8 без праздников». Дополнение 13 октября меняет эту базу, но не было перенесено в спецификацию, словарь, расчётные контракты и критерии. Успешные проверки старых примеров поэтому не доказывают соответствие новым требованиям.

Девять изменений и затронутые места

ID Новое требование Текущее расхождение Где исправлять / как принимать
NEW-01 Под доходом заявки показать расход за период и разницу, отрицательную красным, неотрицательную зелёным В форме и карточке только доход request-modals.js formTotal и оба render; spec REQ-009, design-base §7. При 88 ч, R=4000, C=4300: доход 352000, расход 378400, разница −26400 красная; при R=C разница 0 зелёная. Неизвестная C → прочерк, не ноль
NEW-02 Расход после дохода в помесячной таблице FTE; отрицательная разница красным, иначе без цвета Есть расходная ставка, но нет суммы расхода request-modals.js lineCard. Для каждого месяца расход=P×C; при I−расход<0 выделение, равенство без выделения
NEW-03 Норма сотрудника = норма месяца − праздники − отпуск − больничный; поменять везде normHours(month) общий для всех; отпуска вычитаются отдельно; больничных нет calc.js, api.js report-data, seed.js, data-modals.js, ui.js glossary, план/отчёты, README, tests/data.test.js; ТЗ §1/6/14/16/26/30; analysis Б1; spec REQ-008/018/024/026/027, CONTEXT, architecture, data-flows F4, Q-06, testing/tasks
NEW-04 Статистику и некоммерческие проекты перенести внутрь Отчётов после Распределения Две самостоятельные верхние вкладки ui.js tabs, app.js маршрутизация действий/состояния, reports.js, views/index.js; design-base §3, образец, plan/gap; тест переключения всех шести верхних вкладок устарел
NEW-05 Σ в плане меняет единицу вместе с фильтром Σ ч жёстко задана, суммы всегда в часах plan.js text.total и суммы сотрудников/проектов; задача №227 прямо требует, чтобы Σ ч не менялась — критерий отменён дополнением
NEW-06 Нижняя строка Итог в ресурсном плане Итоговой строки нет plan.js. Суммировать сотрудников один раз, не добавлять повторно дочерние проекты. При сворачивании итог неизменен; фильтры РП/проекта/поиска соблюдены
NEW-07 Расход после Дохода в списке заявок, отрицательная разница красным В requests.js только requestIncome requests.js и shared.js, spec REQ-009, design-sample. Итог расхода неизвестен при неизвестной ставке; одинаковая финансовая модель списка и карточки
NEW-08 Процент утилизации коммерческих проектов в форме плановой утилизации Отдельного кольца/карточки нет; таблица по типам не заменяет показатель reports.js renderUtilization; spec REQ-018, tasks П6. Числитель только коммерческий план, знаменатель той же выбранной группы, одинаковые фильтры
NEW-09 Фактическая утилизация в форме плановой Есть таблица факта по типам, но нет аналогичного показателя рядом с плановым reports.js, REQ-013/018/026/027. Полный факт → A/N×100; неполный → прочерк с пояснением; нулевой знаменатель не даёт Infinity

Расчётные вопросы, которые нельзя скрыть правкой подписей

  1. Развести календарную норму Hcalendar и доступную норму сотрудника Hemployee. Если производственный календарь уже исключает праздники, повторно вычитать их нельзя. Отпуск и больничный считать по рабочим часам и без двойного учёта пересечений.
  2. Норма группы теперь ΣHemployee, а не число людей×одинаковая H. Старое Nбез=N−V после нового определения N вычитает отпуск повторно. Предложение: основная утилизация использует доступную норму; старые колонки «без отпусков» удалить либо явно переопределить относительно календарной нормы после решения заказчика.
  3. Определить, пересчитываются ли утверждённые часы/доход/расход при получении больничного или сохраняется версия согласованного плана. Нужны версия календаря и отсутствий, политика прошлых периодов. Это касается ADR-0006, согласования и аудита.
  4. Σ FTE за несколько месяцев — сумма месячных FTE (единица фактически FTE-месяц) или средняя загрузка периода? DOCX требует смену единицы, но не определяет агрегацию. Аналогично сумма процентов за шесть месяцев не равна проценту загрузки периода. Рекомендация: явно подписанная сумма FTE-месяцев и взвешенный процент периода; решение за автором.
  5. NEW-08 не уточняет плановый или фактический коммерческий числитель. Рекомендация: плановый, поскольку запрошена форма плановой утилизации; название должно это показывать.
  6. При поиске проекта итог плана должен соответствовать показанным проектам: текущий planRows хранит row.all отдельно от row.lines, что требует отдельного решения/исправления при добавлении итогов.

Постановки и артефакты

Выполненные визуальные исправления

styles.css: зарезервировано 40 px под собственную стрелку select; устранено сжатие переключателя режима; добавлены переносы шапки, действий и итогов формы на узких экранах; min-width:0 у карточек устраняет переполнение «Статистики» на 320 px. Палитра и нативная работа select сохранены.

Это изменение только отображения. NEW-01–09 в функциональность прототипа ещё не внесены. Архитектурные документы и постановки этим отчётом не объявляются исправленными.

Чтобы не повторилось

В начале следующей реализации зафиксировать одну ревизию источников: v1.7 + дополнение NEW-01–09 + решения по расчётным вопросам. Привязать каждый критерий к файлам и проверкам. Старые отчёты приёмки явно помечать версией требований; не утверждать архитектуру только по наличию ID и рендеру схем.

Проверка и доставка

analysis/tz-issues.md

Дыры и противоречия ТЗ v1.7

Ссылки — tz-v1.7/tz.md:строка. У каждого пункта есть допущение для этапа 2: работа не ждёт ответа заказчика. Пункты с пометкой вопрос уходят заказчику.

А. Нумерация и перекрёстные ссылки

А1. Нет разделов 8–12. После ## 7 (tz.md:204) сразу идёт ## 13 (tz.md:252). Почти все ссылки в тексте сдвинуты ровно на +5 (см. А3) — значит, из документа вырезали пять разделов, а ссылки не перенумеровали. По ссылкам AC 05–AC 10 (tz.md:159), AC 14–AC 15 (tz.md:248) и «раздел 9» (tz.md:349) видно, что там, вероятно, были приёмочные сценарии AC 01–40 и описание API/кодов ответа. Допущение: нумерацию разделов не меняем, ссылаемся на неё как есть. Вместо AC 01–40 приёмку для разделов 4–7 и 13–15 выводим из FR (в plan.md она расписана по пакетам). Вопрос: прислать разделы 8–12 или подтвердить, что их удалили намеренно.

А2. Ссылки на несуществующие разделы 31 и 32. «Подробные правила отсутствующих данных — в разделах 25 и 31» (tz.md:41); «нормы часов … по типам проектов — в разделах 30–32» (tz.md:67). Последний раздел — 30 (tz.md:716). Допущение: сдвиг +5 → правила отсутствующих данных — разделы 20 и 26 (FR 48–49, FR 61–62); нормы и часы по типам проектов — разделы 25–27.

А3. Систематический сдвиг ссылок на +5.

Место В тексте По содержанию
tz.md:67 отчётность — разделы 21–29 16–24
tz.md:67 по типам проектов — 30–32 25–27
tz.md:67 макеты отчётов — 22–26 и 30 17–21 и 25
tz.md:228, tz.md:353 ручной факт — раздел 25 20 (и 22)
tz.md:232 вкладка «Назначения» — раздел 18 13
tz.md:349 статусы и коды ответа — раздел 9 29 (раздела 9 нет)
tz.md:669, tz.md:690 reportData — раздел 27 22 и 27 (оба описывают reportData)

Ссылки на раздел 13 (tz.md:149, tz.md:666) уже в новой нумерации — документ смешанный. Допущение: в постановке этапа 2 ссылаемся по фактическим номерам заголовков; таблица выше — словарь перевода.

А4. Разные уровни заголовков у разделов одного уровня. «2 Назначение и границы» и «3 Участники» — ### (tz.md:69, tz.md:81), остальные разделы — ##; второй раздел «Обозначения норм факта…» (tz.md:23) без номера. Допущение: считаем 2 и 3 самостоятельными разделами, «Обозначения норм факта» — частью раздела 1.

А5. Номер FR 19 стоит в разделе 28 (tz.md:675), между FR 18 (раздел 7) и FR 20 (раздел 13) — ещё один след перестановки разделов. На смысл не влияет.

Б. Противоречия по существу

Б1. Праздники в норме часов H. Раздел 1: «Праздники и отпуска должны быть учтены. Данные можно брать из API 1С» (tz.md:14). Разделы 6, 14, 16, 30: «праздники и сокращённые дни пока не учитываются», календарь — отдельная доработка (tz.md:183, tz.md:300, tz.md:377, tz.md:726). Отпуска в H тоже не входят — они вычитаются отдельно как V (tz.md:29–30). Решено дополнением 13.10 (NEW-03): H = производственный календарь (праздники, переносы, сокращённые дни) − отпуск − больничный; см. редакцию дополнения. Допущение 12.10 «будни × 8» отменено для целевой модели; P = FTE × персональная H, доход = P × R, расход = P × C. Норма группы — сумма персональных H; отсутствие повторно не вычитается. NEW-03 реализован в 5213150 вместе с остальными NEW; повторного согласования формулы не требуется.

Б2. Источник данных: Сфера/Bitrix24 или 1С. tz.md:714 — оборванная фраза «Данные должны браться из Сферы: Bitrix 24»; tz.md:14 — 1С для нормы; в таблице интеграций у фактических часов статус «Time» (tz.md:725) — непонятно, система это (Time-трекер?) или опечатка. Допущение: этап 2 — только мок-данные, интеграций нет. Вопрос: что такое «Time» в строке «Фактические часы»?

Б3. ЦФО и подразделение в «Распределении сотрудников». FR 42 и tz.md:446: ЦФО и подразделение в этом отчёте показываются прочерком. Но FR 55 (tz.md:540) уже позволяет заполнить и ЦФО, и подразделение, а «Статистика» их использует (FR 51). Допущение: в новом прототипе «Распределение» берёт ЦФО и подразделение из employeeStats / departments, а прочерк выводит только при пустом значении. Это принятое отклонение по решению автора от 12.10; реализовано отдельно от NEW и проверяется в Распределении/CSV. Повторного подтверждения не требуется.

Б4. Таблица границ дублирует строку. «Получение справочников из Bitrix24» дважды (tz.md:75–76), а напротив «Единой доходной ставки…» по смыслу ожидалось что-то про ставки (источник расходных ставок, tz.md:724). Допущение: правая колонка второй строки — «Источник расходных ставок».

Б5. Ограничения FTE разные в разных местах: заявка — 0…1 (tz.md:104); факт — 0…2 (tz.md:546); в «Распределении» есть состояние «Перегрузка» > 100% (tz.md:453), хотя согласование запрещает > 1 FTE в день (FR 07). Это не ошибка: перегрузка возможна на старых данных или при сравнении месячного среднего. Но в ТЗ это не объяснено. Допущение: «Перегрузку» показываем и в демо-данных воспроизводим одной старой заявкой.

Б6. Период заявки: в форме 1–12 месяцев, на сервере 1–24 (tz.md:99, tz.md:107). Допущение: в моке валидируем 1–24 (как сервер), форма ограничивает 12.

Б7. Плановая утилизация по норме описана двумя формулами: «FTE × 100%» (tz.md:189) и «P / H × 100%» (tz.md:55). При дневных изменениях первая не определена (FTE месяца — усреднение). Допущение: везде P / H × 100%.

Б8. Два разных допуска сравнения: 0,00001 FTE для проверки загрузки (tz.md:139) и 0,001 п.п. для состояний (tz.md:453). Допущение: оба — константы в расчётном модуле, как в ТЗ.

Действующая матрица дополнения описывает фактическое покрытие 5213150; старые расхождения исходного v1.7 ниже исторические. Общая QA ещё предстоит.

В. Чего в ТЗ нет

В1. ТЗ описывает систему «как есть», а не цель доработки. Первая строка: «зафиксировать функции разработанного веб-прототипа» (tz.md:5); Базовая версия реализует его почти целиком (gap.md, колонка «База»). Из ТЗ не следует, что меняется на этапе 2, кроме айдентики. Допущение: этап 2 = тот же функционал в айдентике Лоции, отдельный прототип. Вопрос (главный): цель — перекрасить Базовую версию, повторить её в нашем прототипе или развивать функционал дальше? И доступен ли исходный код Базовой версии (React/Vinext/Cloudflare, tz.md:685)?

В2. Базовая версия: стенд жив, но данные старые. https://resource-planning-center.jammyglade1.chatgpt.site открывается (12.10.2026, HTTP 200). GET /api/planning отдаёт revision: 1 без reportData, ставки в демо-заявках лежат помесячно (старый формат, раздел 6 «Совместимость»). При этом в интерфейсе есть всё из v1.7: «Назначения», «Изменить назначение», отчёты, «Некоммерческие проекты», «Статистика», «Типы проектов, факт и отпуска», CSV. Брендинг — «РЕСУРСЫ · Центр планирования», иконки lucide, айдентики Лоции нет. Сценарии не прокликивались: сверка — по строкам интерфейса в бандле. Допущение: Базовая версия — эталон поведения для этапа 2.

В3. Нет приёмки AC 01–40 — см. А1.

В4. Не заданы демо-данные. Макеты используют пул из шести человек (Анна Соколова, Михаил Волков…), три проекта, РП Мария Петрова и Алексей Смирнов — те же, что в API Базовой версии. Реальных людей и ставок нет и быть не должно (tz.md:714). Допущение: демо-данные этапа 2 = состояние Базовой версии + дополнения под AC 41–66.

В5. Нет ролей, кроме шести (tz.md:100). В «Итерациях» и в реальной команде СТТ есть ещё РП, дизайнер, DevOps. Допущение: оставляем шесть ролей ТЗ.