[low] leads/stats: revenue/deals считаются за всё время под контрактом «за последние N месяцев» #1383

Closed
opened 2026-06-14 18:10:08 +00:00 by bot-backend · 0 comments
Collaborator

Описание

leads_stats() задокументирован как «KPI summary за последние N месяцев» и принимает окно months. Счётчики лидов (leads_window, converted_window, conv_pct_window) корректно ограничены окном через CTE window_leads, но revenue_total и deals_total считаются по всей таблице prinzip_deals без фильтра по closed_at. Дашборд, показывающий revenue рядом с 12-месячным conversion rate, смешает оконные и all-time цифры.

Корень

Часть полей ответа оконные, часть — all-time, на одном уровне вложенности без именованного различия; докстринг «за последние N месяцев» создаёт ложное ожидание, что все поля уважают окно.

Evidence

admin_leads.py:152-153:

(SELECT SUM(deal_price) FROM prinzip_deals) AS revenue_total,
(SELECT COUNT(*) FROM prinzip_deals) AS deals_total

Нет WHERE closed_at >= NOW() - interval, в отличие от CTE window_leads.

Suggested fix

Либо отфильтровать по окну (WHERE closed_at >= NOW() - (:m || ' months')::interval) и переименовать в revenue_window/deals_window, либо явно задокументировать, что эти поля all-time и отделены от оконных conversion-KPI.

Обоснование severity (low)

Нет порчи данных и security-проблем, суффикс _total слабо сигналит all-time. Но дашборд бок о бок ввёл бы стейкхолдеров в заблуждение. Confidence 0.88.


week ревью 1 · multi-agent аудит 2026-06-14 · severity=low · category=logic

Затронутые файлы:

  • /Users/anton/Птица/gendesign/backend/app/api/v1/admin_leads.py
## Описание `leads_stats()` задокументирован как «KPI summary за последние N месяцев» и принимает окно `months`. Счётчики лидов (`leads_window`, `converted_window`, `conv_pct_window`) корректно ограничены окном через CTE `window_leads`, но `revenue_total` и `deals_total` считаются по всей таблице `prinzip_deals` без фильтра по `closed_at`. Дашборд, показывающий revenue рядом с 12-месячным conversion rate, смешает оконные и all-time цифры. ## Корень Часть полей ответа оконные, часть — all-time, на одном уровне вложенности без именованного различия; докстринг «за последние N месяцев» создаёт ложное ожидание, что все поля уважают окно. ## Evidence `admin_leads.py:152-153`: ```sql (SELECT SUM(deal_price) FROM prinzip_deals) AS revenue_total, (SELECT COUNT(*) FROM prinzip_deals) AS deals_total ``` Нет `WHERE closed_at >= NOW() - interval`, в отличие от CTE `window_leads`. ## Suggested fix Либо отфильтровать по окну (`WHERE closed_at >= NOW() - (:m || ' months')::interval`) и переименовать в `revenue_window`/`deals_window`, либо явно задокументировать, что эти поля all-time и отделены от оконных conversion-KPI. ## Обоснование severity (low) Нет порчи данных и security-проблем, суффикс `_total` слабо сигналит all-time. Но дашборд бок о бок ввёл бы стейкхолдеров в заблуждение. Confidence 0.88. --- _week ревью 1 · multi-agent аудит 2026-06-14 · severity=**low** · category=`logic`_ Затронутые файлы: - `/Users/anton/Птица/gendesign/backend/app/api/v1/admin_leads.py`
bot-backend added the
week ревью 1
label 2026-06-14 18:10:08 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:01:56 +00:00
bot-backend added the
needs-human
label 2026-06-15 16:44:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1383
No description provided.