From 76f9a1ccfa64077f6a18970fb6aa4dcb1bb4817d Mon Sep 17 00:00:00 2001 From: Roman Chesnokov Date: Wed, 13 May 2026 19:42:17 +0500 Subject: [PATCH] Initial spec: MVP-1 workload + drafts for MVP-2/3/4 + Subsystem D --- .gitignore | 23 + README.md | 67 +++ .../specs/2026-05-13-mvp1-workload-design.md | 479 ++++++++++++++++++ .../specs/2026-05-13-mvp2-deadlines-design.md | 104 ++++ .../specs/2026-05-13-mvp3-finance-design.md | 93 ++++ .../specs/2026-05-13-mvp4-finrez-design.md | 111 ++++ ...026-05-13-subsystem-d-competence-design.md | 102 ++++ 7 files changed, 979 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/superpowers/specs/2026-05-13-mvp1-workload-design.md create mode 100644 docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md create mode 100644 docs/superpowers/specs/2026-05-13-mvp3-finance-design.md create mode 100644 docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md create mode 100644 docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fdeffdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# XML-выгрузки источников (не код проекта — внешние данные) +bitra/ +finrez_1c/ + +# Секреты +.env +.env.local +*.secret + +# Backups +*.sql.gz +backups/ + +# OS / IDE +.DS_Store +Thumbs.db +.vscode/ +.idea/ +*.swp + +# Temp +*.tmp +.tmp/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..6aff04d --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# bit-flight-deck + +Система учёта рабочего времени сотрудников и контроля проектов для проектного отдела. + +## Контекст + +Инициатива объединяет данные четырёх систем-источников в единое read-only аналитическое хранилище для ответов на главные вопросы руководителя проектного отдела: + +- Кто из сотрудников сейчас загружен коммерческими работами? +- Какие задачи подвисают и тормозят следующие работы? +- В каком состоянии проекты по срокам, марже, НЗП, актированию? +- Какой финрезультат у каждого подразделения? + +## Системы-источники + +| Система | Что в ней мастер | Транспорт | +|---|---|---| +| **BIT.RA** (1С на BSP) | Часы, классификация работ, проектная финансовая аналитика, справочник сотрудников | HTTP-сервисы 1С (одноразовая разработка) | +| **EVA Desk** | Задачи разработчиков/PM, Service Desk, история смены статусов | JSON-RPC pull + глобальный админ-токен | +| **Битрикс24** | Сделки и прогноз продаж, оргструктура | Outbound webhooks через CF Tunnel + nightly reconcile | +| **finrez_1c** (самописная 1С) | Месячный финрез по подразделениям (ручной ввод) | HTTP-сервисы 1С (отложено до MVP-4) | + +## Архитектура + +PostgreSQL + N8N + Metabase + NocoDB. Используется существующая инфра в `~/infrastructure/`: +- `pipeline_postgres` (PG 15) — создаём отдельную БД `bit_flight_deck`. +- `n8n` — оркестратор, workflows в существующем контейнере. +- `pipeline_litellm` — LLM-шлюз (опц. для fuzzy-match имён). +- `cloudflared` (host-systemd) — публичный поддомен `n8n.bigmadnekenny.ru` для Bitrix webhooks. + +Новые сервисы в `~/projects/bit-flight-deck/docker-compose.yml`: +- **Metabase** — дашборды. +- **NocoDB** — UI для управления identity_map и весами проектных команд. + +## Декомпозиция на MVP + +| MVP | Цель | Статус | +|---|---|---| +| **MVP-1** | Загрузка сотрудников (4 слоя: факт / текущая / плановая как «осталось» / прогноз из Битрикса) | Spec ready ([docs/superpowers/specs/2026-05-13-mvp1-workload-design.md](docs/superpowers/specs/2026-05-13-mvp1-workload-design.md)) | +| **MVP-2** | Подвисшие задачи + контроль сроков проектов | Draft ([docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md](docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md)) | +| **MVP-3** | Маржа, НЗП, прогноз актирования | Draft ([docs/superpowers/specs/2026-05-13-mvp3-finance-design.md](docs/superpowers/specs/2026-05-13-mvp3-finance-design.md)) | +| **MVP-4** | Финрез по подразделениям | Draft, требует отдельного мозгового штурма ([docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md](docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md)) | +| **Подсистема D** | Компетенции сотрудников (производная из истории работ) | Draft ([docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md](docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md)) | + +## Принципы + +- **Read-only** интеграция. Источники остаются мастерами. +- **Single-user MVP.** Multi-user — вне scope MVP-1. +- **Email — главный ключ identity-resolution** для сотрудников между всеми системами. +- **Вертикальный срез по MVP.** Каждый MVP даёт видимый дашборд за 2-4 недели, не «фундамент на всё». +- **Компетенции — производные.** Не справочник, а расчёт из истории работ. + +## Структура репозитория + +``` +docs/superpowers/specs/ — спецификации MVP по очереди +sql/ — DDL миграции, views, procedures, seed +infra/ — init-скрипты БД, документация по поддоменам CF Tunnel +n8n/workflows/ — JSON-экспорты workflows +``` + +(На MVP-1: создаются по мере реализации.) + +## Связанные + +- Инфра-репозиторий: `https://gitea.bigmadnekenny.ru/admin/infrastructure` +- EVA-bot документация (API EVA + SD-проекты): `https://gitea.bigmadnekenny.ru/admin/eva-bot` diff --git a/docs/superpowers/specs/2026-05-13-mvp1-workload-design.md b/docs/superpowers/specs/2026-05-13-mvp1-workload-design.md new file mode 100644 index 0000000..661b523 --- /dev/null +++ b/docs/superpowers/specs/2026-05-13-mvp1-workload-design.md @@ -0,0 +1,479 @@ +# MVP-1 «Загрузка сотрудников» — Design Document + +| | | +|---|---| +| Дата | 2026-05-13 | +| Статус | Draft на ревью пользователя | +| Владелец | Чесноков Роман (Руководитель проектного отдела) | +| Срок MVP | 3-4 недели | +| Контекст-проект | Workload & Project Control System (см. memory `project_workload_control`) | + +## 1. Контекст и проблема + +В компании используются 4 учётных системы, ни одна из которых не даёт ответа на главные вопросы руководителя проектного отдела: + +- **BIT.RA** (1С) — ежедневные отчёты сотрудников о выполненной работе, проектная финансовая аналитика. +- **EVA Desk** — задачи разработчиков/PM и Service Desk. +- **Битрикс24** — CRM, сделки, прогноз продаж. +- **Самописная 1С (финрез)** — ручной агрегатор финреза по подразделениям. + +Чтобы понять «загрузку сотрудника» сейчас, руководитель должен открыть 3 системы параллельно и склеить данные в голове или в Excel. Это **не масштабируется** и **не даёт прогноза**. + +## 2. Цели MVP-1 + +Построить **первую вертикальную автоматизацию** — единый дашборд «Загрузка сотрудников» с 4 слоями (факт / текущая / плановая / прогнозная) для команды ~20 сотрудников за 3-4 недели работы. + +### Не-цели MVP-1 + +- Контроль сроков проектов поэтапно (подсистема C). +- Расчёт маржи, НЗП, актирования (подсистема C/F). +- Компетенции сотрудников (подсистема D). +- Расчёт финреза по подразделениям (подсистема F — отдельный мозговой штурм). +- BI-дашборды для всех руководителей (подсистема G). +- Multi-user интерфейс с правами по сотрудникам (зафиксировано MVP single-user). +- Двусторонняя интеграция (мы только читаем, источники остаются мастерами). +- Подключение CmfTimeTrackerHistory (под ACL deny, не используется). +- Подключение CmfTaskResAssign (не используется в команде). +- Все 16 воронок Битрикса (только CAT=16 «Проектные продажи (нов.)»). +- ИНН-маппинг клиентов BIT.RA ↔ Битрикс (поле в BIT.RA не заполняется). +- Прямая связь сделок Битрикса с проектами BIT.RA (`UF_CRM_PROJECTID` мёртвое поле). + +## 3. Бизнес-вопросы и их витрины + +| Вопрос | Витрина (mart) | Слой | Покрытие | +|---|---|---|---| +| Кто из сотрудников и сколько часов проработал коммерчески за месяц | `mart.workload_actual` | Факт | 100% от BIT.RA-отчётности | +| Кто сейчас в работе на каких задачах и сколько часов на них уйдёт | `mart.workload_current` | Текущая | ~43% задач EVA (по sample на 2026-05-13 — только задачи с `responsible_id`) | +| Сколько часов осталось доделать у каждого сотрудника (открытые задачи) | `mart.workload_planned` | Плановая (как «осталось») | То же ~43% | +| Сколько часов может прилететь из сделок Битрикса в стадиях после Защиты КП | `mart.workload_forecast` | Прогноз | Зависит от заполнения проектной команды | +| Сколько «безхозных» задач (без исполнителя или без проекта) — намёк команде | `mart.tasks_orphan` | Метрика качества данных | — | + +Дашборд в Metabase собирает всё в один экран. + +## 4. Архитектура верхнего уровня + +``` + Источники Транспорт Оркестратор + Хранилище + ───────────── ───────── ──────────────────────── + + BIT.RA (1C) ──pull──> HTTP-services ─┐ + EVA Desk ──pull──> JSON-RPC + admin ─┤ + Bitrix24 ──pull──> REST ─┼──> N8N orchestrator + Bitrix24 ──push──> Webhooks (tunnel)─┤ (cron + webhook triggers) + │ │ + │ ▼ + │ ┌──────────────────────┐ + │ │ PostgreSQL │ + │ │ raw_bitra (JSONB) │ + │ │ raw_eva (JSONB) │ + │ │ raw_bitrix (JSONB) │ + │ │ ↓ SQL views/procs │ + │ │ stg_* │ + │ │ ↓ │ + │ │ core.* │ + │ │ ↓ │ + │ │ mart.* │ + │ └─────┬────────────────┘ + │ │ + │ ┌─────┴─────┐ + │ ▼ ▼ + │ Metabase NocoDB + │ (dashboards)(admin UI: + │ identity_map, + │ deal_team_weights) + │ + └──> Telegram (alerts, optional) +``` + +### Компоненты + +**Используем существующую инфраструктуру** на хосте (Ubuntu в WSL), репозиторий `~/infrastructure/`: + +| Компонент | Статус | Назначение | Как используем | +|---|---|---|---| +| **pipeline_postgres** (postgres:15-alpine) | ✅ уже стоит | Хранилище | Создаём новую БД `workload` + пользователя `workload_user` | +| **n8n** | ✅ уже стоит | Оркестратор | Создаём наши workflows в существующем контейнере | +| **pipeline_litellm** | ✅ уже стоит (87+ моделей через OpenRouter) | LLM для опц. fuzzy-match ФИО | HTTP-нода в N8N → `http://pipeline_litellm:4000` | +| **pipeline_gitea** | ✅ уже стоит | Версионирование | Новый репозиторий `bit-flight-deck` | +| **Cloudflare tunnel** (host-systemd) | ✅ уже стоит | Публичный endpoint для Bitrix webhooks | Добавляем поддомен `n8n.bigmadnekenny.ru` → `localhost:5678` (N8N webhook-trigger) | + +**Ставим новое** в `~/projects/bit-flight-deck/docker-compose.yml` (подключение к external network `pipeline_net`): + +| Компонент | Назначение | +|---|---| +| **Metabase** | Дашборды поверх mart-таблиц | +| **NocoDB** | UI для ручного управления `core.identity_map`, `core.deal_team_weights` | + +**Источники данных (внешние):** + +| Компонент | Назначение | Где | +|---|---|---| +| **BIT.RA HTTP-сервисы** | Серверный модуль `IntegrationAPI` с REST-эндпоинтами под нужные core-сущности | Внутри BIT.RA (одноразовая 1С-разработка) | +| **EVA Desk JSON-RPC** | Стандартный API EVA с глобальным админ-токеном | Внешний firstbit.evateam.ru | +| **Bitrix24 REST + webhooks** | Pull через REST + push-приёмник через CF Tunnel | Внешний vdst421.1cbit.ru | + +## 5. Транспорт по источникам + +### 5.1. BIT.RA — HTTP-сервисы 1С (pull) + +В BIT.RA пишется серверный модуль `IntegrationAPI` с эндпоинтами: + +| Метод | Эндпоинт | Содержимое | +|---|---|---| +| GET | `/api/works?modified_since=&limit=N` | Document.Работы + ТЧ за период с инкрементом | +| GET | `/api/employees?modified_since=` | Catalog.Пользователи + ContactInfo (email) | +| GET | `/api/projects?modified_since=` | Catalog.Проекты с EVA_ID | +| GET | `/api/dictionaries` | Подразделения, Офисы, Менеджеры, СценарииПланирования и т.д. (редкий полный) | +| GET | `/api/work_types` | Enum.ВидыРабот (статичный, тянем раз в сутки) | +| GET | `/api/dept_history?modified_since=` | InformationRegister.ПодразделениеСотрудников | + +Расписание: works/employees/projects — каждые 30 минут. Dictionaries/work_types — раз в сутки. + +Аутентификация — выделенный 1С-пользователь с правами только на чтение релевантных объектов. + +### 5.2. EVA Desk — Pull-гибрид + глобальный админ-токен + +- **Nightly full sync** (раз в сутки): `.list` на CmfPerson, CmfProject, CmfTask, CmfStatus — полный снимок в `raw_eva.*`. +- **Incremental sync** (каждые 30 минут): `CmfAudit.list?filter=cmf_created_at>=` → список изменённых объектов → `.get` за деталями. + +Глобальный админ-токен в env-переменной N8N. После разработки — пересоздаётся. + +### 5.3. Bitrix24 — Webhooks + nightly reconcile + +- **Outbound webhooks** (push): на события `ONCRMDEALADD`, `ONCRMDEALUPDATE`, `ONCRMDEALDELETE`, `ONUSERADD`, `ONUSERUPDATE`, `ONUSERDELETE`. Битрикс POST'ит на наш endpoint через **существующий Cloudflare Tunnel** → новый поддомен → N8N webhook-trigger принимает → `crm.deal.get` за деталями → запись в raw. +- **Nightly reconcile pull** (раз в сутки): `crm.deal.list?filter[CATEGORY_ID]=16` со всеми UF-полями для сверки. + +**Поддомен для webhook'а:** добавляется к существующему `cloudflared` (host-systemd сервис). Конфигурация — в `cloudflared.env` (route на `localhost:5678`). Webhook-URL — `https://n8n.bigmadnekenny.ru/webhook/bitrix/`. + +Только воронка CAT=16. Только сделки в стадиях от «Защита КП» (`FINAL_INVOICE`) для прогноза + стадии реализации (`UC_XPZ8Z5`, `UC_QYTFP3`) как текущая загрузка. + +### 5.4. finrez_1c — НЕ в MVP-1 + +Откладываем до подсистемы F. Доработка `Catalog.Сотрудники` (добавление email) — также вне MVP-1. + +## 6. Data Model + +### 6.1. Слои PostgreSQL + +``` +raw_bitra.* — JSONB-снимки ответов BIT.RA HTTP-сервисов +raw_eva.* — JSONB-снимки ответов EVA JSON-RPC +raw_bitrix.* — JSONB-снимки сделок и пользователей Битрикса + +stg_bitra.* — нормализованные сущности BIT.RA (по одной таблице на сущность) +stg_eva.* — нормализованные сущности EVA +stg_bitrix.* — нормализованные сущности Битрикса + +core.* — унифицированная модель (см. ниже) + +mart.* — витрины для дашборда +``` + +### 6.2. core-таблицы (MVP-1 минимум) + +```sql +core.employee ( + id bigserial PRIMARY KEY, + email text UNIQUE NOT NULL, + full_name text, + is_active boolean, + is_target_for_mvp1 boolean, -- флаг «в фокусе MVP-1» + bitra_user_id text, -- guid из BIT.RA + eva_person_id text, -- CmfPerson:UUID + bitrix_user_id bigint, -- ID Битрикса + rate decimal(10,2), -- ставка + department_id bigint REFERENCES core.department, + office_id bigint REFERENCES core.office, + last_synced timestamptz +) + +core.department ( + id bigserial PRIMARY KEY, + name text, + bitra_id text, + bitrix_id bigint, + parent_id bigint REFERENCES core.department +) + +core.office ( + id bigserial PRIMARY KEY, + name text, + bitra_id text +) + +core.work_type ( + code text PRIMARY KEY, -- ЛУРВ, ЛТ, Демо, ИТС, ... + label text, + category text, -- commercial | presale | internal | free | ignored + is_billable boolean +) + +core.project ( + id bigserial PRIMARY KEY, + name text, + bitra_id text, + eva_id text, + is_sd boolean DEFAULT false, -- SD-проект (из явного списка 3 ID) + status text, + deadline date, + budget decimal(15,2) +) + +core.work_log ( + id bigserial PRIMARY KEY, + employee_id bigint REFERENCES core.employee, + work_date date NOT NULL, + work_type_code text REFERENCES core.work_type, + project_id bigint REFERENCES core.project, + stage_id bigint, + client_id bigint, + hours decimal(10,2), + description text, + bitra_doc_id text, -- ссылка на Document.Работы + bitra_row_index int +) + +core.task ( + id bigserial PRIMARY KEY, + code text, -- PBSD-12582 + name text, + eva_id text UNIQUE, -- CmfTask:UUID + cache_status_type text, -- OPEN | IN_PROGRESS | IN_REVIEW | CLOSED + project_id bigint REFERENCES core.project, + responsible_id bigint REFERENCES core.employee, + cmf_created_at timestamptz, + cmf_modified_at timestamptz, + status_in_progress_start timestamptz +) + +core.deal ( + id bigserial PRIMARY KEY, + bitrix_id bigint UNIQUE, + title text, + category_id int, -- 16 + stage_id text, -- C16:FINAL_INVOICE и т.д. + stage_semantic_id char(1), -- P | S | F + opportunity decimal(15,2), + begindate date, + closedate date, + assigned_to_id bigint REFERENCES core.employee, + company_id bigint -- ID Битрикс-компании (без маппинга на BIT.RA) +) + +core.deal_team_member ( + deal_id bigint REFERENCES core.deal, + employee_id bigint REFERENCES core.employee, + weight decimal(5,2) DEFAULT 1.0, -- вес сотрудника в команде (для распределения часов). По умолчанию 1.0 = поровну + is_manual boolean DEFAULT false, -- проставлен вручную через NocoDB + PRIMARY KEY (deal_id, employee_id) +) + +core.identity_map ( + entity_type text, -- employee | client | project + core_id bigint, + bitra_id text, + eva_id text, + bitrix_id bigint, + confidence text, -- auto | confirmed | manual + confirmed_by text, + confirmed_at timestamptz +) +``` + +### 6.3. core.work_type — справочник видов работ + +Загружается из BIT.RA `Enum.ВидыРабот` (14 значений), плюс правило категоризации: + +| Code (1С) | Label | Category | is_billable | +|---|---|---|---| +| `ЛУРВ` | ЛУРВ | commercial | true | +| `ЛТ` | ЛТ | commercial | true | +| `Демо` | Пресейл | presale | false | +| `ИТС` | ИТС (договор) | commercial | true | +| `ИТСПлатныеРаботы` | ИТС (доп. услуги) | commercial | true | +| `Сертификация` | Сертификация | internal | false | +| `Внутреннее` | Обучение | internal | false | +| `Управленка` | Работа руководителя | internal | false | +| `ВнутренниеРаботы` | Внутренние работы | internal | false | +| `НеОпл` | Бесплатные часы в счёт ПП | free | false | +| `Установка` | Установка в счёт ПП | free | false | +| `Гарантия` | Гарантия | free | false | +| `Коробка`, `Отложено` | (рудимент) | ignored | false | + +### 6.4. mart-таблицы (дашборд MVP-1) + +```sql +mart.workload_actual_monthly -- сотрудник × месяц → часы по категориям +mart.workload_current -- сотрудник × текущие задачи EVA (статус IN_PROGRESS) → часы (если есть оценка) или штуки +mart.workload_planned -- сотрудник × открытые задачи EVA (OPEN + IN_PROGRESS с responsible_id) → штуки и/или оценочные часы +mart.workload_forecast -- сотрудник × сделки Битрикс (от защиты КП до создания EVA-проекта) × proекторное распределение по проектной команде +mart.tasks_orphan -- задачи без responsible_id или без project_id (для team awareness) +mart.workload_summary -- composite: сотрудник × недели → факт/текущая/план/прогноз +``` + +## 7. Identity-resolution + +### 7.1. Сотрудники — через email + +Главный ключ. `lower(email)` сравнивается между: + +- BIT.RA `Catalog.Пользователи.КонтактнаяИнформация` (нужно дозаполнить если где-то пусто) +- EVA `CmfPerson.login` (= email на firstbit, домен `@1cbit.ru`) +- Bitrix24 `User.EMAIL` (домен `@1cbit.ru` у 117 из 133 активных) + +Fallback: ФИО → ручное разрешение через `core.identity_map` в NocoDB. + +### 7.2. Проекты — через регистры BIT.RA + EVA_ID + +- `Catalog.Проекты.EVA_ID` — частично заполнен. +- `InformationRegister.СоответствиеПроектовEVA_РА` — есть данные, обработка синхронизации сломана. **В рамках MVP-1 НЕ восстанавливаем** (это отдельная 1С-задача). Используем то, что есть в регистре + EVA_ID. +- Что не сматчилось — отмечаем `confidence='manual'` и ждём ручного разрешения в NocoDB. + +### 7.3. Клиенты — не маппим + +В MVP-1 связь BIT.RA-клиент ↔ Битрикс-компания не строим (ИНН в BIT.RA не заполняется, согласовано). Сделки Битрикса висят с `bitrix_company_id` без связки на BIT.RA. + +### 7.4. Identity-map — таблица + +```sql +core.identity_map ( + entity_type, -- employee | project + core_id, -- наш id + bitra_id, + eva_id, + bitrix_id, + confidence, -- auto (по точному email) | confirmed (через UI) | manual (без авто-сматчинга, ждёт человека) + confirmed_by, + confirmed_at +) +``` + +В NocoDB представление — отдельная страница «Identity issues» — все записи с `confidence='manual'` сортированные по дате создания. Пользователь пробегает раз в неделю и подтверждает. + +## 8. Стратегия SQL-трансформаций + +### 8.1. raw → stg + +Stored procedure на каждую сущность каждого источника. Логика: `INSERT INTO stg_X SELECT FROM raw_X WHERE NOT EXISTS (...) ON CONFLICT UPDATE`. Идемпотентно. + +### 8.2. stg → core + +Stored procedure `core.merge_employee()`, `core.merge_project()`, `core.merge_task()`, `core.merge_work_log()`, `core.merge_deal()`. + +Логика merge: +1. Найти `core_id` через `core.identity_map`. +2. Если найден — UPDATE. +3. Если нет — попытаться сматчить (email, EVA_ID и т.п.). Если успех — UPDATE + добавить запись в identity_map. +4. Если не сматчилось — INSERT новый core_id + identity_map с `confidence='manual'`. + +### 8.3. core → mart + +Materialized views, обновляемые после каждой пачки sync'а. Триггер: N8N после sync'а делает `SELECT mart.refresh_all()`. + +### 8.4. Версионирование SQL + +Структура проекта `~/projects/bit-flight-deck/` (имя финальное обсуждаем) — Gitea репозиторий: + +``` +~/projects/bit-flight-deck/ +├── docker-compose.yml -- Metabase + NocoDB (подключение к pipeline_net) +├── .env / .env.example +├── infra/ +│ ├── init-workload-db.sql -- создание БД workload + workload_user в pipeline_postgres +│ └── cloudflared-routes.md-- документация по поддоменам tunnel +├── sql/ +│ ├── migrations/ -- одноразовые DDL миграции (CREATE TABLE и т.п.) +│ ├── views/ -- view-определения +│ ├── procedures/ -- stored procedures +│ └── seed/ -- начальные данные (work_type категории, SD-projects whitelist) +├── n8n/ +│ └── workflows/ -- JSON-экспорты workflows N8N +├── docs/superpowers/specs/ -- эта спека и будущие +└── README.md +``` + +## 9. Дашборд Metabase + +### 9.1. Главный экран «Загрузка сотрудников MVP-1» + +| Раздел | Содержимое | +|---|---| +| Заголовок | Дата последней синхронизации (timestamp) с каждым источником | +| Plate 1 | Средний % коммерческой загрузки команды за 30 дней (большая цифра, цвет) | +| Plate 2 | Количество «безхозных» задач (без responsible_id или project_id) — намёк команде | +| Таблица | По каждому из ~20 сотрудников: ФИО / Подразделение / Факт 30д часы / Факт 30д % коммерч. / Текущая (часы IN_PROGRESS задач) / Осталось (часы OPEN+IN_PROGRESS) / Прогноз 4 недели (Б24) / Итого 4 недели | +| Линейный график | Динамика % коммерческой загрузки команды по неделям за 90 дней | +| Барчарт | Свободные ресурсы — топ-N сотрудников с факт+план ниже 50% | +| Таблица | Перегруженные — топ-N сотрудников с факт+план выше 90% | + +### 9.2. Принципы визуализации + +- Светофор: красный <50%, жёлтый 50-70%, зелёный 70-100%, серый >100% (перегруз). +- Все таблицы — с сортировкой и фильтрами по подразделению, виду работ. +- Цифры — округлены до часов, не до минут. + +## 10. Operational concerns + +### 10.1. Мониторинг + +- N8N-flow «health check» каждый час: проверяет последние sync-таймстампы. Если sync с любым источником > 2 часа — алёрт в Telegram (или просто logging). +- Метрики на дашборде: количество записей в каждой raw_*, last_sync timestamp по каждому источнику. + +### 10.2. Бэкап + +- **PostgreSQL** — автоматический pg_dumpall ещё не настроен в инфре (TODO в `~/infrastructure/ROADMAP.md`). Для MVP-1 — ручной `pg_dump workload > workload-YYYY-MM-DD.sql.gz` раз в сутки (cron в WSL). Когда инфра-уровневый backup поднимется (sidecar `pipeline_pg_backup`) — наш проект пользуется им автоматом. +- **Schema-only** бэкап перед каждой миграцией (`pg_dump --schema-only`). +- **Gitea-репозиторий проекта** — резервируется автоматически с остальным Gitea (в рамках инфры). + +### 10.3. Безопасность + +- EVA админ-токен в env N8N, не в git. +- Bitrix webhook URL — с секретным токеном в URL (защита от случайных POST'ов). +- PostgreSQL — отдельные роли: `etl_writer` (N8N) с правами на raw_*/stg_*, `analyst` (Metabase, NocoDB) с правами read-only на core/mart. +- HTTPS на туннеле для Bitrix-webhooks (Битрикс требует валидный SSL). + +### 10.4. Производительность + +Объёмы маленькие (десятки сотрудников, тысячи задач, тысячи строк работ в год). PostgreSQL без напряга справится. Индексы — по timestamps (modified_at, work_date) + по FK. + +## 11. Acceptance criteria MVP-1 + +1. ✅ В Metabase открыт дашборд «Загрузка сотрудников MVP-1», виден список ~20 сотрудников с 4 слоями загрузки. +2. ✅ Факт за вчера в дашборде совпадает с тем что в BIT.RA `Document.Работы` за вчера (выборочная проверка 3 сотрудников). +3. ✅ Текущая загрузка показывает задачи EVA в статусе `IN_PROGRESS` для сотрудников с `responsible_id`. Сверка с EVA-UI (выборочно). +4. ✅ Прогнозная загрузка показывает сотрудников из проектных команд сделок Битрикса CAT=16 от стадии `FINAL_INVOICE` («Защита сделки»). +5. ✅ NocoDB-страница «Identity issues» показывает несматчившиеся сущности (с `confidence='manual'`). +6. ✅ Свежесть данных: BIT.RA — не старше 1 часа, EVA — не старше 1 часа, Bitrix — не старше 5 минут (webhook). +7. ✅ Один полный цикл E2E: меняешь данные в источниках → через указанные временные окна они отражаются в дашборде. +8. ✅ Дашборд отвечает на 5 бизнес-вопросов из секции 3 без ручной фильтрации. + +## 12. Параллельные организационные задачи + +Не блокеры запуска MVP-1, но запускаются параллельно: + +- **Дисциплина EVA**: внедрить в команде заполнение `plan_start_date` / `plan_end_date` / `deadline` / `responsible_id` для всех новых задач. Через 2-3 месяца — пересмотр MVP-1 с честной «плановой» через plan_start_date. +- **Email во всех системах**: дозаполнить email сотрудников в BIT.RA `Catalog.Пользователи` где пусто. Аналогично в Битриксе для новых юзеров. + +## 13. Open questions / TODO + +- ✅ **Имя проекта** — `bit-flight-deck`. Gitea-репозиторий `bit-flight-deck`. Локальная папка `~/projects/bit-flight-deck/`. +- ✅ **Поддомен для Bitrix-webhooks** — `n8n.bigmadnekenny.ru`. Добавить ingress-роут в cloudflared `host-systemd`. +- **Список ~20 сотрудников MVP-1.** Какие конкретно email/department-id попадают в фокус? До начала разработки — выписать явный whitelist. +- **3 SD-проекта.** Извлечь точные ID/коды из `https://gitea.bigmadnekenny.ru/admin/eva-bot/docs/`. +- **Стадии Битрикса для прогноза.** Подтвердить точный список стадий CAT=16, в которых сделка должна учитываться в прогнозе. Кандидаты: `FINAL_INVOICE` («Защита сделки»), `UC_A02TUT` («Отложено»), `UC_U68WK1` («Подготовка рамочного договора»). Стадии `UC_XPZ8Z5/UC_QYTFP3` (Реализация) — туда уже EVA, в прогноз НЕ включаем. +- **Заполняемость email в BIT.RA.** Через MCP проверить какой % пользователей имеет email в `КонтактнойИнформации`. Если ниже 80% — параллельная организационная задача. +- **Распределение часов сделки по проектной команде.** Базовая логика — поровну между членами команды. Веса можно править в NocoDB. Возможно нужна более умная логика (по компетенциям) — это backlog для подсистемы D. + +## 14. Backlog после MVP-1 + +Не в MVP-1, но зафиксировано для последующих итераций: + +- **MVP-2: Подвисшие задачи и контроль сроков** — EVA `CmfStatusHistory` + детектор простоев + алёрты в Telegram. +- **MVP-3: Маржа, НЗП, актирование** — BIT.RA `ОборотыПроектныхПоказателей_v2` + расчёты маржинальности и НЗП. +- **MVP-4: Финрез по подразделениям** — finrez_1c + отдельный мозговой штурм по схеме расчёта + доработка финрезной 1С. +- **Подсистема D: Компетенции (производная из core.work_log)** — расчёт «что сотрудник реально умеет» из истории работ. +- **Восстановление обработки `СинхронизацияДанныхEVA_РА` в BIT.RA** — если потребуется для подсистемы C/D. +- **Автоматическое распределение SD-задач по компетенциям сотрудников** — подсистема D. +- **EVA TimeTracker** — если получится получить токен с правами на TimeTracker. +- **DataLens вместо Metabase** — если потребуются более сложные визуализации. +- **Полная Bitrix-интеграция** — все воронки, лиды, контакты. diff --git a/docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md b/docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md new file mode 100644 index 0000000..1effb6b --- /dev/null +++ b/docs/superpowers/specs/2026-05-13-mvp2-deadlines-design.md @@ -0,0 +1,104 @@ +# MVP-2 «Подвисшие задачи и контроль сроков» — Design Draft + +| | | +|---|---| +| Дата | 2026-05-13 | +| Статус | **Draft — фиксация обсуждённого, требует доработки после MVP-1** | +| Зависимости | MVP-1 завершён (есть core.employee, core.task, core.project, core.work_log) | +| Срок | 2-3 недели после MVP-1 | + +> **Назначение этого документа:** зафиксировать то, что уже обсудили по MVP-2, чтобы не вспоминать заново. Это **набросок**, не финальная спека. Финальная спека пишется отдельно перед стартом MVP-2 после результатов MVP-1. + +## Цели MVP-2 + +Автоматический контроль за сроками проектов и поиск подвисающих задач, которые тормозят следующие работы. Расширение дашборда MVP-1 + добавление алёртов. + +### Главные бизнес-вопросы (из исходной постановки пользователя) + +- В каком состоянии сейчас проекты? +- Где отстаём по срокам? +- Какие задачи подвисают и тормозят следующие работы? +- На какой задаче может зависнуть проект (декомпозиция до уровня задачи)? + +## Что добавляем к MVP-1 + +### Расширение core + +```sql +-- (MVP-1 уже имеет core.task) +core.task_status_history ( + id bigserial PRIMARY KEY, + task_id bigint REFERENCES core.task, + from_status_type text, -- OPEN | IN_PROGRESS | IN_REVIEW | CLOSED + to_status_type text, + from_status_id text, + to_status_id text, + cmf_author_id text, -- кто сделал переход (EVA) + employee_id bigint REFERENCES core.employee, + cmf_created_at timestamptz, + transition_id text, + resolution_id text +) + +core.stage ( + id bigserial PRIMARY KEY, + name text, + bitra_id text, + project_id bigint REFERENCES core.project, + plan_start_date date, + plan_end_date date, + is_completed boolean, -- BIT.RA.Catalog.ЭтапыПроектов.Выполнен + is_acted boolean -- BIT.RA.Catalog.ЭтапыПроектов.АктПодписан +) +``` + +### Новые витрины + +``` +mart.stalled_tasks — задачи IN_PROGRESS без смены статуса > N дней (N конфигурируется) +mart.project_health — по каждому открытому проекту: список задач, кто работает, факт-часы, текущий статус, риск-флаги +mart.deadline_risks — задачи и этапы у которых дедлайн в ближайшие N дней, но статус не закрыт +mart.task_lead_time — среднее время задачи в каждом статусе (для бенчмарка «нормальное» vs «подвисло») +``` + +### Источники данных (помимо MVP-1) + +- **EVA** — добавить полную синхронизацию `CmfStatusHistory` (есть 114k записей, фильтр по `cmf_created_at` работает — инкрементально). +- **BIT.RA** — добавить эндпоинт `/api/stages` для `Catalog.ЭтапыПроектов` (с реквизитами `Выполнен`, `АктПодписан`). +- **BIT.RA** — добавить эндпоинт `/api/project_status` для `Document.СтатусПроекта` (протоколы статус-совещаний). Опционально — может пригодиться для понимания «когда последний раз обсуждали проект». + +### Алёрты Telegram + +Базовый набор: +- «Задача подвисла» — в IN_PROGRESS более N дней без смены статуса (N = 5 / 7 / 10 — конфигурируется). +- «Этап проекта просрочен» — `Catalog.ЭтапыПроектов.ДатаОкончания < today AND Выполнен=false`. +- «Проект без активности» — нет работ по проекту за последние N дней. + +Триггер — N8N workflow раз в сутки → SELECT из витрин → POST в Telegram бот. + +### Дашборд (расширение MVP-1) + +Новые секции на главном дашборде Metabase: +- Плитка «N подвисших задач» с цветом (красная если > X). +- Таблица «Топ-N подвисших задач» — задача, исполнитель, проект, статус, дней без активности. +- Таблица «Проекты с риском срыва» — проект, плановая дата, % выполнения, последняя активность. +- Heatmap «Среднее время в статусе» по сотрудникам — кто узкое горло. + +## Бэклог в рамках MVP-2 + +- **Автоматическое распределение SD-задач по компетенциям сотрудников** (из исходного бэклога). Это связано с [Subsystem D](./2026-05-13-subsystem-d-competence-design.md): компетенции = производная от `core.work_log`. Распределение = выбор сотрудника с подходящей компетенцией и низкой текущей загрузкой. + +## Open questions (для финализации перед стартом MVP-2) + +- Пороги «подвисло» — конфигурируемые в `core.config` (per-status, per-priority?) или единый N дней? +- Включаем ли в MVP-2 контроль сроков по подписанию документов (актов)? Это пересекается с MVP-3 (НЗП). Возможно стоит часть из MVP-3 (контроль актов) перенести в MVP-2. +- Алёрты — только в Telegram, или ещё в дашборд (плитка «требует внимания»)? +- Что делать с задачами без `responsible_id` (43% покрытие — см. [reference-eva-empirical](../../memory/reference_eva_empirical.md))? Они невидимы в контроле сроков — нужна отдельная стратегия (например, алёрт «N задач без исполнителя» — намёк команде заполнять). + +## Зависимости от MVP-1 + +MVP-2 стартует когда: +- ✅ MVP-1 работает в проде (3 слоя загрузки + дашборд). +- ✅ `core.task` и `core.work_log` заполняются стабильно. +- ✅ Identity-map по сотрудникам стабильно работает (>95% сматчены). +- Дисциплина EVA в команде начала улучшаться (растёт % задач с `responsible_id`). diff --git a/docs/superpowers/specs/2026-05-13-mvp3-finance-design.md b/docs/superpowers/specs/2026-05-13-mvp3-finance-design.md new file mode 100644 index 0000000..b047342 --- /dev/null +++ b/docs/superpowers/specs/2026-05-13-mvp3-finance-design.md @@ -0,0 +1,93 @@ +# MVP-3 «Маржа, НЗП, актирование» — Design Draft + +| | | +|---|---| +| Дата | 2026-05-13 | +| Статус | **Draft — фиксация обсуждённого, требует доработки после MVP-2** | +| Зависимости | MVP-1 + MVP-2 (есть core.employee, core.project, core.stage, core.work_log) | +| Срок | 2-3 недели после MVP-2 | + +> **Назначение этого документа:** зафиксировать то, что уже обсудили по MVP-3, чтобы не вспоминать заново. Это **набросок**, не финальная спека. + +## Цели MVP-3 + +Финансовая аналитика по проектам: маржа план/факт, незавершёнка (НЗП), прогноз актирования следующего месяца, контроль подписания результирующих документов. + +### Главные бизнес-вопросы + +- Какая маржа по проектам (план/факт)? +- Сколько НЗП (незавершёнки) на каждом активном проекте? +- Сколько денег будем актировать в следующем месяце? +- Где отстаём по срокам подписания актов? +- Какая общая себестоимость и себестоимость по закрытым актам? + +## Что добавляем к MVP-1/2 + +### Расширение core + +```sql +core.project_finance ( + id bigserial PRIMARY KEY, + project_id bigint REFERENCES core.project, + stage_id bigint REFERENCES core.stage, + scenario_code text, -- план | факт | прогноз (из Catalog.СценарииПланирования BIT.RA) + analytics_type text, -- ВидАналитики из BIT.RA (рассмотреть в core или хранить как есть) + employee_id bigint REFERENCES core.employee, + period_date date, -- дата движения + sum_total decimal(15,2), -- Сумма (плановая/фактическая) + sum_acted decimal(15,2), -- СуммаАкт + sum_expense decimal(15,2), -- СуммаРасход + source_doc_id text -- ссылка на Document.ПланФактПроектныхПоказателей_v2 +) + +-- Возможно понадобится: +core.stage_act ( + id bigserial PRIMARY KEY, + stage_id bigint REFERENCES core.stage, + plan_act_date date, -- плановая дата акта (из Catalog.ЭтапыПроектов.ДатаОкончания) + actual_act_date date, -- фактическая дата подписания (если известно) + is_signed boolean, + sum_planned decimal(15,2), + sum_actual decimal(15,2) +) +``` + +### Новые витрины + +``` +mart.project_margin — маржа план/факт по проекту: (Сумма_план - СуммаРасход_план) / Сумма_план и аналогично для факта +mart.wip — НЗП = Σ(часы × ставка) - актированная_выручка по проекту/этапу +mart.actuation_forecast — прогноз актирования: открытые этапы с ДатаОкончания в следующем месяце и Σ их Сумма +mart.deadline_risks_financial — риски по подписанию документов (расширение mart.deadline_risks из MVP-2 на финансовую сторону) +mart.cost_summary — общая себестоимость и себестоимость по закрытым (АктПодписан=true) этапам +``` + +### Источники данных (помимо MVP-1/2) + +- **BIT.RA эндпоинт `/api/project_register`** — `AccumulationRegister.ОборотыПроектныхПоказателей_v2` с инкрементом (измерения Сценарий+Проект+Этап+ВидАналитики+Исполнитель → ресурсы Сумма+СуммаАкт+СуммаРасход). +- **BIT.RA эндпоинт `/api/plan_fact_v2`** — `Document.ПланФактПроектныхПоказателей_v2`. **ValueStorage поле `ХранилищеДерева` не тянем** (по [identity-and-scope](../../memory/feedback_identity_and_scope.md)). +- **BIT.RA эндпоинт `/api/lurv`** — `Document.ЛУРВ` для понимания фактически выписанных листов учёта результатов выполнения. + +### Дашборд (расширение) + +Новый дашборд «Финансы проектов» в Metabase: +- Плитка «Общая НЗП» (сумма по всем активным проектам). +- Плитка «Прогноз актирования за следующий месяц». +- Таблица «Маржинальность проектов» — проект, план-маржа, факт-маржа, отклонение, цвет светофор. +- Таблица «Этапы к актированию в этом/следующем месяце» — этап, плановая дата, сумма, готовность. +- График «Динамика НЗП по проектам» за 12 месяцев. + +## Open questions (для финализации перед стартом MVP-3) + +- **Что считать НЗП именно?** Текущая идея — `Σ(core.work_log.hours × core.employee.rate) − Σ(core.project_finance где сценарий=факт-акт)`. Но если расход в `ОборотыПроектныхПоказателей_v2.СуммаРасход` уже считается по факту работ — это будет двойной счёт. Уточнить семантику регистра. +- **Сценарии (`Catalog.СценарииПланирования` BIT.RA)** — какие реально используются? План, факт, прогноз? Нужно понять словарь. +- **`ВидАналитики` в регистре** — что это за измерение, какие значения? Возможно нужно тянуть `Catalog.ВидыАналитикиПроектныхПоказателей` (или подобное). +- **Связь с финрезом подразделений (MVP-4)** — финрез считается из выручки и расходов, маржа проектов — тоже. Не дублируем ли мы расчёты? Возможно MVP-3 и MVP-4 нужно объединить или строго разграничить (MVP-3 = разрез по проектам, MVP-4 = разрез по подразделениям). +- **Контроль подписания документов** — нужны ли дополнительные сущности (Договоры, ДополнительныеСоглашения)? Они есть в BIT.RA `Catalog.Договоры` и в ТЧ `Проекты.ДокументыЭтапов`. + +## Зависимости от MVP-2 + +MVP-3 стартует когда: +- ✅ MVP-2 работает (есть core.stage, deadline-логика). +- ✅ Identity-map проектов BIT.RA ↔ EVA стабильна. +- Полезно но не обязательно: восстановлена обработка `СинхронизацияДанныхEVA_РА` (для стабильного маппинга проектов). diff --git a/docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md b/docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md new file mode 100644 index 0000000..8df0b1d --- /dev/null +++ b/docs/superpowers/specs/2026-05-13-mvp4-finrez-design.md @@ -0,0 +1,111 @@ +# MVP-4 «Финрез по подразделениям» — Design Draft + +| | | +|---|---| +| Дата | 2026-05-13 | +| Статус | **Draft — требует отдельного мозгового штурма по схеме расчёта** | +| Зависимости | MVP-1 + MVP-2 + MVP-3 | +| Срок | 2-3 недели после MVP-3 + отдельная сессия с пользователем по схеме расчёта | + +> **Назначение этого документа:** зафиксировать то, что уже обсудили по MVP-4, чтобы не вспоминать заново. **Это самая сырая из спек** — финальная схема расчёта финреза требует отдельного мозгового штурма. + +## Цели MVP-4 + +Автоматизация расчёта финрезультата по подразделениям. Сейчас пользователь ведёт расчёт **руками в Excel** и кладёт итоги в самописную 1С (см. [reference-finrez-1c](../../memory/reference_finrez_1c.md)). + +### Главные бизнес-вопросы + +- Какой финрез у каждого подразделения за прошлый месяц / квартал / год? +- Прогноз финреза на основе текущей загрузки. +- Какие подразделения убыточны, какие прибыльны? + +## Текущий статус автоматизации (как есть) + +В **самописной 1С** (без БСП, 9 объектов): +- `Document.РегистрацияПоказателейЗаПериод` — ввод вручную раз в месяц. +- ТЧ: Сотрудник × ФОТ × Оборот × КоличествоЧасов. +- `AccumulationRegister.ПоказателиЗаПериод` — обороты с измерениями Сотрудник + Подразделение, ресурсы ФОТ + Оборот + Часы. + +То есть **в 1С лежит только итог**. **Сложная схема расчёта** живёт в голове пользователя и Excel-файлах. По его словам — «считаю сам, кладу финальную информацию, конфигурацию придется дорабатывать под реальные расчеты». + +## Что планируется в MVP-4 + +### Этап 1 — Сбор и автоматизация ввода (вместо Excel) + +**До детального проектирования** — обязательная **сессия с пользователем** где он рассказывает: +- Как именно считается выручка по подразделению (распределение проектной выручки между подразделениями? через сотрудников?). +- Как считается расход (ФОТ + амортизация + накладные? распределение общих расходов?). +- Какие статьи используются (ДДС / БДР)? +- Как меняется схема по времени (что было до этого, что планируется). + +### Этап 2 — Доработка самописной 1С + +Текущая конфигурация — приёмник готовых цифр. Нужно превратить в **калькулятор**: +- Добавить справочник статей затрат. +- Добавить документ с детализацией: Сотрудник × Статья × Сумма за период. +- Привязка к проектам (если расходы можно атрибутировать на проект). +- Привязка к данным из BIT.RA (фактические работы сотрудников). +- Добавить email в `Catalog.Сотрудники` (для identity-resolution). +- HTTP-сервисы — реализация в самописной 1С (см. [architecture-transport-decisions](../../memory/architecture_transport_decisions.md)). + +### Этап 3 — ETL в core + +```sql +core.dept_finance_monthly ( + department_id bigint REFERENCES core.department, + period_month date, + fot decimal(15,2), + oborot decimal(15,2), + hours_count decimal(15,2), + finrez decimal(15,2) -- oborot - fot - расходы +) + +core.expense_item ( + code text PRIMARY KEY, + label text, + category text -- ФОТ, амортизация, общие, ... +) + +core.dept_finance_detailed ( + department_id bigint, + period_month date, + employee_id bigint REFERENCES core.employee, + expense_item_code text REFERENCES core.expense_item, + amount decimal(15,2) +) +``` + +### Этап 4 — Витрины + +``` +mart.dept_finance_monthly — по подразделению × месяц: выручка, расходы по статьям, финрез, маржинальность +mart.finrez_trend — динамика по подразделениям за 12 мес +mart.finrez_forecast — прогноз финреза на основе текущей загрузки + средних показателей +``` + +### Этап 5 — Дашборд + +«Финрез по подразделениям» в Metabase: +- Плитка «Финрез компании за прошлый месяц». +- Таблица по подразделениям: выручка, расходы, финрез, маржинальность %, цвета. +- График: динамика финреза по подразделениям за 12 месяцев. +- Прогноз следующего месяца на основе загрузки. + +## Identity-resolution + +Сотрудники самописной 1С ↔ BIT.RA — **сейчас нет общего ключа** (`Catalog.Сотрудники` имеет только Код+Наименование). После добавления email в `Catalog.Сотрудники` — связь через email (см. [identity-and-scope](../../memory/feedback_identity_and_scope.md)). + +## Open questions (для финализации перед стартом MVP-4) + +1. **Схема расчёта финреза.** Это **самый главный вопрос**. Без него нельзя проектировать. Отдельная сессия пользователя. +2. **Уровень детализации.** Расход сразу по статьям или агрегированно? По сотрудникам или нет? +3. **Атрибуция выручки.** Как делится выручка проекта между подразделениями (если в проекте сотрудники разных подразделений)? Пропорционально часам? По ставке × часы? +4. **Альтернатива** — может проще не дорабатывать 1С, а реализовать расчёт прямо в core PG, оставив 1С только для просмотра итогов? Решение зависит от готовности пользователя работать с витриной в Metabase вместо отчёта в 1С. +5. **Прогноз финреза** — на основе чего считать? Среднее за прошлые периоды + текущая загрузка + ставки. Или модель сложнее. + +## Зависимости от MVP-3 + +MVP-4 стартует когда: +- ✅ MVP-3 работает (есть core.project_finance с маржой). +- ✅ Отдельная сессия с пользователем по схеме финреза завершена. +- ✅ Решение по доработке finrez_1c принято (доработка vs расчёт в core). diff --git a/docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md b/docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md new file mode 100644 index 0000000..f152ab7 --- /dev/null +++ b/docs/superpowers/specs/2026-05-13-subsystem-d-competence-design.md @@ -0,0 +1,102 @@ +# Подсистема D «Компетенции сотрудников» — Design Draft + +| | | +|---|---| +| Дата | 2026-05-13 | +| Статус | **Draft — может реализовываться параллельно с MVP-2/3 или после** | +| Зависимости | MVP-1 (есть core.work_log + core.employee + core.project) | +| Срок | 1-2 недели работы (зависит от того, насколько детально нужен механизм распределения) | + +> **Назначение:** зафиксировать обсуждённый подход к компетенциям. Это **набросок**. + +## Ключевое решение пользователя + +Цитата: «таблицу по компетенциям возможно придется собирать по проделанным зафиксированным работам в БИТ.РА, портфолио проектов возможно тоже». + +**Why:** ручное ведение справочника компетенций сотрудников — нерабочая практика (устаревает, субъективно, никто не обновляет). Объективная компетенция = что человек реально делал в последний период. + +См. [identity-and-scope](../../memory/feedback_identity_and_scope.md). + +## Цели Подсистемы D + +1. Автоматически рассчитать матрицу «сотрудник × компетенция × уровень» на основе истории работ. +2. Использовать матрицу для: + - Подсказки распределения проектной команды Битрикс-сделок на конкретных сотрудников (улучшение MVP-1 — сейчас наивно поровну). + - Автоматического распределения SD-задач по компетенциям (бэклог-айтем MVP-2). + - Подсказки руководителю «кто свободен и умеет делать X». + +## Что такое «компетенция» в нашем контексте + +**Двухмерное определение:** +- **Конфигурация** = с каким продуктом сотрудник работал (1С:ERP, 1С:ЗУП, БИТ.ФИНАНС, и т.д.). Берём из `core.project.bitra_id` → `BIT.RA.Catalog.Проекты.Конфигурация` (`Catalog.Конфигурации`). +- **ВидРаботы** = что делал (ЛУРВ / ЛТ / ИТС / Пресейл и т.п.). Берём из `core.work_log.work_type_code` (см. [reference-bitra-work-types](../../memory/reference_bitra_work_types.md)). + +То есть компетенция = пара `(Конфигурация × ВидРаботы)`. + +## Расчёт уровня компетенции + +``` +weight(employee, config, work_type, period) = + Σ(hours) where work_log.employee = employee + AND work_log.project.config = config + AND work_log.work_type = work_type + AND work_log.period >= period - 12 months +``` + +Уровень владения = относительный вес: +- «Эксперт» — > 100 часов за последние 12 мес. +- «Опытный» — 30-100 часов. +- «Знаком» — 5-30 часов. +- «Нет опыта» — < 5 часов. + +Пороги — конфигурируемые в `core.config`. + +## Расширение core + +```sql +core.employee_competence ( + employee_id bigint REFERENCES core.employee, + config_code text, -- Конфигурация (1С:ERP, БИТ.ФИНАНС и т.д.) + work_type_code text, -- Вид работ + hours_12m decimal(15,2), -- часы за последние 12 месяцев + hours_3m decimal(15,2), -- за последние 3 месяца (для свежей картины) + level text, -- эксперт | опытный | знаком | нет_опыта + last_work_date date, -- когда последний раз делал + PRIMARY KEY (employee_id, config_code, work_type_code) +) +``` + +Заполняется materialized view'хой, обновляется раз в сутки (после ежедневной синхронизации BIT.RA). + +## Применение в системе + +### 1. Распределение проектной команды сделок Битрикс (улучшение MVP-1) + +Сейчас (MVP-1): часы делятся поровну между членами `UF_CRM_1729244690` (проектная команда). + +С компетенциями (улучшение): часы распределяются с учётом уровня компетенции каждого члена команды по `Конфигурации` сделки (`UF_CRM_1729244070`). Эксперт получает больше, новичок — меньше. Веса можно править в NocoDB вручную. + +### 2. Автоматическое распределение SD-задач (бэклог-айтем) + +В SD-задачах часто нужно быстро назначить исполнителя. Если задача относится к 1С:ERP (по `cf_konfiguracziya1`), система предлагает топ-3 сотрудника с подходящей компетенцией и низкой текущей загрузкой. + +### 3. Дашборд «Компетенции команды» + +Витрина `mart.competence_matrix`: +- Heatmap: сотрудники × Конфигурации, цвет = уровень компетенции. +- Таблица «Узкие места» — конфигурации, по которым у компании только 1 эксперт. +- Таблица «Покрытие команды» — какие компетенции есть в команде, какие нет. + +## Open questions + +- **Маппинг `Catalog.Конфигурации` BIT.RA ↔ Bitrix `UF_CRM_1729244070`** — это разные справочники, но семантически похожие. Нужна ручная таблица соответствий в `core.identity_map_config`. См. также [reference-bitrix24-classifications](../../memory/reference_bitrix24_classifications.md). +- **Учёт пресейла как компетенции.** Если сотрудник делал только пресейл по конфигурации (без ЛУРВ/ЛТ) — он эксперт по продаже, но не по реализации. Различать. +- **Перевод сотрудника** — если человек 5 лет делал 1С:Розница, потом переключился на 1С:ERP, окно «12 месяцев» это покажет, но текущая компетенция = ERP. Можно добавить «свежесть» (hours_3m). +- **Подсистема D vs MVP-2.** Если автоматическое распределение SD-задач нужно как часть MVP-2 — D становится зависимостью MVP-2. Если как улучшение MVP-1 — параллельно с MVP-2. Решить после MVP-1. + +## Зависимости от MVP-1 + +Подсистема D стартует когда: +- ✅ MVP-1 работает. +- ✅ `core.work_log` стабильно заполняется из BIT.RA. +- ✅ `core.project` маппится с конфигурациями (через `Catalog.Проекты.Конфигурация`).