(medium) PDF-отчёт Trade-In печатает period_months=24, тогда как данные за 12 месяцев — неверное окно в клиентском документе #1351

Closed
opened 2026-06-14 18:08:57 +00:00 by bot-backend · 1 comment
Collaborator

Описание

Источник истины для окна сделок — DEALS_PERIOD_MONTHS = 12 (estimator.py:79). POST /estimate строит AggregatedEstimate с period_months=DEALS_PERIOD_MONTHS (12), GET /estimate/{id} корректно хардкодит period_months=12 (trade_in.py:301). Endpoint /estimate/{id}/pdf хардкодит period_months=24. Одна и та же сохранённая оценка показывается с period_months=12 на экране / при reopen по shared-link, но period_months=24 в скачанном PDF. Это не метка-косметика: экспортёр (trade_in_pdf.py:799) считает period_start = today - timedelta(days=period_months * 30) и рендерит диапазон в PDF (trade_in_pdf.py:866). При period_months=24 PDF указывает окно ~2 года, тогда как сделки реально отфильтрованы последними 12 месяцами — фактически ложное утверждение в клиентском финансовом документе.

Корень

Copy-paste/рассинхрон: в PDF-ветке захардкожено period_months=24 вместо актуального окна оценки. Отдельный 24-месячный запрос не выполняется — переиспользуются те же persisted analogs/actual_deals.

Evidence

/Users/anton/Птица/gendesign/tradein-mvp/backend/app/api/v1/trade_in.py:399

# PDF endpoint:
period_months=24,
# vs GET rehydrate (trade_in.py:301): period_months=12
# vs estimator.py:79  DEALS_PERIOD_MONTHS = 12  # сделки за последний год

Suggested fix

Заменить в PDF-ветке period_months=24 на period_months=12. Лучше — импортировать DEALS_PERIOD_MONTHS из app.services.estimator и использовать его и в GET rehydrate, и в PDF-endpoint, чтобы значение не дрейфовало от реального окна сделок.

Обоснование severity

Medium: фактически неверная метка в клиентском документе (диапазон дат сделок), но сама оценка цены не затронута. Путь полностью достижим (стандартный GET-endpoint, без feature-флагов).


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

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

  • /Users/anton/Птица/gendesign/tradein-mvp/backend/app/api/v1/trade_in.py
## Описание Источник истины для окна сделок — `DEALS_PERIOD_MONTHS = 12` (`estimator.py:79`). POST `/estimate` строит `AggregatedEstimate` с `period_months=DEALS_PERIOD_MONTHS` (12), GET `/estimate/{id}` корректно хардкодит `period_months=12` (`trade_in.py:301`). Endpoint `/estimate/{id}/pdf` хардкодит `period_months=24`. Одна и та же сохранённая оценка показывается с `period_months=12` на экране / при reopen по shared-link, но `period_months=24` в скачанном PDF. Это не метка-косметика: экспортёр (`trade_in_pdf.py:799`) считает `period_start = today - timedelta(days=period_months * 30)` и рендерит диапазон в PDF (`trade_in_pdf.py:866`). При `period_months=24` PDF указывает окно ~2 года, тогда как сделки реально отфильтрованы последними 12 месяцами — фактически ложное утверждение в клиентском финансовом документе. ## Корень Copy-paste/рассинхрон: в PDF-ветке захардкожено `period_months=24` вместо актуального окна оценки. Отдельный 24-месячный запрос не выполняется — переиспользуются те же persisted `analogs`/`actual_deals`. ## Evidence `/Users/anton/Птица/gendesign/tradein-mvp/backend/app/api/v1/trade_in.py:399` ```python # PDF endpoint: period_months=24, # vs GET rehydrate (trade_in.py:301): period_months=12 # vs estimator.py:79 DEALS_PERIOD_MONTHS = 12 # сделки за последний год ``` ## Suggested fix Заменить в PDF-ветке `period_months=24` на `period_months=12`. Лучше — импортировать `DEALS_PERIOD_MONTHS` из `app.services.estimator` и использовать его и в GET rehydrate, и в PDF-endpoint, чтобы значение не дрейфовало от реального окна сделок. ## Обоснование severity Medium: фактически неверная метка в клиентском документе (диапазон дат сделок), но сама оценка цены не затронута. Путь полностью достижим (стандартный GET-endpoint, без feature-флагов). --- _week ревью 1 · multi-agent аудит 2026-06-14 · severity=**medium** · category=`correctness`_ Затронутые файлы: - `/Users/anton/Птица/gendesign/tradein-mvp/backend/app/api/v1/trade_in.py`
bot-backend added the
week ревью 1
label 2026-06-14 18:08:57 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:01:51 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: tradein-mvp/backend/app/api/v1/trade_in.py:399 (внутри эндпоинта @router.get("/estimate/{estimate_id}/pdf"), trade_in.py:341).

Корень: в PDF-ветке AggregatedEstimate(...) собирается с захардкоженным period_months=24 (trade_in.py:399), тогда как:

  • GET-rehydrate /estimate/{id}period_months=12 (trade_in.py:301);
  • источник истины — tradein-mvp/backend/app/services/estimator.py:79 DEALS_PERIOD_MONTHS = 12, который POST /estimate и использует (estimator.py:2807, :3995period_months=DEALS_PERIOD_MONTHS).
    Отдельный 24-мес запрос не делается — переиспользуются те же persisted analogs/actual_deals (фактически отфильтрованные 12 мес.), так что PDF печатает ложное окно дат. Подтверждено: рассинхрон именно копипастой константы, цена не затронута.

Что править:

  • Заменить trade_in.py:399 period_months=24period_months=12.
  • Лучше: from app.services.estimator import DEALS_PERIOD_MONTHS и использовать period_months=DEALS_PERIOD_MONTHS и в PDF-ветке (:399), и в GET-rehydrate (:301) — чтобы значение не дрейфовало.

Что посмотреть:

  • Код: trade_in.py:341-412 (PDF endpoint), :299-338 (GET rehydrate), estimator.py:79. Note: значения period_months=24 в trade_in.py:1568,1589 относятся к ДРУГИМ эндпоинтам (sales-vs-listings) — их не трогать. Экспортёр app/services/exporters/trade_in_pdf.py считает period_start = today - period_months*30 и рендерит диапазон — проверить, что после фикса диапазон стал 12-мес.
  • Vault: релевантных заметок не найдено.
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `tradein-mvp/backend/app/api/v1/trade_in.py:399` (внутри эндпоинта `@router.get("/estimate/{estimate_id}/pdf")`, `trade_in.py:341`). **Корень:** в PDF-ветке `AggregatedEstimate(...)` собирается с захардкоженным `period_months=24` (`trade_in.py:399`), тогда как: - GET-rehydrate `/estimate/{id}` — `period_months=12` (`trade_in.py:301`); - источник истины — `tradein-mvp/backend/app/services/estimator.py:79` `DEALS_PERIOD_MONTHS = 12`, который POST `/estimate` и использует (`estimator.py:2807`, `:3995` → `period_months=DEALS_PERIOD_MONTHS`). Отдельный 24-мес запрос не делается — переиспользуются те же persisted `analogs`/`actual_deals` (фактически отфильтрованные 12 мес.), так что PDF печатает ложное окно дат. Подтверждено: рассинхрон именно копипастой константы, цена не затронута. **Что править:** - Заменить `trade_in.py:399` `period_months=24` → `period_months=12`. - Лучше: `from app.services.estimator import DEALS_PERIOD_MONTHS` и использовать `period_months=DEALS_PERIOD_MONTHS` и в PDF-ветке (`:399`), и в GET-rehydrate (`:301`) — чтобы значение не дрейфовало. **Что посмотреть:** - Код: `trade_in.py:341-412` (PDF endpoint), `:299-338` (GET rehydrate), `estimator.py:79`. Note: значения `period_months=24` в `trade_in.py:1568,1589` относятся к ДРУГИМ эндпоинтам (sales-vs-listings) — их не трогать. Экспортёр `app/services/exporters/trade_in_pdf.py` считает `period_start = today - period_months*30` и рендерит диапазон — проверить, что после фикса диапазон стал 12-мес. - Vault: релевантных заметок не найдено.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#1351
No description provided.