[
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Трейдер",
  "description": "Ім\\'я провайдера (AccountProvider) у платіжній системі.",
  "pattern": "cols",
  "key": "n"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Score",
  "description": "Загальний бал 0–100 = зваж. сума 8 метрик: PO_P90×20% + PI_P90×18% + CR×18% + Settle×15% + Stmt×10% + Auto×7% + AvgVol×7% + Cost×5%.",
  "pattern": "cols",
  "key": "sc"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Zone",
  "description": "High (≥53), Mid (29–52), Low (≤29). Зони відкалібровані на ~25/50/25 рози розподілу.",
  "pattern": "cols",
  "key": "z"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "PO P90",
  "description": "PayOut P90 (хв). Менше = краще. 100=≤22.3 · 75=≤31.1 · 50=≤42.4 · 25=≤58.7 · 0=>58.7. Вага 20%.",
  "pattern": "cols",
  "key": "pop"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "PI P90",
  "description": "PayIn P90 (хв). Менше = краще. 100=≤1.67 · 75=≤2.80 · 50=≤4.74 · 25=≤8.24 · 0=>8.24. Вага 18%.",
  "pattern": "cols",
  "key": "pip"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "CR,%",
  "description": "Conversion Rate = success/total×100. 100=≥52.8% · 75=≥50.9% · 50=≥49.3% · 25=≥46.4% · 0=<46.4%. Вага 18%.",
  "pattern": "cols",
  "key": "cr"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Settle,%",
  "description": "Settlement = ABS(SUM(BAA.settlement)/SUM(BAA.dayPayinAmount))×100. 100=≥65.5 · 75=≥23.1 · 50=≥8.3 · 25=≥2.3 · 0=≤0. Вага 15%.",
  "pattern": "cols",
  "key": "sr"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Stmt,%",
  "description": "Statement coverage. 100=≥80 · 75=≥59.1 · 50=≥34.8 · 25=≥14.7 · 0=<14.7. Вага 10%.",
  "pattern": "cols",
  "key": "st"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Auto,%",
  "description": "Auto success = auto/success×100. 100=≥93.1 · 75=≥78.2 · 50=≥58.6 · 25=≥33.4 · 0=<33.4. Вага 7%.",
  "pattern": "cols",
  "key": "fw"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Avg Vol/Day",
  "description": "SUM(BAA.dayPayinAmount)/COUNT(DISTINCT date з dayPayinAmount>0). 100=≥302K · 75=≥176K · 50=≥106K · 25=≥42K · 0=<42K. Вага 7%.",
  "pattern": "cols",
  "key": "av"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Days",
  "description": "Кількість активних торгових днів у 30-денному вікні (з dayPayinAmount > 0).",
  "pattern": "cols",
  "key": "days"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Volume",
  "description": "Сумарний payin volume за період (з BAA.dayPayinAmount).",
  "pattern": "cols",
  "key": "vol"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Менеджер",
  "description": "Афф-менеджер з реєстру афіліатів (Google-таблиця). Рядок «Не заведено в CRM» — афіліати, яких у реєстрі немає взагалі. Це та сама група, яку Affiliate Weekly і Tier називають «— Без менеджера»: набір один, підпис на цьому борді інший (рішення замовника 2026-09-04).",
  "pattern": "cols",
  "key": "nm"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Трейдерів",
  "description": "COUNT провайдерів під афіліатами менеджера.",
  "pattern": "cols",
  "key": "tr"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Скоринг",
  "description": "Середній Total score трейдерів групи (Scoreboard, rolling 30d). Δ немає — snapshot без історії.",
  "pattern": "cols",
  "key": "sc"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Churn",
  "description": "churned / active_last_week × 100% — методологія цього ж борду (7d vs 14d), щоб вкладка сходилася з дашбордом.",
  "pattern": "cols",
  "key": "churn"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Афіліат",
  "description": "Назва афіліата (single-attribution)",
  "pattern": "cols",
  "key": "affiliate"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Менеджер",
  "description": "Менеджер з API Андрія (reports.halleg) — єдине джерело для всіх звітів",
  "pattern": "cols",
  "key": "manager"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Tier",
  "description": "A≥80 · B 60-79 · C 38-59 · C-watch<38",
  "pattern": "cols",
  "key": "tier"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Score",
  "description": "Сума 4 складових (без sub-aff буфера)",
  "pattern": "cols",
  "key": "score"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Напрям",
  "description": "▲/▬/▼ — прогноз run-rate + Δ міс-до-міс + WoW. New: внутрішньомісячна динаміка; «—» якщо даних замало",
  "pattern": "cols",
  "key": "dir"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Причина",
  "description": "Найбільший драйвер зміни Score vs минулий місяць (▲/▼ PayIn / Трейдери / Avg Score). Блокер перекриває.",
  "pattern": "cols",
  "key": "reason"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "PayIn M",
  "description": "PayIn за місяць (млн INR). При наведенні — повне число",
  "pattern": "cols",
  "key": "payin_m"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Активні",
  "description": "Трейдери зі статусом active",
  "pattern": "cols",
  "key": "traders"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Avg Score",
  "description": "Середній Trader Scoreboard (rolling-30d)",
  "pattern": "cols",
  "key": "avg_score"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Scale★",
  "description": "50-99→+5 100-149→+8 150+→+10",
  "pattern": "cols",
  "key": "pts_scale"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Sub-aff",
  "description": "Буфер (не в Tier)",
  "pattern": "cols",
  "key": "subaff"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Прогноз",
  "description": "Score/Tier. Для New — прогнозний тир за поточним Score («71 → Tier B»)",
  "pattern": "cols",
  "key": "forecast"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Днів до клас.",
  "description": "Для New: зворотний відлік до класифікації (з 30 днів)",
  "pattern": "cols",
  "key": "d2c"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Потенціал↑",
  "description": "Балів до наступного тиру",
  "pattern": "cols",
  "key": "pot_up"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Ризик↓",
  "description": "Запас балів до нижнього тиру",
  "pattern": "cols",
  "key": "pot_dn"
 },
 {
  "report": "Affiliate_Tier_Board",
  "slug": "trader-affiliate-tier",
  "name": "Стан",
  "description": "Блокери та lifecycle",
  "pattern": "cols",
  "key": "flags"
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "PayIn",
  "description": "Сума вхідних за тиждень (operation=payin), INR. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "PayOut",
  "description": "Сума виплат (operation=payout), INR. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Сетл",
  "description": "Settlement (expenses category=settlement). Валюта — за перемикачем. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "CR %",
  "description": "Конверсія: успішні ÷ всі payin-транзакції (status completed/successed_by_partner) — як у Trader Operational. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Активних",
  "description": "Унікальні трейдери з ≥1 PayIn за тиждень. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Нові каб.",
  "description": "Нові кабінети, створені цього тижня. Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Запущено",
  "description": "Трейдери з 1-м PayIn цього тижня (активація). Δ — до пред. тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Score",
  "description": "Середній Trading Score трейдерів афіліата (rolling-30d snapshot)",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ PayIn %",
  "description": "Зміна PayIn до попереднього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ PayOut %",
  "description": "Зміна PayOut до попереднього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Сетл",
  "description": "Settlement (expenses category=settlement). Валюта — за перемикачем",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ Сетл %",
  "description": "Зміна Settlement до попереднього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "CR %",
  "description": "Конверсія: успішні ÷ всі payin-транзакції (як у Operational)",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ CR %",
  "description": "Зміна CR% до попереднього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Активних трейдерів",
  "description": "Унікальні трейдери з ≥1 PayIn за тиждень (uniqExact provider)",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ Актив.",
  "description": "Зміна активних до попереднього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Нові кабінети",
  "description": "Нові provider-кабінети, створені цього тижня",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ Нові каб.",
  "description": "Зміна нових кабінетів",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Запущено",
  "description": "Трейдери з 1-м PayIn цього тижня (активація)",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Δ Запущ.",
  "description": "Зміна запущених",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Avg Score",
  "description": "Середній Trading Score (rolling-30d snapshot)",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Sub-aff L2",
  "description": "ПРОТОТИП (гіпотеза): к-сть L2 суб-афіліатів — на 1 позицію глибше за майстра в ланцюгу. Питання 6 ТЗ",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Affiliate_Weekly_Report",
  "slug": "trader-affiliate-weekly",
  "name": "Sub-aff L3",
  "description": "ПРОТОТИП (гіпотеза): к-сть L3 суб-афіліатів — на 2 позиції глибше за майстра",
  "pattern": "colfn",
  "key": null
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Total CR",
  "description": "COUNT(status='completed') / COUNT(*). Джерело: payments.status · type='payin'",
  "pattern": "cols",
  "key": "cr"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "% AutoPayin",
  "description": "COUNT(completed AND edited_by_support=false) / COUNT(completed). Джерело: payments.edited_by_support",
  "pattern": "cols",
  "key": "auto"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "ARPU / Avg Check",
  "description": "SUM(amount WHERE completed) / COUNT(completed). Джерело: payments.amount",
  "pattern": "cols",
  "key": "arpu"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Amount IN",
  "description": "SUM(amount) WHERE type='payin' AND completed. Джерело: payments.amount · провайдер через bank_accounts.provider_pid",
  "pattern": "cols",
  "key": "amt"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "AVG speed",
  "description": "avg(updatedAt − createdAt), success payin, БЕЗ апілів (PAYIN AVG чистий). Джерело: payments.source_updated_at − source_created_at · виключено payin з appeals. Методика @la_grange_FC. Для ротованих провайдерів абсолют плаває через атрибуцію (Finaxis)",
  "pattern": "cols",
  "key": "speed"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Settlement",
  "description": "−SUM(amount − fee) completed — нетто після комісії. Джерело: payments.amount, payments.fee (НЕ з settlements/expenses). Підтверджено замовником; абсолют занижений для ротованих провайдерів",
  "pattern": "cols",
  "key": "settle"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Amount OUT",
  "description": "SUM(ABS(amount)) WHERE payout AND completed. Джерело: payments.amount (для SLU ≈ 0)",
  "pattern": "cols",
  "key": "amtout"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Оборот G-I",
  "description": "Amount IN + Settlement(додатний) + Amount OUT — сукупний рух коштів. Джерело: SUM(amount payin) + SUM(amount − fee) + SUM(ABS(amount payout)), completed. Приклад Finaxis: 168 244 736 + 156 230 292 + 0 = 324 475 028. Settlement береться за модулем (у колонці Settlement він зі знаком −)",
  "pattern": "cols",
  "key": "gi"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Сер/день",
  "description": "Amount IN / активні дні (де ≥20 completed). Джерело: підтверджено замовником — не календарні дні",
  "pattern": "cols",
  "key": "avgd"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Днів 20+",
  "description": "К-сть діб IST де COUNT(completed) ≥ 20. Джерело: payments агрегація (провайдер × день)",
  "pattern": "cols",
  "key": "days20"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Total Requests",
  "description": "COUNT(*) payin-заявок. Джерело: payments · partner_pid",
  "pattern": "cols",
  "key": "req"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Success",
  "description": "COUNT(completed) payin. Джерело: payments.status",
  "pattern": "cols",
  "key": "succ"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Reject",
  "description": "COUNT(rejected) payin. Джерело: payments.status",
  "pattern": "cols",
  "key": "rej"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "CR",
  "description": "Success / Requests. Джерело: payments.status",
  "pattern": "cols",
  "key": "cr"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "ARPU",
  "description": "Total PayIn / Success. Джерело: payments.amount",
  "pattern": "cols",
  "key": "arpu"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Avg Daily PayIn",
  "description": "Total PayIn / календарних днів періоду. Джерело: розрахунок",
  "pattern": "cols",
  "key": "avgpayin"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "% First",
  "description": "1 − % Second — частка нових платників (унікальні рахунки). Джерело: senderAccount = payments.counterparty_account. secondsend=1, якщо max(completed_count) по (мерч × рахунок) ≥ 3. За скриптом @la_grange_FC (SenderAccountPayinAggregate реалізовано в Hermes)",
  "pattern": "cols",
  "key": "first"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "% Second+",
  "description": "distinct(рахунок з secondsend=1) / distinct(рахунок) у періоді. Джерело: payments.counterparty_account · secondsend = max(completed per partner) ≥ 3. per_sender/eligible_send за скриптом @la_grange_FC — пряма реалізація ops-борд-логіки в Hermes",
  "pattern": "cols",
  "key": "second"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Total PayIn",
  "description": "SUM(amount) WHERE payin AND completed. Джерело: payments.amount · partner_pid",
  "pattern": "cols",
  "key": "payin"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Total PayOut",
  "description": "SUM(ABS(amount)) WHERE payout AND completed. Джерело: payments.amount",
  "pattern": "cols",
  "key": "payout"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Avg Daily PayOut",
  "description": "Total PayOut / календарних днів. Джерело: розрахунок",
  "pattern": "cols",
  "key": "avgpayout"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "PayOut ARPU",
  "description": "Total PayOut / COUNT(payout completed). Джерело: payments.amount",
  "pattern": "cols",
  "key": "payoutarpu"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "AVG Total Time",
  "description": "avg(updatedAt − createdAt), success payin (PAYIN AVG загальний, З апілами). Джерело: payments.source_updated_at − source_created_at. Методика @la_grange_FC. Росте заднім числом як апіли дорешуються — старі періоди вищі за момент вигрузки",
  "pattern": "cols",
  "key": "time"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Requests",
  "description": "COUNT(*) payin для пари. Джерело: payments · partner_pid × провайдер(bank_account)",
  "pattern": "cols",
  "key": "req"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Success",
  "description": "COUNT(completed). Джерело: payments.status",
  "pattern": "cols",
  "key": "succ"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Reject",
  "description": "COUNT(rejected). Джерело: payments.status",
  "pattern": "cols",
  "key": "rej"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "ARPU",
  "description": "Amount IN / Success. Джерело: payments.amount",
  "pattern": "cols",
  "key": "arpu"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Amount IN",
  "description": "SUM(amount) payin completed. Джерело: payments.amount",
  "pattern": "cols",
  "key": "amt"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "% Auto",
  "description": "completed∧¬edited_by_support / completed. Джерело: payments.edited_by_support",
  "pattern": "cols",
  "key": "auto"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Settlement",
  "description": "−SUM(amount − fee) completed. Джерело: payments.amount, payments.fee",
  "pattern": "cols",
  "key": "settle"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "Avg/день",
  "description": "Amount IN / календарних днів. Джерело: розрахунок",
  "pattern": "cols",
  "key": "avgd"
 },
 {
  "report": "Merchant_SLU",
  "slug": "trader-merchant-slu",
  "name": "AVG speed",
  "description": "avg(updatedAt − createdAt), success payin, БЕЗ апілів (чистий). Джерело: payments.source_updated_at − source_created_at. Методика @la_grange_FC",
  "pattern": "cols",
  "key": "speed"
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Базові поняття",
  "description": "Трейдер = AccountProvider (провайдер), атрибуція через bank_accounts.provider_pid . «Активний у вікні W» = є ≥1 payin -запис будь-якого статусу (факт спроби, не лише успіх) — саме так рахує Power BI. Вікна — півінтервали [start, end) від «сьогодні» (або дати To ): This [t−7,t) , Last [t−14,t−7) . Сьогодні (t) — відкритий край (snapshot). Affiliate — за префіксом імені трейдера ( G[P2P]→Griffin ), та сама схема, що в Trader Operational / Weekly KPI / PBI. Manager = provider_groups.name . Виключено службовий Operation provider .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Фільтри",
  "description": "Affiliate / Manager / Status / Group / Type / Trader — мультивибір, як у Weekly KPI; перераховують усі вкладки. Type=P2P за замовчуванням. From–To : To = дата «станом на» (snapshot churn на цю дату), From розширює діапазон динаміки. Update — примусове оновлення з бази. Скинути фільтр (кнопка в кожному дропдауні) очищає лише його; Reset — усі фільтри до дефолту (P2P, сьогодні).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Churned (відтік)",
  "description": "Трейдер, активний минулого тижня й не активний цього. Це тижневий event , не «всього неактивних». формула Churned This Week = active(Last [t−14,t−7)) AND NOT active(This [t−7,t)) active = ≥1 payin (будь-який статус)",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Churn rate",
  "description": "churned / active_last_week — знаменник = база минулого тижня.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Active (this / last week)",
  "description": "К-сть трейдерів з payin у вікні цього / минулого тижня.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Reactivated",
  "description": "Активний цього тижня, не активний минулого, але був активний раніше (повернувся).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "New",
  "description": "Активний цього тижня, не активний минулого, і раніше payin не було (новий).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Net retention",
  "description": "New + Reactivated − Churned — чистий приріст активної бази за тиждень.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "WoW (Δ) — чип динаміки",
  "description": "У матрицях (статуси, втрати) під числом — зміна тиждень-до-тижня: ▲ зелена = ріст, ▼ червона = спад vs попередній тиждень. Для лічильників — у % , для churn rate — у pp (процентних пунктах).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Churn у динаміці",
  "description": "Потижневий перерахунок churn-event по ковзному вікну 7 календарних днів (графік: rate % + к-сть churned).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Матриця статус × тиждень",
  "description": "Поточний providers.status churned-трейдерів по тижнях (active / paused / scammer / lost…). Клітинка = к-сть + WoW Δ% . Перемикач Кількість / % : «%» = частка статусу від churned тижня. Показує, яка частина «відтоку» — не реальна втрата.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Неактивні трейдери (Statistics)",
  "description": "Список тих, хто churned станом на вибрану дату за поточним типом churn (7d / 14 / Formal — перемикач нижче): менеджер · трейдер · афіліат · статус · останній PayIn · днів мовчить . Кількість рядків = останній стовпець графіка «Churn в динаміці» (той самий розрахунок). Formal — методологія E: трейдери, чий статус на кінець поточного періоду термінальний (archive/scammer/lost/60DaysLost, audit виключено), а на кінець попереднього був робочим; стани відновлено з журналу змін статусів, тому минулі періоди не переписуються; рахуються лише трейдери, що колись мали PayIn. Клік на рядок — матриця активності по тижнях. Детальна матриця втрат — у вкладці Losses .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Losses — когорта",
  "description": "Трейдери, що за минулий тиждень перетекли з active у не-active (= churned-this-week). «Скільки недобираємо через відтік».",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Run-rate (Amount/7)",
  "description": "Денна швидкість метрики = Σ(за останні 7 активних днів) / 7 . Нормалізує тих, хто активний не всі 7 днів.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "PayIn / день (₹)",
  "description": "Run-rate обігу payin. Джерело — transactions (operation=payin), INR .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "PayOut / день (₹)",
  "description": "Run-rate обігу payout ( abs(amount) ), INR .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Settle / день ($)",
  "description": "Run-rate сетлу. Джерело — settlements.amount_usdt , USDT .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Σ Unique Deposit ($)",
  "description": "Депозит = баланс депозит-акаунта ( bank_accounts.account_balance по deposit_bank_account_pid ), USDT . Це константа на трейдера → не сумується по днях, агрегат = сума по унікальних трейдерах.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Тижнева / місячна проєкція",
  "description": "Cohort-total денний = Σ run-rate усіх трейдерів когорти. Проєкція: ×7 (тиждень) / ×30.44 (місяць, серед. днів/міс). Валова (gross) оцінка до реактивації — реальна (net) втрата нижча на величину false-churn; для фінзвіту брати confirmed-поріг. Deposit — стан, не проєктується.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Матриця втрат × тижні",
  "description": "Рядок = трейдер, колонки = 8 тижнів, клітинка = метрика за тиждень + WoW Δ% . Рядок «Разом» — сума по когорті за кожен тиждень. Перемикач PayIn / PayOut / Settle.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Reactivation — неактивні трейдери",
  "description": "Список нетермінальних трейдерів (мали PayIn за ~2 міс), відсортований за днями мовчання = днів від останньої PayIn- спроби ( payments , будь-який статус — як у Power BI). Повзунок «Вікно неактивності» 3–15 днів задає поріг N — показуються трейдери з днів мовчить ≥ N . Клік на рядок — матриця активності по тижнях (гроші з transactions ) + остання спроба PayIn. Чипи статусу фільтрують список.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Retention__Churn",
  "slug": "churn",
  "name": "Джерело даних / паритет",
  "description": "ClickHouse hermes (readonly, CDC). Churn-membership = payin- спроби (як PBI); гроші (Losses/Reactivation) = фактичний обіг (success). Звіряється з Power BI-еталоном. Дедуплікація довідників через FINAL .",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "UPI увімкнені",
  "description": "приймає payin",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Остання РУЧНА зміна Payout access",
  "description": "хто з команди (логін) і коли (IST). Джерело: supportzones «Logs → Show logs» (hermes.account_provider_events, field_changed=payoutAccess). Історія ведеться з 31.01.2026 — глибше даних не існує. «—» = ручних змін не було.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Остання БУДЬ-ЯКА зміна Payout access",
  "description": "включно з автоматичними: hook при зміні статусу, cron, system. Показує актора і час IST. «—» = змін не було.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Max Payin Amount Limit",
  "description": "макс. сума одного payin. Трейдер системно обмежений по великих payin.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Трейдери (верхняя таблиця)",
  "description": "1 рядок = 1 трейдер (агрегат по всіх його UPI). Клік по рядку → модалка з його UPI (з window toggle 1ч/24ч/7д). Trader / Manager + status-бейдж — біля імені показується бейдж лише для 3 статусів providers.status : suspicious / restricted (червоні), locked (жовтий). active та решта (audit/paused/…) — без бейджа . Restricted = усі status='restricted' (будь-яка причина, вкл. балансову), як у settings-provider. Це збігається зі sticky-блоком і supportzones. «Запрет на IN» (restrict_toggle) як бейдж прибрано — операційний налив видно в колонках Налив / Вкл.payin. Зміна — 🟢 зараз на зміні, 🔘 поза зміною. Робочі години — з providers.working_hours_from/to в IST. Логіка: пуста from/to → 24/7; from to → нічна зміна (≥from OR Вкл. payin (П.11) — перше справжнє включення будь-якого UPI трейдера за обрану дату ( bank_account_events.forClientPayin=true , IST). «—» якщо не включався в цю дату. Червоним ⚠ — запізнення відносно початку зміни. Налив — кількість UPI в наливі / усього UPI у трейдера. Balance / Limit — як у supportzones Account Providers . Balance = операційний баланс трейдера = canonical earnings_balance (Σ INR-транзакцій по його рахунках − Σ balance_movements провайдера; той самий, що в Capacity). Limit = providers.custom_limit_to_warn_about_overflow (ліміт переповнення; для трейдерів без кастом-ліміту — депозит INR як fallback, позначка ~ ). Приклад: Agent Team 230k / 600k. НЕ provider_balance і НЕ Σ account_balance_limit (старе значення давало 14.6M / 46.8млрд). % Ліміт — Balance / Limit (як supportzones, напр. 38.2%). Sub — депозит INR. Може бути від'ємним, якщо операційний баланс CR — success/total payins сьогодні. %Auto In = payin без ручної правки саппорту ( edited_by_support=0 ) / success. %Auto Out = payout, апрувнутий системою по SMS-push без перевірки антискам-відділом ( payments.checking_by = '1f122b62-3961-66aa-9d47-b390dada47a9' — UUID системного чекера SMS-push) / усі success payout. На рівні трейдера. ARPU (П.6) — середній чек payout = Σ payout success ₹ / кількість success payout за день. Сер. час — медіана часу payout у руках трейдера (processing→completed) з payment_status_history (поле time_to_complete_payout зламане в CH = const 60). PayIn ₹ — Σ успішних payin сьогодні. Аномалія (П.9): у нормі — В наливе (UPI увімкнені, приймає payin). Аномалії: OFF/SHIFT — на зміні але всі UPI вимкнені; OFF-HOURS — UPI в наливі поза зміною. Тумблер Тільки аномалії змін залишає тільки аномалії. Сортування за замовч. (П.8) — проблемні статуси (suspicious / restricted / locked / scammer) угорі, вторинно — за обсягом payin. Клік по заголовку — звичайне сортування.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Модалка Trader UPIs (по кліку)",
  "description": "Список усіх UPI цього трейдера з вікнами CR/Auto: 1 час · 24 часа · 7 дней (rolling від now() ). UPI в наливі — підсвічений зеленою рамкою. UPI-номер з 📋 — клік копіює у clipboard (toast \"Скопійовано\"). Pending — payin зі статусом pending зараз для цього UPI (count · ₹). Клік по рядку UPI → drill-down з усіма payins за вибрану дату (Settings → Date).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Тимлід фільтр",
  "description": "Каркас з 4 опціями (All / Олег / Никита / Ваня). Маппінг тимлід→менеджери ще не налаштований у backend — фільтр поки тільки додає &teamlead= у запит, що ігнорується. Після уточнення маппінгу — заробить без правок UI.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Trader Accounts (old)",
  "description": "Трейдер / Менеджер — ім'я трейдера + manager. Поряд з ім'ям — статус-pill: active (зелений), suspicious/paused/audit (жовтий), locked/restricted/scammer (червоний), інші (сірий). Джерело — providers.status . Налив — счёт принимает payin прямо сейчас : for_client_payin=1 AND is_paused=0 AND work_state='work' . Если нет — pill показывает реальный статус (OFF / PAUSED / BLOCK / ARCHIVE). Баланс / Ліміт — account_balance и account_balance_limit из bank_accounts. Прогресс-бар показывает % заполнения; зелёный 80%. depo X · Y% (под Balance / Cap) — страховой депозит трейдера в INR и % его provider_balance относительно депозита . Формула: deposit_inr = bank_accounts.account_balance (USDT по providers.deposit_bank_account_pid) × exchange_rates.rate (live, rate_type='account_provider', operation='BUY') ; %бал = providers.provider_balance / deposit_inr . Если depo=0 → \"—\" (deposit_bank_account_pid не задан или баланс депо нулевой). Значение >100% — баланс уже превышает весь депозит (тревога). Free Balance ₹ = cap − balance. Сколько ещё влезет на сам счёт до стелі. Today In / Daily Cap — daily_incoming_trx_amount и incoming_amount_limit_day . Прогрес-бар поряд показує заповнення дневного ліміту. CR today — success / total payins сегодня (по этому счёту). % Авто In = success AND edited_by_support=0 / success для PayIn (по этому счёту). Высокий = саппорт почти не правил руками. % Авто Out = success AND edited_by_support=0 / success для PayOut. На уровне трейдера (payout-заявка не привязана к bank_account), одно значение на все строки одного трейдера. Avg ticket — средний чек успешного payin за сегодня. Hist CR — last_transactions_conversion — конверсия по последним N транзакциям (готовая метрика из bank_accounts). Risk — индикатор риска вылета. См. блок ниже.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Фильтры",
  "description": "Affiliate / Manager / Status / Group / Trader / Bank Account / Date — стандартные срезы. Тільки в наливі — тумблер. При включении остаются только счета с for_client_payin=1 AND is_paused=0 AND work_state='work' на момент запроса. KPI пересчитываются в этом scope.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "⚠ Sticky-блок Suspicious / Restricted / Locked (П.2)",
  "description": "Закріплена панель угорі — завжди видима . Показує трейдерів у статусах suspicious / restricted / locked / scammer у межах поточного фільтра. Рамка червоніє, коли такі є. Клік по чипу → UPI цього трейдера. Рядки таких трейдерів у таблиці підсвічені (red/yellow). Звірка очима — supportzones. Джерело статусу — CH-репліка providers.status . Можливий незначний дрейф від prod (supportzones); якщо критично — синхронізацію CH прискорити або перейти на prod-PG.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Нові метрики верхньої панелі",
  "description": "Capacity P2P · сейчас (П.7) — вільна ємність приймання payin INR по всьому P2P у моменті, 1:1 CH-репліка lab liquidity-management → daily.capacity_aggr (фінансова специфікація). Не залежить від фільтрів групи/статусу. Per trader: Threshold = depo_usdt × FX_mid × (max_fill/100) × (1+fee/100) ; Balance = earnings_balance (CH: Σ транзакцій INR − Σ balance_movements провайдера); Capacity = MIN(ba_remaining, MAX(Threshold − Balance, 0)) . Картка: Σcapacity + fill % (Σbalance/Σthreshold) + к-ть трейдерів. Дрібні розбіжності з lab — лаг CDC-реплікації. Balance 100k+ ₹ (П.12) — трейдери з op_balance ≥ 100 000 INR (операційний баланс = supportzones = earnings_balance, не provider_balance). У поточному статус-фільтрі. Значення = Σ op_balance / кількість таких трейдерів; sub — скільки їх і Σ. 1П / 2П / 3П (П.10) — 1П = на зміні зараз (по working_hours, мають працювати); 2П = з них реально в наливі (on_shift AND in_naliv); 3П = в наливі взагалі (незалежно від зміни). Приклад: 1П-10 / 2П-5 / 3П-8 (8 = 5 у свою зміну + 3 поза зміною). ARPU payout (П.6) = Σ payout success ₹ / кількість success payout. AVG Trader Time = медіана часу payout (processing→completed) з payment_status_history по active P2P.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "Live Processing",
  "description": "PayOut-ы в статусе processing — назначены трейдеру, ждут завершения. Группировка по трейдерам : одна строка = один трейдер с несколькими висящими payout-ами. # — сколько payout-ов сейчас \"в руках\" этого трейдера. Σ Сума ₹ — суммарная сумма этих payout-ов. Найдовше очікування = max(now()−assigned_at) среди его payout-ов. Жёлтый >10м, красный >30м. Сортировка по умолчанию — Oldest wait DESC: вверху самый \"горящий\" трейдер. Сер. швидкість = медиана времени выполнения payout (processing→completed из payment_status_history ) за сегодня. Сравнение «как обычно платит» vs «сколько висит сейчас» — триггер пойти и поговорить с трейдером. Клик по строке → раскрывается список конкретных транзакций (method · amount · assigned · created · wait · source_id). В шапке секции — общий пульс: сколько трейдеров платят, Σ ₹, самый старый wait, общий avg speed по всем.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Detailed_Dashboard",
  "slug": "trader-detailed",
  "name": "KPI Row",
  "description": "PayIn ₹ — успешные payins за день (сумма + req/ok/%Auto). CR — success / total payins. PayOut ₹ — успешные payouts за день + %Auto Out. ARPU payout + AVG Trader Time — см. блок «Нові метрики». Processing #/₹ — сколько сейчас \"в руках\" трейдера (+ avg wait с момента назначения). Settle ₹ — settlement за день (expenses code='settlement'). Capacity P2P · сейчас , Balance 100k+ , 1П / 2П / 3П — см. блок «Нові метрики верхньої панелі».",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Діапазон",
  "description": "скільки трейдерів-годин знадобиться у best/worst випадку (мінімальний/максимальний попит з 4 historical samples).",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Demand multiplier",
  "description": "у скільки разів виросте PayIn",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Cheque per provider",
  "description": "у скільки разів виросте чек",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Realized so far",
  "description": "Сума фактичного PayIn у завершених годинах сьогодні (з Transaction).",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Projected remaining",
  "description": "Прогноз PayIn на залишок дня = forecast_mean для current (часткова година) + future hours.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Total day (mean)",
  "description": "Очікуваний підсумок дня = realized so far + projected remaining.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Sum Recommended (24h)",
  "description": "Сума recommended за всі 24 години = Σ (demand × buffer / saturated). Past hours використовують факт, future — прогноз.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Total forecast (mean)",
  "description": "Сумарний прогнозований PayIn на 24 години завтра. Σ mean forecast по кожній годині (4 historical same-weekday samples, detrended).",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Sum Recommended (mean)",
  "description": "Сума рекомендованих трейдерів-годин на 24 години завтра = Σ (forecast × buffer / saturated). На вибраному P зі слайдера.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Realized so far",
  "description": "Сума фактичного PayIn у завершених годинах.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Projected remaining",
  "description": "Прогноз PayIn на залишок дня.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Total day (mean)",
  "description": "Очікуваний підсумок дня.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Sum Recommended v2 (24h)",
  "description": "Сума P50 forecast + actual past по 24 годинах сьогодні.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Sum Forecast Demand",
  "description": "Сумарний прогнозований PayIn за 24 години.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_Hourly_Calculator",
  "slug": "trader-hourly-calculator",
  "name": "Sum Recommended v2",
  "description": "Сума P50 forecast active count за 24 години завтра.",
  "pattern": "label-tip",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "PayIn Volume",
  "description": "сума PayIn-транзакцій за період",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Active Traders Unique",
  "description": "унікальні трейдери з PayIn > 0 за період",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "AVG Active Traders",
  "description": "середня кількість активних трейдерів на день",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "AVG PayIn/Trader",
  "description": "обсяг PayIn / сума денних активних трейдерів",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Deposit",
  "description": "кумулятивний депозит на останній день періоду (без archive/Payable)",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Settle %",
  "description": "частка settlement від PayIn Volume",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Vol/Dep Ratio",
  "description": "(PayIn за день) / (депозит активних × 93)",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "New Traders",
  "description": "трейдери з першою PayIn-транзакцією у цьому періоді",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn 7D",
  "description": "були активні (спроба PayIn) у попередньому періоді, неактивні в поточному",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn 7D %",
  "description": "частка відтоку: Churn 7D / активних у попередньому періоді. Нормалізує відтік до розміру бази",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn Formal",
  "description": "присвоєно формальний статус відтоку (Archive/Scammer/Lost/60DaysLost) у цьому періоді",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Вкладка Weekly",
  "description": "KPI-карточки — 12 метрик за текущую неделю с сравнением с предыдущей (% изменения). Churn-карточки показывают абсолют и % долю вместе: Churn 7D · Churn 7D %, Churn Formal · Churn Formal %. Графики — Active Traders Unique & PayIn Volume (комбо), AVG Active Traders, New Traders, Settle % & Deposit, Vol/Dep Ratio, Churn 7D & Churn Formal. Прогноз — на последнем баре пунктирный блок показывает прогноз до конца периода (Hourly Profile Scaling). Tooltip: Fact + Forecast = Total. Таблица — понедельное сравнение всех метрик с % изменения, включая Churn 7D и Churn Formal.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Вкладка Daily",
  "description": "Аналогично Weekly, но в разрезе дней. Последние 30 дней с графиками, прогнозом и таблицей Day-over-Day.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Вкладка Monthly",
  "description": "Аналогично Weekly, но в разрезе месяцев. Прогноз до конца текущего месяца.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Фильтры",
  "description": "Affiliate / Manager / Payment Method / Status / Group / Trader — все графики и таблицы пересчитываются при изменении. Group = P2P — по умолчанию. Оновити — принудительное обновление из базы (очистка кеша). Скинути — сброс всех фильтров.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Обсяг PayIn",
  "description": "Сумма успешных payin транзакций (из таблицы Transaction). Включаются только провайдеры с общим объёмом > 5,000. SQL-query ▾ SELECT SUM(tran.amount) AS payin_volume FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON ba.id = tran.\"bankAccount\" WHERE tran.operation = 'payin' AND ba.\"accountProvider\" IN ( -- Только провайдеры с total payin > 5000 SELECT pid FROM vol_daily GROUP BY pid HAVING SUM(volume) > 5000 )",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Унікальні активні трейдери",
  "description": "Количество уникальных трейдеров (провайдеров), у которых сумма payin > 0 за выбранный период. Каждый трейдер считается один раз. SQL-query ▾ SELECT COUNT(*) FROM ( SELECT ba.\"accountProvider\" AS pid FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON ... WHERE tran.operation = 'payin' GROUP BY ba.\"accountProvider\" HAVING SUM(tran.amount) > 0 ) sub",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Сер. активні трейдери",
  "description": "Среднее количество активных трейдеров в день. Сумма ежедневных уникальных трейдеров / количество дней. SQL-query ▾ SELECT AVG(day_traders) AS avg_active FROM ( SELECT dt, COUNT(DISTINCT pid) AS day_traders FROM vol_daily WHERE operation = 'payin' AND volume > 0 GROUP BY dt ) daily_active",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "AVG PayIn per Trader",
  "description": "Средний объём PayIn на одного трейдера. Общий объём / сумма ежедневных трейдеров. SQL-query ▾ SELECT SUM(payin_volume) / SUM(day_traders) AS avg_payin -- day_traders: ежедневный DISTINCTCOUNT -- НЕ среднее, а именно SUM",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Нові трейдери",
  "description": "Трейдеры, у которых первая payin транзакция попадает в выбранный период. SQL-query ▾ SELECT COUNT(*) AS new_traders FROM ( SELECT ba.\"accountProvider\" AS pid, MIN((tran.\"createdAt\" AT TIME ZONE 'UTC' AT TIME ZONE 'Asia/Kolkata')::date) AS first_tr FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON ... WHERE tran.operation = 'payin' GROUP BY 1 ) ftx WHERE first_tr >= :period_start",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Deposit Volume",
  "description": "Кумулятивный депозит на последний день периода. Исключаются архивные трейдеры и аккаунты 'Payable'. SQL-query ▾ SELECT SUM(dc.cum_dep) AS deposit FROM period_last_dt pld JOIN dep_cumulative dc ON dc.dt = pld.last_dt JOIN \"AccountProvider\" ap ON ap.id = dc.pid WHERE ap.status != 'archive' AND ap.name NOT LIKE '%Payable%'",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Сетл %",
  "description": "Доля settlement от PayIn Volume. SQL-query ▾ SELECT SUM(settlement) / NULLIF(SUM(payin_volume), 0) AS settle_pct -- settlement: из BankAccountAggregate -- payin_volume: из Transaction",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Vol/Dep Ratio",
  "description": "Коэффициент эффективности капитала. Дневной PayIn / (депозит × 93). SQL-query ▾ SELECT (SUM(payin_volume) / active_days) / (dep_active_traders * 93) AS vol_dep -- active_days: дни с payin > 0 -- dep_active_traders: cumulative_dep -- на LASTDATE для трейдеров -- активных в последний день периода",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Прогнозирование (Forecast)",
  "description": "Метод: Hourly Profile Scaling. Берутся последние 4 недели того же дня недели, строится профиль почасового накопления. Текущий факт / % прошедшего времени = прогноз. SQL-query ▾ -- Профиль по часам (тот же день недели) SELECT hr, SUM(vol) OVER (ORDER BY hr) / SUM(vol) OVER () AS cum_pct FROM ( SELECT EXTRACT(hour FROM ...) AS hr, SUM(tran.amount) AS vol FROM \"Transaction\" tran WHERE EXTRACT(isodow FROM ...) = EXTRACT(isodow FROM now()) AND ... >= now() - '28 days' GROUP BY 1 ) -- Прогноз = actual / cum_pct",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn 7D",
  "description": "Кількість трейдерів, які були активні в попередньому періоді, але НЕ активні в поточному (set-difference по періодах). Вимірює «відтік» по тижнях/днях/місяцях. Активність = факт спроби PayIn у таблиці payments (будь-який статус, не лише успішні) — вирівняно зі звітом /churn. Universe = трейдери з provider.type='p2p' , без Operation provider та %QA_Test%. Періоди — календарні (ISO-тижні Пн-Нд), тому значення близькі до /churn, але не ідентичні (там ковзні 7-денні вікна).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn 7D %",
  "description": "Частка відтоку: Churn 7D / кількість активних у попередньому періоді × 100 . Нормалізує відтік до розміру бази: абсолютний Churn 7D природно росте разом із базою трейдерів, тому +50% у штуках може означати незмінний або навіть нижчий ВІДСОТОК відтоку. Чисельник і знаменник — з одного universe (PayIn-спроби в payments, provider.type='p2p'). Зміна в таблиці — у процентних пунктах (pp). Зростання = погіршення (червоний).",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn Formal",
  "description": "Кількість трейдерів, чий статус на кінець періоду — термінальний ( Archive, Scammer, Lost, 60DaysLost ), а на кінець попереднього періоду був робочим (методологія E — «дельта станів на межах періодів», зафіксована 2026-08-21). Стани відновлюються з журналу змін статусів account_provider_events . Чому журнал, а не снепшот: стара логіка читала поточний статус і status_updated_at — при переведенні lost → archive подія «переїжджала» на нову дату і статус, історія переписувалась заднім числом, а реанімовані трейдери зникали з минулих періодів. За журналом минулі значення метрики більше не змінюються. Властивості: та сама модель «порівняння двох фотографій», що і в Churn 7D; клацання статусами всередині періоду (адмін-флапінг) невидимі; трейдер, реактивований і згодом знову втрачений, чесно рахується вдруге; переходи «термінальний → термінальний» подіями не є. Статус у розкладці = статус на кінець періоду. Тільки реальні трейдери — лише ті, хто колись мав спробу PayIn у payments в межах universe provider.type='p2p' (без Operation provider / %QA_Test%). Audit виключено — тимчасовий робочий статус.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Churn Formal %",
  "description": "Частка формального відтоку: Churn Formal / кількість активних трейдерів у попередньому періоді × 100 . Знаменник той самий, що у Churn 7D % (активні = ≥1 спроба PayIn за попередній період) — обидві частки порівнянні між собою. При базі, що росте, абсолютний Churn Formal зростає механічно; відсоток показує реальну інтенсивність відтоку.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Matrix (внизу кожної вкладки)",
  "description": "Розбивка однієї метрики по вимірах: рядки — Affiliate / Manager / Trader (перемикач), колонки — періоди вкладки (тижні / дні / місяці). Кнопки метрик: Volume, Traders, AVG Tr, AVG/Tr, Deposit, Settle%, V/D, New, Churn 7D, Churn Fm. Рядок Total рахується з сирих компонентів (для ratio-метрик — не сумою клітинок). Для виміру Trader показуються топ-200 рядків за сумою. Фільтри й діапазон дат застосовуються. CSV — повні числа без скорочень.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Тип периода",
  "description": "Daily: сегодня vs вчера. Weekly: ISO Пн-Вс vs предыдущая. Monthly: месяц vs предыдущий.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Источник данных",
  "description": "PostgreSQL (DigitalOcean). SQL идентичен Power BI Trader_Detailed M-query. Грейн: Provider × Day. IST (UTC+5:30). Кеш: 1 час, авто-обновление 30 мин.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Статуси трейдерів — Active / Paused / Restricted / Suspicious",
  "description": "Active — трейдер повністю активний, може робити PayIn і PayOut. Paused — виставляється автоматично якщо трейдер не користується кабінетом 1 тиждень (немає PayIn тощо). Перевести в Active можуть лише співробітники з КС. Paused / Active — Paused (paused), Active (active) Restricted — виставляється автоматично, коли трейдер виконує PayOut і накопичується багато PayOut, не перевірених антискамом. В Active переводить антискам після перевірки. Трейдер не може ввімкнути акаунти на PayIn. Restricted / Обмежений (restricted) Suspicious — виставляється і знімається антискамом: використовується при проблемах з перевіркою доказів від трейдера по PayOut, або багато реджектів PayIn підряд, іноді автоматично (якщо трейдер при PayOut прикріпив поганий скрін). Трейдеру недоступні функції PayOut і PayIn, не може ввімкнути акаунти. Suspicious / Підозрілий (suspicious) Locked — статус можуть виставляти Support, менеджери, антискам — у кожного відділу свої причини. Locked / Заблокований (locked)",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "Статуси трейдерів — формальний відтік (Churn Formal)",
  "description": "Archive — ставиться фінами коли немає жодної активності в кабінеті трейдера на стадії інтеграції (новий кабінет, депозит не внесено, трейдер АФК — кабінет архівують), або після аудиту при завершенні співпраці, або після тривалої неактивності після списання балансу. Archive / Архів (archive) Scammer — ставить антискам після перевірок трейдера та виявлення доказів скаму. Scammer / Шахрай (scammer) Lost — статус ставиться автоматично якщо трейдер не користується кабінетом 2 тижні і немає активності. Або якщо затягується процес аудиту і щоб трейдер не світився в портфелі менеджера — Саша ставить вручну. Lost / Втрачений (lost) 60DaysLost — трейдер неактивний довго. Фіни орієнтуються на цей статус щоб списати баланс і перевести дашборд в архів. 60DaysLost / Втрачений 60 днів (60DaysLost) Audit — ставиться і знімається фінвідділом. Трейдер не може працювати до завершення аудиту і переведення в Active. Audit / Аудит (audit) У метриці Churn Formal враховуються термінальні статуси Archive, Scammer, Lost, 60DaysLost — за методологією E: подія є, коли статус на кінець періоду термінальний, а на кінець попереднього був робочим (стани — з журналу змін статусів, минуле не переписується). Audit не враховується — це тимчасовий робочий статус, а не остаточний відтік.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_KPI_Dashboard",
  "slug": "trader-kpi",
  "name": "${l.m}",
  "description": "${l.d}${l.sql?` SQL-query ▾ ${l.sql} `:''}",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "PayIn Volume",
  "description": "Сумма успешных payin транзакций (₹) за этот час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "PayOut Volume",
  "description": "Абсолютная сумма payout транзакций (₹) за этот час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Active Traders",
  "description": "Количество уникальных трейдеров с PayIn > 0 в этот час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Active Accounts",
  "description": "Количество уникальных банковских счетов с активностью в этот час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "% Auto",
  "description": "Доля автоматически обработанных заявок (editedBySupport=false) от успешных за час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Avg PayIn/Trader",
  "description": "Средний PayIn Volume на одного активного трейдера за час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Settlement",
  "description": "Сумма settlement расходов (₹) за этот час.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Out Pending #",
  "description": "Количество payout-заявок в статусе pending в момент HH:mm. ГЛОБАЛЬНАЯ метрика — pending payout не имеет accountProvider, поэтому фильтры по трейдеру не применяются. Учитывается только Pmt Method.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Out Pending ₹",
  "description": "Сумма payoutAmount payout-заявок в статусе pending в момент HH:mm. Учитывается только Pmt Method.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Unassigned (#)",
  "description": "Количество ClientPayin созданных в этом получасе с bankAccount IS NULL — заявки не получившие счёт. Учитывается ТОЛЬКО фильтр Pmt Method.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Unassigned (₹)",
  "description": "Сумма ClientPayin созданных в этом получасе с bankAccount IS NULL. Учитывается ТОЛЬКО фильтр Pmt Method.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Plan (traders)",
  "description": "кількість трейдерів формально на зміні у цю годину (з AccountProvider.workingHoursFrom..To). Сирий розклад без врахування фактичної явки.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Active (traders)",
  "description": "фактична кількість unique трейдерів які мали хоча б 1 транзакцію у цю годину.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Avg accounts/hr",
  "description": "середня кількість bank-account-ів задіяних на одного активного трейдера в цю годину.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Status General (v1)",
  "description": "глобальний стан ВСІХ P2P трейдерів за цю годину, незалежно від фільтра. DEFICIT = система в цілому недоукомплектована (навіть якщо твоя команда у нормі). Розраховано з Trader Hourly Calculator v1.",
  "pattern": "title",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "PayIn Volume",
  "description": "Сумма успешных payin транзакций (₹). Из таблицы Transaction, operation=payin. Учитываются только провайдеры с объёмом > 5,000.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "PayOut Volume",
  "description": "Абсолютная сумма payout транзакций (₹). ABS(SUM) из таблицы Transaction, operation=payout.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Active Traders",
  "description": "Количество уникальных трейдеров с PayIn > 0 за день. Считается из Transaction по accountProvider.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Active Accounts",
  "description": "Сумма уникальных банковских счетов с активностью по каждому часу и трейдеру за день.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "CR, %",
  "description": "Конверсия — доля успешных заявок (successed_by_partner) от общего числа ClientPayin за день.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "% Auto",
  "description": "Доля автоматически обработанных заявок (editedBySupport=false) от успешных ClientPayin.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Avg PayIn/Trader",
  "description": "Средний PayIn Volume на одного активного трейдера за день.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Settlement",
  "description": "Сумма settlement расходов (₹). Из Transaction → Expense → ExpenseCategory(Settlement).",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Settle/PayIn, %",
  "description": "Доля settlement от PayIn Volume. Показывает какой % входящего потока уходит на расчёты.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Statement, %",
  "description": "Доля банковских счетов, для которых загружена выписка (BankAccountFile) за период активности.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "CR, %",
  "description": "Конверсия — доля успешных заявок (successed_by_partner) от общего числа ClientPayin за час.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Settle/PayIn, %",
  "description": "Доля settlement от PayIn Volume за этот час.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Вкладка Daily",
  "description": "KPI-карточки — 10 ключевых метрик за сегодня с сравнением со вчерашним днём (% изменения). График — выбранная метрика по дням. Выходные дни выделены оранжевым. Переключение метрики — кнопками над графиком. TOP-5 — пять лидеров по выбранной метрике в разрезе Affiliate / Manager / Trader. Пересчитываются при смене метрики. Матрица — сводная таблица: строки = Affiliate / Manager / Trader (переключатель), столбцы = даты. Сортировка по Total. Переключение разреза — кнопками Affiliate / Manager / Trader. Day-over-Day — таблица с ежедневным сравнением всех метрик. Зелёные/красные стрелки показывают рост/падение относительно предыдущего дня.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Вкладка Hourly",
  "description": "Почасовая статистика за выбранный день. Выберите дату в выпадающем списке. KPI-карточки — суммарные/средние значения за день. График — выбранная метрика по часам. Показывает только часы с данными (будущие часы скрыты). Таблица — все метрики по каждому часу.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Вкладка Shifts",
  "description": "Контроль смен: кто вышел на смену, кто нет, кто работает вне своей смены. Смены (Plan) — плановое время работы из workingHoursFrom/To . S1: 06:00–14:00 IST, S2: 13:00–22:00, S3: 20:00–07:00. 24/7 = 00:00–24:00. Активность (Fact) — трейдер активен в час H, если PayIn > 0 или PayOut > 0 за этот час по IST. Цвета ячеек: ■ Active in shift, ■ Planned (впереди), ■ Missed (пропуск), ■ Active outside (вне смены). Coverage % = Active / Plan × 100%. Зелёный ≥80%, жёлтый ≥50%, красный Hours in/out — часы активности в смену / вне смены. PayIn in/out — объём PayIn в смену / вне смены. Клик на имя — детали: смена, менеджер, 24-часовая разбивка, итоги дня.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Фильтры",
  "description": "Affiliate / Manager / Group / Status / Trader — фильтрация данных. Все графики, KPI, матрица и таблицы пересчитываются при изменении фильтра. Group = P2P — установлен по умолчанию. Hour to Hour (H2H) — для честного сравнения дней. При включении каждый день показывает данные только до текущего часа IST. Пример: сейчас 14:00 — вчерашний день показывает данные за 00:00–14:00, а не за весь день.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Выбор метрики",
  "description": "Кнопки над графиком (PayIn Volume, CR%, Active Traders и т.д.) переключают: • График по дням / часам • TOP-5 панели • Матрицу (значения в ячейках) Все 10 метрик доступны для анализа в каждом разрезе.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Обсяг PayIn",
  "description": "Сумма успешных payin транзакций из таблицы Transaction. SQL-query ▾ SELECT SUM(tran.amount) AS payin_volume FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON tran.\"bankAccount\" = ba.id JOIN \"AccountProvider\" ap ON ba.\"accountProvider\" = ap.id WHERE tran.operation = 'payin' AND (tran.\"createdAt\" AT TIME ZONE 'UTC' AT TIME ZONE 'Asia/Kolkata')::date = :dt AND ap.name != 'Operation provider'",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Обсяг PayOut",
  "description": "Абсолютная сумма payout транзакций. SQL-query ▾ SELECT ABS(SUM(tran.amount)) AS payout_volume FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON tran.\"bankAccount\" = ba.id WHERE tran.operation = 'payout' AND (tran.\"createdAt\" AT TIME ZONE 'UTC' AT TIME ZONE 'Asia/Kolkata')::date = :dt",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Активні трейдери",
  "description": "Количество уникальных провайдеров, у которых суммарный payin > 0. Группируется по провайдеру, фильтруется по SUM > 0 (не по каждой транзакции отдельно). SQL-query ▾ SELECT COUNT(*) AS active_traders FROM ( SELECT ba.\"accountProvider\" AS pid FROM \"Transaction\" tran JOIN \"BankAccount\" ba ON tran.\"bankAccount\" = ba.id WHERE tran.operation = 'payin' AND (tran.\"createdAt\" ...)::date = :dt GROUP BY ba.\"accountProvider\" HAVING SUM(tran.amount) > 0 ) sub",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Активні рахунки",
  "description": "Сумма уникальных банковских аккаунтов по каждому часу и трейдеру. Один аккаунт, активный в 5 часах, считается 5 раз (аналог Power BI SUM(active_accounts)). SQL-query ▾ SELECT SUM(accts) AS active_accounts FROM ( SELECT dt, hr, ap.id AS tid, COUNT(DISTINCT ba.id) AS accts FROM \"ClientPayin\" cp JOIN \"BankAccount\" ba ON cp.\"bankAccount\" = ba.id JOIN \"AccountProvider\" ap ON ba.\"accountProvider\" = ap.id WHERE (cp.\"createdAt\" ...)::date = :dt GROUP BY dt, hr, ap.id ) sub",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "CR, % (Conversion Rate)",
  "description": "Конверсия — доля успешных заявок от общего числа. Успешная заявка: status IN ('completed','successed_by_partner') — новый статус 'completed' замінив 'successed_by_partner' у червні 2026. SQL-query ▾ SELECT SUM(CASE WHEN cp.status IN ('completed','successed_by_partner') THEN 1 END)::float / NULLIF(COUNT(cp.id), 0) AS cr_pct FROM \"ClientPayin\" cp JOIN \"BankAccount\" ba ON cp.\"bankAccount\" = ba.id JOIN \"AccountProvider\" ap ON ba.\"accountProvider\" = ap.id WHERE (cp.\"createdAt\" ...)::date = :dt",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "% Авто",
  "description": "Доля автоматически обработанных заявок — без ручного вмешательства поддержки (editedBySupport = false). SQL-query ▾ SELECT SUM(CASE WHEN cp.status IN ('completed','successed_by_partner') AND cp.\"editedBySupport\" = false THEN 1 END)::float / NULLIF(SUM(CASE WHEN cp.status IN ('completed','successed_by_partner') THEN 1 END), 0) AS auto_pct FROM \"ClientPayin\" cp ...",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Сер. PayIn/трейдер",
  "description": "Средний объём PayIn на одного активного трейдера. SQL-query ▾ SELECT SUM(payin_volume) / NULLIF(active_traders, 0) AS avg_payin_trader -- payin_volume: SUM из Transaction -- active_traders: COUNT(DISTINCT provider) -- GROUP BY provider HAVING SUM(amount) > 0",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Сетлмент",
  "description": "Сумма settlement расходов. Источник: Transaction → Expense → ExpenseCategory, где category = 'Settlement'. SQL-query ▾ SELECT SUM(tran.total) * (-1) AS settlement FROM \"Transaction\" tran JOIN \"Expense\" e ON e.id = tran.\"expenseId\" JOIN \"ExpenseCategory\" ec ON e.\"category\" = ec.id WHERE tran.operation = 'expense' AND ec.label = 'Settlement' AND (tran.\"createdAt\" ...)::date = :dt",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Сетл/PayIn, %",
  "description": "Доля settlement от PayIn Volume. Показывает, сколько средств возвращается трейдерам. SQL-query ▾ SELECT SUM(settlement) / NULLIF(SUM(payin_volume), 0) AS settle_payin_pct -- settlement: из Expense (category='Settlement') -- payin_volume: из Transaction (operation='payin')",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Виписка, %",
  "description": "Доля аккаунтов с банковской выпиской. Volume-weighted: крупный трейдер с 2000 аккаунтов правильно доминирует над мелким с 1 аккаунтом. Без двойного AVG. SQL-query ▾ SELECT SUM(has_statement)::float / NULLIF(SUM(total_accounts), 0) AS statement_pct FROM ( SELECT dt, tid, SUM(has_stmt) AS has_statement, COUNT(DISTINCT account_number) AS total_accounts FROM ( SELECT DATE(cp.\"createdAt\" + '5h30m') AS dt, ba.\"accountProvider\" AS tid, ba.\"account\" AS account_number, MAX(CASE WHEN baf.id IS NOT NULL THEN 1 ELSE 0 END) AS has_stmt FROM \"ClientPayin\" cp JOIN \"BankAccount\" ba ON ... LEFT JOIN LATERAL ( SELECT f.id FROM \"BankAccountFile\" f WHERE f.\"bankAccount\" = ba.id AND cp.\"createdAt\" BETWEEN f.\"beginDateTime\" AND f.\"endDateTime\" LIMIT 1 ) baf ON TRUE GROUP BY dt, tid, account_number ) raw GROUP BY dt, tid ) agg",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Out Pending (только Hourly)",
  "description": "Сколько payout-заявок было в статусе 'pending' в момент HH:mm — реконструкция через таблицу History. Снапшот в моменте, как если бы бот делал запрос в это время. Для каждого получаса отдельно. ВНИМАНИЕ: pending payout не имеет accountProvider (ещё не назначен трейдеру), поэтому метрика ГЛОБАЛЬНАЯ и уважает только фильтр Pmt Method. Остальные фильтры (Affiliate/Manager/Status/Group/Trader) на эту колонку не влияют. SQL-query ▾ -- 1) Найти в History моменты выхода из статуса 'pending' WITH payout_pending_end AS ( SELECT \"recordId\" AS payout_id, MIN(\"createdAt\") AS pending_end FROM \"History\" WHERE \"table\" = 'ClientPayout' AND \"logJson\"->'data'->'status'->>'old' = 'pending' GROUP BY \"recordId\" ) -- 2) Для каждого payout: pending_start=createdAt, pending_end -- 3) Для каждого получаса T: -- был pending в момент T ⇔ -- pending_start T)",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Unassigned (только Hourly)",
  "description": "ClientPayin созданные в этом получасе с bankAccount IS NULL — заявки которые не получили счёт. Колонки: # (количество) и ₹ (сумма). Уважает ТОЛЬКО фильтр Pmt Method — остальные фильтры (Affiliate/Manager/Group/Status/Trader) недоступны, потому что без bankAccount нет связи с трейдером. SQL-query ▾ SELECT COUNT(*) AS unassigned_count, COALESCE(SUM(amount), 0) AS unassigned_amount FROM \"ClientPayin\" WHERE \"bankAccount\" IS NULL AND (\"prevPendingClientPayinId\" IS NULL OR \"prevPendingClientPayinId\" = '') -- + фильтр по получасу createdAt -- + фильтр paymentMethodType (если выбран)",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Hour-to-Hour (H2H)",
  "description": "Фильтр для честного сравнения дней. При включении каждый день показывает данные только до текущего часа IST. Если сейчас 14:00 — все дни показывают 00:00–14:00. SQL-query ▾ -- Добавляется ко всем запросам: WHERE hr",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Матрица",
  "description": "Сводная таблица: строки = Affiliate / Manager / Trader, столбцы = даты, значения = выбранная метрика. Сортировка по Total убыванию. Total для процентных метрик (CR, Auto, Settle/PayIn) — средневзвешенное, не простая сумма.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "TOP-5",
  "description": "Пять лидеров по выбранной метрике в разрезе Affiliate / Manager / Trader. Пересчитывается при смене метрики. Для процентных метрик используется взвешенный расчёт.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "Источник данных",
  "description": "ClickHouse hermes. Грейн: date × hour × trader. Период: по умолчанию последние 30 дней, доступно до 90 дней истории. Часовой пояс: IST (UTC+5:30). Данные обновляются каждые 30 минут.",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Operational_Dashboard",
  "slug": "trader-operational",
  "name": "'+l.m+'",
  "description": "'+l.d+sqlBlock+'",
  "pattern": "lg-item",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Trader",
  "description": "Unique name/alias of the trader (AccountProvider).",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Score",
  "description": "Final weighted score (0-100). PO_P90*20% + PI_P90*18% + CR*18% + Settlement*15% + Statement*10% + Auto*7% + AvgVol*7% + Cost*5%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Zone",
  "description": "High (Score >=60): top ~25%. Mid (35 < Score < 60): ~50%. Low (Score <=35): bottom ~25%. Cutoffs swept to land at ~25/50/25 on live distribution.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "PO P90",
  "description": "PayOut P90 (min). Lower=better. 100pts <=14.7, 75pts <=20.6, 50pts <=29.1, 25pts <=43.9, 0pts >43.9. Weight 20%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "PI P90",
  "description": "PayIn P90 (min). Lower=better. 100pts <=0.87, 75pts <=0.97, 50pts <=1.33, 25pts <=2.78, 0pts >2.78. Weight 18%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "CR,%",
  "description": "Conversion Rate: success/total*100 (total = final statuses). 100pts >=66.5%, 75pts >=64.2%, 50pts >=62.1%, 25pts >=58.7%, 0pts <58.7%. Weight 18%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Settle,%",
  "description": "Settlement: ABS(SUM(BAA.settlement)/SUM(BAA.dayPayinAmount))*100. 100pts >=64.0%, 75pts >=22.7%, 50pts >=8.1%, 25pts >=2.6%, 0pts <=0. Weight 15%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Stmt,%",
  "description": "Statement coverage. 100pts =100%, 75pts >=93.8%, 50pts >=85.7%, 25pts >=71.0%, 0pts <71.0%/blank. Weight 10%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Auto,%",
  "description": "Auto success: auto/success*100. 100pts >=97.8%, 75pts >=95.5%, 50pts >=89.8%, 25pts >=67.7%, 0pts <67.7%. Weight 7%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Avg Vol/Day",
  "description": "SUM(BAA.dayPayinAmount) / COUNT(DISTINCT date FILTER dayPayinAmount>0). 100pts >=232K, 75pts >=146K, 50pts >=96K, 25pts >=52K, 0pts <52K. Weight 7%.",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Days",
  "description": "Active trading days in the period (payin_volume > 0).",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Trader_Scoreboard",
  "slug": "trader-scoreboard",
  "name": "Volume",
  "description": "Total payin volume for the period (INR, with thousands separators).",
  "pattern": "showM",
  "key": null
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayIn Volume",
  "description": "Сумма входящих платежей за неделю (₹). Источник: Transaction, operation='payin'. Учитывается все, кроме операторов-провайдеров. Чем выше — тем больше денег обработано.",
  "pattern": "dict",
  "key": "payin_volume"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayOut Volume",
  "description": "Сумма исходящих выплат за неделю (₹). Источник: Transaction, operation='payout' (берется абсолютное значение). Параллель к PayIn.",
  "pattern": "dict",
  "key": "payout_volume"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Active Traders",
  "description": "Количество уникальных трейдеров с PayIn-активностью в эту неделю.",
  "pattern": "dict",
  "key": "active_traders"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Active Accounts",
  "description": "Количество уникальных банковских счетов (BankAccount), с которых были payin-операции за неделю.",
  "pattern": "dict",
  "key": "active_accounts"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "CR, %",
  "description": "Conversion Rate — доля успешных payin-заявок от общего числа за неделю. Формула: COUNT(status='successed_by_partner') / COUNT(*). Чем выше — тем эффективнее обработка.",
  "pattern": "dict",
  "key": "cr"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "% Auto",
  "description": "Доля автоматически обработанных payin-заявок (без участия support). Формула: COUNT(status='successed' AND editedBySupport=false) / COUNT(status='successed'). Чем выше — тем меньше ручной работы.",
  "pattern": "dict",
  "key": "auto_pct"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Avg PayIn/Trader",
  "description": "Средний PayIn Volume на одного активного трейдера за неделю. Формула: SUM(payin) / COUNT(DISTINCT active_traders).",
  "pattern": "dict",
  "key": "avg_payin_trader"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Settlement",
  "description": "Сумма расходов категории Settlement за неделю. Источник: Transaction → Expense → ExpenseCategory.label='Settlement'. Это возвраты средств трейдерам.",
  "pattern": "dict",
  "key": "settlement"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Settle/PayIn, %",
  "description": "Доля settlement от PayIn Volume. Формула: SUM(settlement) / SUM(payin_volume). Показывает, какой процент входящего потока возвращается трейдерам.",
  "pattern": "dict",
  "key": "settle_payin_pct"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Statement, %",
  "description": "Доля банковских счетов, имеющих привязанные выписки (BankAccountFile). Volume-weighted: SUM(has_statement) / COUNT(DISTINCT ba.account). Считается на уровне ba.id с дедупликацией по account number.",
  "pattern": "dict",
  "key": "statement_pct"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayIn Speed (median, min)",
  "description": "Медианное время от создания заявки ClientPayin до её updatedAt (минут). Статусы completed + successed_by_partner. Методология согласована с ИТ (updatedAt вместо join на Transaction — транзакций может быть несколько). Чем меньше — тем быстрее работают трейдеры.",
  "pattern": "dict",
  "key": "payin_speed_min"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayOut Speed (median, min)",
  "description": "Медианное время от assignedAt до updatedAt в ClientPayout (минут). Статусы completed + successed_by_partner. Чем меньше — тем быстрее выплаты.",
  "pattern": "dict",
  "key": "payout_speed_min"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayIn Speed (average, min)",
  "description": "Среднее арифметическое время payin (минут). Может быть искажено выбросами — поэтому также показываем медиану.",
  "pattern": "dict",
  "key": "payin_speed_avg"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayOut Speed (average, min)",
  "description": "Среднее арифметическое время payout (минут). Может быть искажено выбросами.",
  "pattern": "dict",
  "key": "payout_speed_avg"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayIn Speed (P90, min)",
  "description": "90-й перцентиль времени payin (минут): 90% заявок закрываются быстрее этого значения. Показывает «хвост» медленных заявок, который не виден в медиане.",
  "pattern": "dict",
  "key": "payin_speed_p90"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "PayOut Speed (P90, min)",
  "description": "90-й перцентиль времени payout (минут): 90% выплат проходят быстрее этого значения. Показывает «хвост» медленных выплат.",
  "pattern": "dict",
  "key": "payout_speed_p90"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "N transactions",
  "description": "Количество транзакций для расчета медианы/среднего.",
  "pattern": "dict",
  "key": "n_tx"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Середній SLA IN",
  "description": "Зважений середній час від створення PayIn до підтвердження трейдером (cp.source_created_at → cp.source_updated_at) у MM:SS. Тільки успішні (status IN ('completed','successed_by_partner')). Включає очікування оплати клієнтом + обробку банку + підтвердження трейдером. Менше — краще.",
  "pattern": "dict",
  "key": "rk_avg_sla_in"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Середній SLA OUT",
  "description": "Зважений середній час від створення PayOut до прийняття трейдером (cp.source_created_at → cp.assigned_at) у MM:SS. Cap 4 години (нічні черги виключаються). Менше — краще.",
  "pattern": "dict",
  "key": "rk_avg_sla_out"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Середній % автоматичних",
  "description": "Частка успішних PayIn-ів, де SLA IN < 5 хв («автоматичні»). Рахується по топ-95% найшвидших трейдерів. Σ sharepayin / Σ cntpayin.",
  "pattern": "dict",
  "key": "rk_avg_auto"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Середній CR",
  "description": "Conversion Rate: Σ payin_success / Σ payin_total по активних трейдерах за період. Чим вище — тим ефективніша обробка.",
  "pattern": "dict",
  "key": "rk_avg_cr"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Нових трейдерів",
  "description": "Кількість провайдерів, у яких перша транзакція в системі (min(transactions.source_created_at) за payin) потрапляє в обраний період.",
  "pattern": "dict",
  "key": "rk_new_count"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Сумарний PayIn, INR",
  "description": "Загальна сума INR по успішних PayIn всіх активних трейдерів за обраний період. «Активний» = хоча б один payin у періоді.",
  "pattern": "dict",
  "key": "rk_total_payin"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Кількість активних трейдерів",
  "description": "Кількість P2P-провайдерів, у яких payin_total > 0 в обраний період.",
  "pattern": "dict",
  "key": "rk_active_count"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Кількість використаних рахунків",
  "description": "Кількість унікальних банківських рахунків (bank_accounts.account), з яких прийнято хоча б один успішний PayIn за обраний період (глобально по всій вибірці).",
  "pattern": "dict",
  "key": "rk_used_accounts"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "% завантаження виписок",
  "description": "Частка банківських рахунків, для яких завантажено банківську виписку (hermes.bank_statements — дзеркало Keystone BankAccountFile), що покриває час PayIn. Volume-weighted, за тією ж формулою що й Statement% у Trader Operational (finance-exact): рахунок за день «має виписку», якщо хоча б один його PayIn потрапляє в інтервал виписки [period_from, period_to]. Формула: Σ has_stmt (по ba.pid за день) / Σ uniqExact(ba.account) (за день). Тільки P2P, усі статуси PayIn.",
  "pattern": "dict",
  "key": "rk_statement_pct"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Трейдерів що «випали»",
  "description": "Трейдери, у яких в попередньому аналогічному за тривалістю періоді була активність (payin_total_p > 0), але в поточному — немає (payin_total = 0). Показує відтік активних.",
  "pattern": "dict",
  "key": "rk_fallen"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Tier",
  "description": "Категорія трейдера по Score (canonical Power BI пороги): Platinum ≥ 80, Gold ≥ 65, Silver ≥ 45, Bronze ≥ 30, інакше Inactive. Score — зважена сума 7 sub-score'ів (див. Methodology).",
  "pattern": "dict",
  "key": "rk_tier"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Tier — Count",
  "description": "Кількість трейдерів у даному Tier за поточний період.",
  "pattern": "dict",
  "key": "rk_tier_count"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Tier — Volume, INR",
  "description": "Сумарний Volume (PayIn) трейдерів цього Tier за поточний період.",
  "pattern": "dict",
  "key": "rk_tier_volume"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Trader",
  "description": "Назва P2P провайдера (з префіксом групи: G[P2P], D[P2P], L[P2P] тощо). Зірочка ★ — новий трейдер (перша транзакція у поточному періоді).",
  "pattern": "dict",
  "key": "rk_provider_name"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Manager",
  "description": "Менеджер групи провайдерів (provider_groups.name).",
  "pattern": "dict",
  "key": "rk_manager"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Status",
  "description": "Поточний статус провайдера: active / archive / audit / paused / scammer / locked / lost / 60DaysLost / suspicious.",
  "pattern": "dict",
  "key": "rk_provider_status"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Deposit",
  "description": "Загальна сума депозитів трейдера ALL-TIME (bank_accounts.title LIKE '%deposit%'). Net flow по expenses.cash_in − cash_out для deposit-рахунків. Не залежить від обраного періоду.",
  "pattern": "dict",
  "key": "rk_deposit"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Score",
  "description": "Зважений бал 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.",
  "pattern": "dict",
  "key": "rk_score"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Volume INR",
  "description": "Сума INR по успішних PayIn трейдера за обраний період. Колонка %Δ — зміна відносно попереднього аналогічного по тривалості періоду.",
  "pattern": "dict",
  "key": "rk_volume"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Settle INR",
  "description": "Сума settlements з expenses.cash_out (категорія expense_categories.code='settlement') для рахунків провайдера за обраний період.",
  "pattern": "dict",
  "key": "rk_settle"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "CR%",
  "description": "Conversion Rate провайдера: payin_success / payin_total. Δ% відносно попереднього періоду.",
  "pattern": "dict",
  "key": "rk_cr"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "SLA IN",
  "description": "Середній час підтвердження PayIn (MM:SS): cp.source_created_at → cp.source_updated_at. Тільки успішні. Δ% — менше = краще (зелений ↓, червоний ↑).",
  "pattern": "dict",
  "key": "rk_sla_in"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "SLA OUT",
  "description": "Середній час прийняття PayOut (MM:SS): cp.source_created_at → cp.assigned_at. Cap 4 години. Δ% — менше = краще.",
  "pattern": "dict",
  "key": "rk_sla_out"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Active Days",
  "description": "Кількість унікальних дат (IST) з хоча б одним PayIn за обраний період.",
  "pattern": "dict",
  "key": "rk_active_days"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "BA",
  "description": "Кількість унікальних банківських рахунків (bank_accounts.account) трейдера з успішними PayIn за обраний період.",
  "pattern": "dict",
  "key": "rk_ba"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Velo IN",
  "description": "Velocity IN — медіана часу між послідовними успішними PayIn (хвилини). P95-trimmed (найповільніші 5% виключені).",
  "pattern": "dict",
  "key": "rk_velo_in"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Velo OUT",
  "description": "Velocity OUT — медіана часу між послідовними успішними PayOut (хвилини). P95-trimmed.",
  "pattern": "dict",
  "key": "rk_velo_out"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Last payin",
  "description": "Дата останнього успішного PayIn провайдера (з усієї історії, не лише в межах періоду).",
  "pattern": "dict",
  "key": "rk_last_payin"
 },
 {
  "report": "Weekly_KPI_Dashboard",
  "slug": "trader-weekly",
  "name": "Days since",
  "description": "Кількість днів від останнього payin до сьогодні (IST).",
  "pattern": "dict",
  "key": "rk_days_since"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Всього афіліатів",
  "description": "COUNT DISTINCT affiliate name з prefix mapping (affiliate_map.py) — тестовано в affiliate-pc.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Active / Risk / Dormant breakdown",
  "description": "Active = PayIn>0 за 7д. Risk = signals score>=51. Dormant = 14д без відповіді. [⚠ Логіка статусу афіліата ще не зафіксована — треба уточнити з менеджментом.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Активних трейдерів MTD",
  "description": "COUNT DISTINCT trader_id з PayIn>0 в поточному календарному місяці (IST). Готова логіка з ch.fetch_dashboard_kpi.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Сума PayIn MTD",
  "description": "SUM(transactions.amount) WHERE operation=payin AND date >= mtd_start_ist. 1:1 з прод-розрахунками.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Сума PayOut MTD",
  "description": "Аналогічно PayIn для operation=payout. [⚠ Не перевіряли проти аудиту виплат — є ризик розходження з фінансовим звітом.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Settlement MTD (PI − PO)",
  "description": "Зараз = PayIn − PayOut. [⚠ Уточнити: бізнес-визначення Settlement у Affiliate Dept (може включати expenses категорії settlement, як на трейдер-скоринг).]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Avg Score (трейдерів)",
  "description": "Середнє по scoring.compute_score (8 метрик з калібровкою — pop/pip/cr/sr/st/fw/av/cost). 1:1 з Trader Scoreboard.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Avg PayIn / трейдера",
  "description": "SUM(PayIn MTD) / COUNT(active traders MTD).",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Нових кабінетів MTD",
  "description": "COUNT trader_id з ap.source_created_at в поточному місяці. [⚠ Уточнити: чи \"новий кабінет\" = новий trader_id, чи запис у CRM (зараз CRM не підключений).]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Запущено трейдерів MTD",
  "description": "Нові кабінети з >=1 PayIn в період. [⚠ Логіка прозора, але ціль 80% ще не зафіксована як SLA.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Churned MTD (кількість + rate)",
  "description": "Логіка churn ще не реалізована. Треба: трейдер вважається churned, якщо мав активність N днів тому але не сьогодні. [❌ Уточнити N (30д? 14д?) і причини: пішов сам / 90-day Ownership / видалено менеджером.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Нових афіліатів MTD",
  "description": "Немає таблиці \"affiliate signed at\" у Hermes. Треба підключити CRM або створити таблицю affiliate_onboarding. [❌ Уточнити джерело.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Запущено афіліатів MTD",
  "description": "Залежить від \"нових афіліатів MTD\" + \"1й трейдер ≤7д від handoff\" — handoff date невідомий, треба CRM.",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "PayIn / PayOut / Settlement per Tier",
  "description": "Розрахунок прямий — SUM по афіліатах кожного tier. [⚠ Чекає визначення правила tier афіліата.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Avg Score per Tier",
  "description": "Avg trader score per tier — формула прозора, але tier афіліата залежить від п.вище.",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Гістограма Tier × метрика",
  "description": "Дані з попередніх рядків. Графік готовий, чекає правил.",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Топ-5 по PayIn MTD",
  "description": "ORDER BY PayIn DESC LIMIT 5 — тривіально.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Сумарні KPI зверху (6 карток)",
  "description": "Все агреговано з афіліатів. [⚠ Залежить від визначення статусів і churn.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Активність трейдерів (3 картки)",
  "description": "Нові каб./Запущено/Реактивовано — частково готово. [⚠ Реактивовано (трейдер після 30+ днів без PayIn повернувся) — не реалізовано, треба SQL з window function.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Таблиця афіліатів (12 колонок)",
  "description": "Колонки Назва/Tier/Статус/Трейдерів/Score/PayIn/PayOut/Settlement/Churn/Нових/Запущ./Реакт. Колонку Менеджер прибрано (2026-06-23). [⚠ Все залежить від визначень вище.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Control KPIs: CRM/Ownership/Freshness",
  "description": "Метрики CRM-якості (% заповнених карток, % з прив'язаним owner, % з контактом ≤7д). Джерела даних — CRM, який не підключено. [❌ Уточнити чи буде Hermes мати ці поля, чи окрема CRM-БД.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Менеджер кожного афіліата",
  "description": "Зараз manager беремо з provider_groups (Hermes). [❓ Уточнити: це правильна одиниця \"affiliate manager\" чи треба окрему модель?]",
  "pattern": "coverage-legend",
  "key": "req"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "PayIn / PayOut / Settlement тренди (6 графіків)",
  "description": "Тижневі агрегати — ch.fetch_weekly_dynamics готовий. [✓ Settlement потребує уточнення формули.]",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Кількість трейдерів за тиждень",
  "description": "COUNT DISTINCT trader_id з активністю в кожен тиждень.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Avg Score за тиждень",
  "description": "Avg score треба перераховувати щотижня. [⚠ Зараз scoring рахується по rolling 30d — треба зробити snapshot.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Фільтр афіліата для тренду",
  "description": "UI готовий, передає aff_id в SQL.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "KPI: ліди / first contacts / qualified / handoffs",
  "description": "Воронка залучення — потрібна CRM-інтеграція. Зараз немає таблиці leads. [❌ Уточнити джерело (Bitrix? власна БД?).]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Воронка 8 стадій",
  "description": "Стадії: Ліди → First Contact → Відповів → Qualified → Offer → Negotiating → Handoff → 1й трейдер. [❌ Уточнити точні визначення кожного переходу + датасет.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Тижнева матриця результативності",
  "description": "Залежить від воронки. [❌ Уточнити метрики (CR на кожному кроці, avg днів до handoff).]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Channel Attribution",
  "description": "Звідки приходить лід (Telegram/Referral/Форуми/Cold). [❌ Треба поле channel у CRM.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Win/Loss причини",
  "description": "Категоризація відмов. [❌ Треба структуроване поле у CRM.]",
  "pattern": "coverage-legend",
  "key": "none"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Фільтр Manager (multi-select)",
  "description": "Cb-drop pattern як в інших звітах. Дані з provider_groups через aff prefix mapping.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Фільтр Affiliate (multi-select)",
  "description": "Cb-drop. Дані з affiliate_map.AFFILIATE_PREFIXES.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Фільтр Tier (multi-select)",
  "description": "UI готовий. [⚠ Залежить від правил tier афіліата.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Фільтр Status (multi-select)",
  "description": "UI готовий. [⚠ Залежить від правил статусу афіліата.]",
  "pattern": "coverage-legend",
  "key": "warn"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Період From → To (date range)",
  "description": "Як на Weekly KPI / Trader Operational — input type=date, default MTD start → today (IST). Передається date_from/date_to в API.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Login redirect + JWT cookie",
  "description": "Уже працює для всіх інших звітів — підключаємо той самий хендлер.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Audit log (page_view + filters)",
  "description": "log_audit() викликається в /trader-affiliate.",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Permissions per user (allowed_affiliates, managers)",
  "description": "Той самий механізм — get_user_permissions. [✓ Треба додати \"trader-affiliate\" у REPORT_LABELS і дати дозвіл потрібним користувачам у /admin.]",
  "pattern": "coverage-legend",
  "key": "ok"
 },
 {
  "report": "Affiliate_Dashboard",
  "slug": "trader-affiliate",
  "name": "Top-nav з іншими звітами",
  "description": "/api/me?report=trader-affiliate повертає reports list — UI підвантажує.",
  "pattern": "coverage-legend",
  "key": "ok"
 }
]