# Расхождения в метриках: что видно из кода, без доступа к halleg

Источник: сохранённые копии в `local/Source/`, снимок от 11.09.2026 (все страницы между 11:43 и 17:16 одного дня).
Метод: в страницы зашиты собственные описания метрик - в подсказках `title=`, в вызовах `showM(имя, описание)` и в словарях вида `{n:"Имя", d:"Описание"}`. Их можно извлечь и сравнить между отчётами.

**Важно:** сравниваются определения, а не значения. Значения сравнить нельзя - часть чисел приходит через `/api/*`, которого у нас нет. Но расхождение в определении само по себе гарантирует расхождение в цифрах.

Всего извлечено определений: 105 уникальных имён. Встречаются в двух и более отчётах: 13. Из них **определены по-разному: 13**.

## Покрытие определениями по отчётам

| Отчёт | Метрик с описанием |
|---|---:|
| Weekly_KPI_Dashboard | 45 |
| Trader_Operational_Dashboard | 18 |
| Affiliate_Weekly_Report | 13 |
| Trader_Scoreboard | 12 |
| Trader_KPI_Dashboard | 11 |
| Affiliate_Dashboard | 6 |
| Trader_Detailed_Dashboard | 5 |
| Trader_Hourly_Calculator | 5 |
| Affiliate_Tier_Board | 4 |
| Merchant_SLU | 0 |
| Retention__Churn | 0 |

У `Merchant_SLU` и `Retention__Churn` описаний нет вообще.

## Расхождения

Отсортировано по серьёзности: сначала те, где расходится суть, потом те, где расходится формулировка.

### Score

- **Trader_Scoreboard**: Final weighted score (0-100). PO_P90*20% + PI_P90*18% + CR*18% + Settlement*15% + Statement*10% + Auto*7% + AvgVol*7% + Cost*5%.
- **Weekly_KPI_Dashboard**: Зважений бал 0–100 за canonical формулою TIER_CALCULATION.md (Power BI Main Dashboard, 1:1 з Affiliate-pc): Volume×0.3 + Succ×0.2 + Active×0.1 + Tenure×0.1 + Velo IN×0.1 + Velo OUT×0.1 + Stab×0.1. Деталі порогів — у Methodology.

### PayIn Volume

- **Trader_KPI_Dashboard**: сума PayIn-транзакцій за період
- **Trader_Operational_Dashboard**: Сумма успешных payin транзакций (₹). Из таблицы Transaction, operation=payin. Учитываются только провайдеры с объёмом > 5,000.
- **Weekly_KPI_Dashboard**: Сумма входящих платежей за неделю (₹). Источник: Transaction, operation='payin'. Учитывается все, кроме операторов-провайдеров. Чем выше — тем больше денег обработано.

### Active Accounts

- **Trader_Operational_Dashboard**: Сумма уникальных банковских счетов с активностью по каждому часу и трейдеру за день.
- **Weekly_KPI_Dashboard**: Количество уникальных банковских счетов (BankAccount), с которых были payin-операции за неделю.

### Deposit

- **Trader_KPI_Dashboard**: кумулятивний депозит на останній день періоду (без archive/Payable)
- **Weekly_KPI_Dashboard**: Загальна сума депозитів трейдера ALL-TIME (bank_accounts.title LIKE '%deposit%'). Net flow по expenses.cash_in − cash_out для deposit-рахунків. Не залежить від обраного періоду.

### Active Traders

- **Trader_Operational_Dashboard**: Количество уникальных трейдеров с PayIn > 0 за день. Считается из Transaction по accountProvider.
- **Weekly_KPI_Dashboard**: Количество уникальных трейдеров с PayIn-активностью в эту неделю.

### Statement, %

- **Trader_Operational_Dashboard**: Доля банковских счетов, для которых загружена выписка (BankAccountFile) за период активности.
- **Weekly_KPI_Dashboard**: Доля банковских счетов, имеющих привязанные выписки (BankAccountFile). Volume-weighted: SUM(has_statement) / COUNT(DISTINCT ba.account). Считается на уровне ba.id с дедупликацией по account number.

### % Auto

- **Trader_Operational_Dashboard**: Доля автоматически обработанных заявок (editedBySupport=false) от успешных ClientPayin.
- **Weekly_KPI_Dashboard**: Доля автоматически обработанных payin-заявок (без участия support). Формула: COUNT(status='successed' AND editedBySupport=false) / COUNT(status='successed'). Чем выше — тем меньше ручной работы.

### CR, %

- **Trader_Operational_Dashboard**: Конверсия — доля успешных заявок (successed_by_partner) от общего числа ClientPayin за день.
- **Weekly_KPI_Dashboard**: Conversion Rate — доля успешных payin-заявок от общего числа за неделю. Формула: COUNT(status='successed_by_partner') / COUNT(*). Чем выше — тем эффективнее обработка.

### Settlement

- **Trader_Operational_Dashboard**: Сумма settlement расходов (₹). Из Transaction → Expense → ExpenseCategory(Settlement).
- **Weekly_KPI_Dashboard**: Сумма расходов категории Settlement за неделю. Источник: Transaction → Expense → ExpenseCategory.label='Settlement'. Это возвраты средств трейдерам.

### Settle/PayIn, %

- **Trader_Operational_Dashboard**: Доля settlement от PayIn Volume. Показывает какой % входящего потока уходит на расчёты.
- **Weekly_KPI_Dashboard**: Доля settlement от PayIn Volume. Формула: SUM(settlement) / SUM(payin_volume). Показывает, какой процент входящего потока возвращается трейдерам.

### Avg PayIn/Trader

- **Trader_Operational_Dashboard**: Средний PayIn Volume на одного активного трейдера за день.
- **Weekly_KPI_Dashboard**: Средний PayIn Volume на одного активного трейдера за неделю. Формула: SUM(payin) / COUNT(DISTINCT active_traders).

### PayOut Volume

- **Trader_Operational_Dashboard**: Абсолютная сумма payout транзакций (₹). ABS(SUM) из таблицы Transaction, operation=payout.
- **Weekly_KPI_Dashboard**: Сумма исходящих выплат за неделю (₹). Источник: Transaction, operation='payout' (берется абсолютное значение). Параллель к PayIn.

### Trader

- **Trader_Scoreboard**: Unique name/alias of the trader (AccountProvider).
- **Weekly_KPI_Dashboard**: Назва P2P провайдера (з префіксом групи: G[P2P], D[P2P], L[P2P] тощо). Зірочка ★ — новий трейдер (перша транзакція у поточному періоді).

## Что из этого следует

1. **Сырьё для глоссария уже есть.** Не нужно изобретать описания метрик: они написаны авторами отчётов и лежат в коде страниц. Глоссарий платформы собирается из них автоматически, а не пишется руками.

2. **Расхождения находятся машинно.** Тот же разбор, который построил эту таблицу, может работать постоянно: при публикации или правке отчёта сравнивать определение метрики с эталоном и ругаться на несовпадение. Это ровно пункт 4* из пожеланий аналитиков, и он оказывается дешевле, чем выглядел.

3. **Основная работа - не техническая.** Из 13 расхождений часть это разные формулировки одного и того же, а часть - разные метрики под одним именем. Развести одно от другого может только человек, который знает предметную область. Наша задача - принести ему готовый список, а не заставлять искать самому.

4. **Покрытие неровное.** 45 описаний в Weekly KPI против нуля в Merchant SLU и Retention & Churn. Глоссарий закроет только то, что описано; остальное придётся дописывать.

## Вопросы, которые из этого выросли

- `Score` в `Weekly_KPI_Dashboard` ссылается на **`TIER_CALCULATION.md`** как на эталонную формулу («Power BI Main Dashboard, 1:1 з Affiliate-pc»). Где лежит этот файл? Он и есть точка правды для скоринга?
- `PayIn Volume` в `Trader_Operational_Dashboard` считается только по провайдерам с объёмом больше 5 000, а в `Weekly_KPI_Dashboard` - по всем, кроме операторов-провайдеров. Это осознанное различие или баг?
- `Active Accounts` в `Trader_Operational_Dashboard` - это сумма уникальных счетов по каждому часу и трейдеру, то есть один счёт считается многократно за день. В `Weekly_KPI_Dashboard` - честный `COUNT(DISTINCT)`. Под одним именем две разные величины. Так и задумано?
- `Score` в `Trader_Scoreboard` и в `Weekly_KPI_Dashboard` - две совершенно разные формулы с разными компонентами и весами. Какая из них настоящая?
- `Deposit`: в `Trader_KPI_Dashboard` зависит от выбранного периода, в `Weekly_KPI_Dashboard` - ALL-TIME и от периода не зависит. Пользователь видит одно слово и разные числа.

---

# ОБНОВЛЕНИЕ 17.09.2026: найден из `metrics-legend` глоссарий

В `local/Source/Trader_Reporting.html` (страница `metrics-legend` на halleg) лежит **из `metrics-legend` глоссарий метрик**. Он не был виден, потому что отсутствует в навигации: доступен только по прямой ссылке, общий `sidebar.js` не подключён, своя палитра, посещений ноль.

Что в нём есть:

- **15 метрик** с полями: означення, формула, одиниці, синоніми, де присутня, примітки;
- явное правило: «Метрика рахується **тільки так**, як тут описано; якщо звіт рахує інакше - **виправляється звіт**»;
- часовой пояс IST, источник данных - **ClickHouse-реплика `hermes`**;
- **синонимы метрик** по отчётам и по финансам - то, чего нет нигде больше;
- владельцы определений: **Halleg (дашборд) и la_grange (финансы)**;
- дата актуализации - **27.07.2026** (страницы отчётов сохранены 11.09, разрыв шесть недель);
- ссылка на **Confluence-страницу «Глосарій метрик»** - ещё один источник, которого у нас нет.

Метрики в `metrics-legend`: PayIn Volume, PayOut Volume, Settlement ₹, Settle/PayIn %, CR %, % Auto (In/Out), Statement %, Active Traders, Active Accounts, New Traders, Avg PayIn/Trader, Deposit, PayIn Speed, PayOut Speed, Capacity/Threshold.

## Пересборка списка расхождений по `metrics-legend`

Из 13 найденных ранее расхождений картина стала другой.

### Закрыты `metrics-legend`: осознанные отклонения, документированы

| Метрика | Что говорит `metrics-legend` |
|---|---|
| `Active Traders` | два разных понятия: «за период» (`metrics-legend` дашборда) и «онлайн сейчас» (`metrics-legend` финансов). Сравнивать нельзя, и это прямо написано |
| `Deposit` | тоже два понятия: snapshot (финансы) и cumulative (Trader KPI). Оба легальны |
| `Avg PayIn/Trader` | в Trader KPI знаменатель - среднедневное число активных, а не за период. Отмечено как отдельная метрика |
| `% Auto` | это **две** метрики, In и Out, с разными полями. Для payout `edited_by_support` использовать нельзя - оно там ≈100% |

### Нарушения `metrics-legend`: легенда сама велит их чинить

| Метрика | Где | В чём нарушение |
|---|---|---|
| `CR, %` | Trader_Operational | числитель только `successed_by_partner`, `metrics-legend` требует `completed` + `successed_by_partner` |
| `CR, %` | Weekly_KPI | знаменатель `COUNT(*)` включая pending - занижает CR в течение дня. `metrics-legend`: только финальные статусы |
| `Active Accounts` | Trader_Operational | сумма уникальных по каждому часу вместо `COUNT(DISTINCT bank_account)` за период |

### Расхождение между легендой и кодом

`PayIn Volume`: `metrics-legend` говорит, что фильтр «провайдер с total payin > 5 000 ₹» - **особенность отчёта Trader KPI, не часть `metrics-legend`**. Но в коде этот фильтр нашёлся в описании метрики у **Trader_Operational**. Либо легенда описывает не тот отчёт, либо фильтр расползся. Проверить по коду.

### Нет в `metrics-legend` вообще

**`Score`** - в глоссарии его нет. Есть только упоминания «вес 20% у Score», «вес 18% у Score» внутри других метрик. При этом в отчётах две разные формулы:

- `Trader_Scoreboard`: `PO_P90*20% + PI_P90*18% + CR*18% + Settlement*15% + Statement*10% + Auto*7% + AvgVol*7% + Cost*5%` - веса совпадают с упоминаниями в легенде;
- `Weekly_KPI`: `Volume×0.3 + Succ×0.2 + Active×0.1 + Tenure×0.1 + Velo IN×0.1 + Velo OUT×0.1 + ...` со ссылкой на `TIER_CALCULATION.md`.

Это **самое крупное нерешённое расхождение**: главная сводная метрика существует в двух несовместимых версиях, и `metrics-legend` её не покрывает.

### Требуют проверки по коду

- `Statement, %` - `metrics-legend` задаёт окно rolling 30 дней, ни в одном из отчётов это окно в описании не упомянуто;
- `PayOut Volume` - `metrics-legend` требует скоуп P2P и исключение счетов TRANSIT, в описаниях отчётов этого нет.

## Что это меняет в плане платформы

1. **Глоссарий не строим - импортируем.** `metrics-legend` уже написан, и написан хорошо: с формулами, синонимами и разбором конфликтов. Задача сводится к тому, чтобы превратить его в реестр метрик и подключить к отчётам.

2. **Появилась проверяемая задача:** сверить код каждого отчёта с `metrics-legend` и выдать список нарушений. Три штуки уже найдены по одним только описаниям. Это ровно то, чего аналитики хотели от «агента, проверяющего метрики», и для этого не нужен ни агент, ни доступ к базе.

3. **Синонимы - неожиданно ценное.** В `metrics-legend` перечислены все названия одной метрики по отчётам и у финансов: «Налив», «vol», «pi», «Amount IN», «Demand» - это всё PayIn Volume. Поиск по платформе должен искать по синонимам, иначе человек не найдёт метрику под тем именем, которым её называет его отдел.

4. **Проблема шире halleg.** В `metrics-legend` фигурируют «финансы (lab)», «eye-of-god», Confluence - то есть параллельные системы со своими определениями. Платформа, объединяющая только отчёты halleg, решает лишь часть задачи.

5. **`metrics-legend` может протухать.** Актуализирован 27.07, отчёты живут дальше. Ничто не связывает изменение расчёта с обновлением определения - именно это и должен чинить реестр метрик, где описание лежит рядом с расчётом.

## Актуален ли `metrics-legend`: что удалось проверить

Дата в футере - 27.07.2026. Копии отчётов сохранены 11.09. Разрыв шесть недель. Проверки, которые можно сделать без доступа к серверу:

### Тест 1: знает ли `metrics-legend` о новых отчётах - ПРОВАЛЕН

По статистике использования три отчёта появились **после** 27.07: `Affiliate Native` (с 11.08), `Merchant OUT/IN` (начало сентября), `Trader Teamlead` (сентябрь).

| Отчёт | Появился | Упомянут в `metrics-legend` |
|---|---|---|
| Affiliate Native | 11.08 | **нет** |
| Merchant OUT/IN | начало сентября | **нет** |
| Trader Teamlead | сентябрь | **нет** |
| Operational, Weekly, Detailed, Scoreboard, Merchant-SLU, Churn, KPI, THC, Capacity | до 27.07 | все упомянуты |

Вывод однозначный: на 27.07 `metrics-legend` покрывал **все** существовавшие отчёты, и с тех пор его не трогали. Три отчёта он не видит.

### Тест 2: сходится ли «де присутня» с фактом - в основном ДА

Сверка по синонимам из самого `metrics-legend`. Точно совпали: `% Auto` (5 отчётов из 5), `Deposit`, `PayIn Speed`, `Settlement` (10 из заявленных 11), `PayIn Volume`, `Active Traders`, `Statement, %`.

Не сошлось: `PayOut Volume` (`metrics-legend` заявляет Detailed, Churn, Affiliate - не найдено), `Active Accounts` (заявлен Detailed - не найдено), `New Traders` (заявлены Weekly и Churn - не найдено), `PayOut Speed` (заявлены Merchant-SLU и Scoreboard - не найдено).

Осторожно: страницы многоязычные, и отсутствие английского имени не доказывает отсутствия метрики. Это сигнал, а не приговор.

### Тест 3: схема данных расходится

| Где | Как называются таблицы |
|---|---|
| `metrics-legend` | `transactions.amount`, `bank_accounts.provider_pid`, `expense_category.code`, `payments.amount` |
| Описания в отчётах | `Transaction`, `ClientPayin`, `Expense`, `ExpenseCategory`, `BankAccountFile`, `BankAccount` |

`metrics-legend` описывает snake_case-схему ClickHouse-реплики `hermes`, отчёты - PascalCase-сущности Postgres. Либо отчёты переехали на ClickHouse позже, чем писались их описания, либо `metrics-legend` описывает целевое состояние, а не текущее. Спросить.

### Итог

**`metrics-legend` был точен на 27.07 и с тех пор не обновлялся.** Это не «протух», но и не «актуален»: определения 15 метрик, скорее всего, в силе, а охват отстал минимум на три отчёта.

Проверить формулы по существу можно только сверив их с кодом расчёта - а код у нас только в виде описаний из 12 страниц. Это ещё один аргумент за то, чтобы получить репозиторий.

---

## Что дают эндпоинты (и чего не дают)

Из 12 копий вытащено 67 адресов `/api/*`. Формул они не содержат - расчёт живёт в серверном коде. Но кое-что извлекается.

### Машиночитаемые идентификаторы метрик

В `Trader_Operational` параметр `metric=` принимает ровно десять значений, и они однозначно ложатся на `metrics-legend`:

```
payin_volume  payout_volume  active_traders  active_accounts  cr
auto_pct  avg_payin_trader  settlement  settle_payin_pct  statement_pct
```

Это ключ связи между глоссарием и API: реестр метрик платформы можно предзаполнить этими идентификаторами, а не придумывать свои.

### Один смысл - разные идентификаторы

Собрав идентификаторы и имена полей по всем отчётам, видно то же расслоение, что и в определениях, только на уровне имён:

| Смысл | Как называется в разных отчётах |
|---|---|
| PayIn Volume | `payin_volume`, `payin`, `payin_inr`, `total_volume`, `d_volume`, `rk_total_payin`, `rk_volume` |
| Active Traders | `active_traders`, `unique_traders`, `day_traders`, `n_traders`, `rk_active_count` |
| Active Accounts | `active_accounts`, `unique_accounts`, `used_accounts`, `total_accounts`, `rk_used_accounts` |
| CR | `cr`, `cr_pct`, `cr_fin` |
| Settle/PayIn % | `settle_payin_pct`, `settle_pct` |
| Deposit | `deposit_inr`, `depo_inr` |
| Speed | `payin_speed_min`, `payout_speed_min`, `pp_p90`, `ttfp_p90`, `fc_p90`, `l5_speed` |

Оговорка: часть этих строк - идентификаторы метрик в API, часть - имена полей в ответах. Разделить одно от другого без примеров ответов нельзя.

Практический вывод: поиск метрики в платформе должен работать и по техническим именам, а не только по человеческим. Аналитик ищет `cr_fin`, а не «Conversion Rate».

### Архитектурные факты из списка эндпоинтов

- `/api/scoreboard/refresh` - есть ручное обновление, значит **предрасчёт существует**, данные не всегда считаются на лету.
- `/api/weekly/health` возвращает `last_refresh_ist` - **механизм свежести данных уже есть**, его можно показывать в платформе.
- `/api/scoreboard/export` - **серверный экспорт уже реализован** хотя бы в одном отчёте. Это важно для решения «выгрузка уважает права»: в браузерном экспорте через `xlsx.full.min.js` права соблюсти невозможно, в серверном можно.
- `/api/me?report=<slug>` - проверка доступа на уровне отчёта **уже работает**, её не нужно изобретать.
- `/api/filters` встречается в трёх отчётах, но рядом живут `/api/weekly/filters`, `/api/churn/filters`, `/api/affiliate/filters` - фильтры частично общие, частично продублированы.
- Есть «безымянные» эндпоинты без префикса отчёта: `/api/daily`, `/api/monthly`, `/api/traders`, `/api/detailed`. Похоже на остатки более раннего общего API.

### Чего эндпоинты не дают

Формул, фильтров, источников данных и причин расхождения цифр. На вопрос «почему в двух отчётах разный PayIn Volume» они не отвечают - отвечает `metrics-legend` и код расчёта.
