05-project-statistics

ProjectStatistics

backend-common/src/statistics/project-statistics.schema.ts · колекції project_statistics і project_statistics_temp — операції партнера і платні дії RU всіх проєктів в одній формі. Пише лише сервіс проєкту (кожен свій project), платформа читає і будує проєкції: favorites, глобальні favorites, календар, далі статистику й метрики.

Поля

  • project, adminId, tuId — canonical посилання; adminId — через яку адмін панель отримано запис, null для операцій поза нашою агенцією.
  • ruId — ID RU партнера як string; null для статистики без RU (Prime, Udate).
  • at — момент операції як Date, зони не має.
  • day — YYYY-MM-DD у часовій зоні проєкту (Golden — Kyiv, решта — UTC), рахується один раз під час запису. Групування по добі, календар і статистика беруть day; порядок і перша/остання дія пари — at.
  • type — тип партнера як є: рядок у Golden, Prime і Udate, числовий код у Chathouse; у коді enum проєкту (GoldenStatisticsType, ChathouseStatisticsType, PrimeStatisticsType, UdateStatisticsType).
  • amount — сума у форматі проєкту; для платної дії RU це 1.
  • isFree — операція без реальної витрати: бонусні монети Golden, free credits Chathouse.
  • isExternal — операція TU поза нашою агенцією: історія, докачана по API самої TU при появі TU (legacy golden_other_bonuses). Favorites, календар і agency її беруть, статистика операторів і TU фільтрує isExternal: false.
  • operatorProjectId / supervisorProjectId / clientManagerProjectId / topManagerUserId — прив’язка до команди на момент операції; null, доки окрема логіка прив’язки їх не заповнить.
  • eventId — ключ дедуплікації дії RU (ID повідомлення партнера); в операцій статистики немає.
  • createdAt — час запису.

Дві колекції, одна форма

КолекціяЩоХто пишеЯк
project_statisticsзавершені днісервіс проєкту після денної вигрузкивидалення днів адмін панелі і запис заново
project_statistics_tempнезавершені дні (Golden: сьогодні, до 13:06 і вчора)сервіс проєкту щохвилиниповна заміна знімка адмін панелі

Temp ніколи не потрапляє у стабільні колекції: платформа накладає його на favorites і календар під час читання. Після запису завершеного дня проєкт прибирає ці дні зі знімка, щоб день не рахувався двічі.

Правила по типах

backend-common/src/statistics/project-statistics.rules.ts — клас ProjectStatisticsRules, єдине місце, де код розрізняє типи партнера: подарунки, free-типи, умова на рядки favorites, поріг freeloader. Конфіг на проєкт у rules/; споживачі беруть ProjectStatisticsRules.of(project) і питають isGift, isFree, isFreeloader, favoritesFilter.

ПроєктПодарунокУ favorites не берутьсяFreeloader
GoldenGiftsDelivery*unknown, Activation, PhoneTranslation, ContactInfoSatellite, Penalties, amount = 0 (бонусні монети)profit <= 0
Chathousepresent_sendamount <= 0profit <= 0
Primevirtual_giftрядки без RUprofit <= 10
UdateVIRTUAL_GIFT_PURCHASEрядки без RUprofit <= 10

Індекси

project + tuId + day (заміна обсягу, статистика TU), project + tuId + ruId + at (favorites, календар), project + day (статистика за період), project + adminId + day (останній день адмін панелі), partial unique project + eventId (дії RU). Temp: project + adminId, project + tuId.

Нюанси

  • Golden finances v2 віддає date у мілісекундах epoch, тому at не конвертується, а day рахується через getProjectDay.
  • Обсяги на проді: Golden 3.8M рядків, Chathouse 3.7M, Prime 5.1M дій, Udate ~1.9M; запити з індексом по project не залежать від сумарного розміру, повний скан проєкту робить лише ремонтний перерахунок.
  • Міграція legacy Golden: POST /migrations/statistics/apply переносить golden_statistics і golden_other_bonuses зі збереженням _id (ідемпотентно); date + time legacy як Kyiv-час, legacy operator/supervisor стають operatorProjectId/supervisorProjectId, other bonuses стають isExternal: true з adminId: null, заглушки date: 'null' (позначка legacy «історію вже перевірено») пропускаються. Після неї денна вигрузка продовжує з дня після останнього перенесеного.
  • Наповнена лише Golden: вигрузка живе у project-golden (StatisticsService.processTemp і processFinal); нова адмін панель докачується з 2022-01-01 помісячно, як у legacy.
  • Історія TU до появи в нашій агенції (isExternal: true, adminId: null): init TU на платформі (init TU) викликає POST /internal/statistics/download-tu-history { tuId } сервісу проєкту, той качає finances credentials самої TU за 2022-01-01..день перед першим днем з нашою адмінкою (перший власний рядок, а до першої денної вигрузки — день появи в project_tus) і замінює external-рядки TU цілком. Денна вигрузка після запису власних днів прибирає external-рядки цих TU від їх першого власного дня, тому перетину між історією і нашою статистикою немає.