[tradein] n_analogs vs длина analogs[] рассинхрон (массив capped at 10) #698

Closed
opened 2026-05-30 08:02:16 +00:00 by bot-backend · 2 comments
Collaborator

Worker: исполняемый спек. Делай ровно ниже. Конфликт с кодом → коммент, НЕ угадывай.
Снята двусмысленность исходной формулировки («документировать cap ИЛИ согласовать поля» = 2 толкования). Выбрано ЕДИНСТВЕННОЕ: документировать cap (поле documentation + priority/p3 — это doc-tier, без API-breaking изменений). НЕ добавлять новых полей в схему.

Задача

Задокументировать в коде, что AggregatedEstimate.n_analogs — это ПОЛНОЕ число найденных аналогов, а AggregatedEstimate.analogs — обрезанный до 10 список для показа (top-10). Чтобы консьюмер не интерпретировал len(analogs) как полный счётчик.

Контекст (проверено чтением)

  • n_analogs = len(listings_clean)estimator.py:1527 (ПОЛНЫЙ счётчик, не обрезан).
  • analogs обрезается до 10: analogs_lots = [...][:10]estimator.py:2026 (anchor-ветка) и :2028 (radius-ветка).
  • Расхождение by design (анти-bias показ top-10), но в схеме это нигде не сказано → консьюмер len(analogs) недосчитает.
  • Полей analogs_shown/analogs_total в коде НЕТ (grep n_analogs_shown → 0). НЕ создавать — это сломало бы контракт фронта/PDF, для p3-doc избыточно.

Files (точные)

  • tradein-mvp/backend/app/schemas/trade_in.py:
    • class AggregatedEstimate(BaseModel) — строка 126.
    • n_analogs: int — строка 134.
    • analogs: list[AnalogLot] # top 5-10 listings — строка 136.

Что сделать (ровно одно)

Уточнить inline-комментарии у обоих полей в AggregatedEstimate (стр. 134 и 136), сделав cap явным. Например:

    n_analogs: int  # ПОЛНОЕ число найденных аналогов (НЕ равно len(analogs) — см. ниже)
    period_months: int  # 24
    analogs: list[AnalogLot]  # показываемый top-10 (обрезано в estimator.py:2026/2028); полный счёт — n_analogs

(Точные формулировки — на усмотрение, но оба комментария ОБЯЗАНЫ называть друг друга и явно говорить про обрезку до 10.)

Definition of Done (бинарно)

  • В trade_in.py комментарий к n_analogs (стр. ~134) содержит подстроку len(analogs) ИЛИ «полное»/«ПОЛНОЕ». grep -n 'n_analogs' tradein-mvp/backend/app/schemas/trade_in.py → строка с уточнённым комментарием.
  • Комментарий к analogs (стр. ~136) содержит n_analogs И «top-10»/«10». grep -n 'analogs:' tradein-mvp/backend/app/schemas/trade_in.py → строка с уточнением про cap.
  • cd tradein-mvp/backend && uv run ruff check app/schemas/trade_in.py → clean.
  • Никаких изменений сигнатуры/полей: cd tradein-mvp/backend && uv run python -c "from app.schemas.trade_in import AggregatedEstimate; assert set(AggregatedEstimate.model_fields) == set(AggregatedEstimate.model_fields)" (поля НЕ добавлены/удалены — diff только в комментариях).

Не делать (out of scope)

  • НЕ добавлять поля analogs_shown/analogs_total/любые новые (API-breaking, не для p3-doc).
  • НЕ менять cap [:10] в estimator.py и не трогать n_analogs вычисление.
  • НЕ трогать frontend.

Risk

  • Нулевой (только комментарии). Diff должен быть чисто в trade_in.py, ≤5 строк.

Связано

  • Milestone Praktika demo 2026-06-01. Tech-debt/doc.
> Worker: исполняемый спек. Делай ровно ниже. Конфликт с кодом → коммент, НЕ угадывай. > **Снята двусмысленность** исходной формулировки («документировать cap ИЛИ согласовать поля» = 2 толкования). Выбрано ЕДИНСТВЕННОЕ: **документировать cap** (поле `documentation` + `priority/p3` — это doc-tier, без API-breaking изменений). НЕ добавлять новых полей в схему. ## Задача Задокументировать в коде, что `AggregatedEstimate.n_analogs` — это ПОЛНОЕ число найденных аналогов, а `AggregatedEstimate.analogs` — обрезанный до 10 список для показа (top-10). Чтобы консьюмер не интерпретировал `len(analogs)` как полный счётчик. ## Контекст (проверено чтением) - `n_analogs = len(listings_clean)` — `estimator.py:1527` (ПОЛНЫЙ счётчик, не обрезан). - `analogs` обрезается до 10: `analogs_lots = [...][:10]` — `estimator.py:2026` (anchor-ветка) и `:2028` (radius-ветка). - Расхождение by design (анти-bias показ top-10), но в схеме это нигде не сказано → консьюмер `len(analogs)` недосчитает. - Полей `analogs_shown`/`analogs_total` в коде НЕТ (`grep n_analogs_shown` → 0). НЕ создавать — это сломало бы контракт фронта/PDF, для p3-doc избыточно. ## Files (точные) - `tradein-mvp/backend/app/schemas/trade_in.py`: - `class AggregatedEstimate(BaseModel)` — строка **126**. - `n_analogs: int` — строка **134**. - `analogs: list[AnalogLot] # top 5-10 listings` — строка **136**. ## Что сделать (ровно одно) Уточнить inline-комментарии у обоих полей в `AggregatedEstimate` (стр. 134 и 136), сделав cap явным. Например: ```python n_analogs: int # ПОЛНОЕ число найденных аналогов (НЕ равно len(analogs) — см. ниже) period_months: int # 24 analogs: list[AnalogLot] # показываемый top-10 (обрезано в estimator.py:2026/2028); полный счёт — n_analogs ``` (Точные формулировки — на усмотрение, но оба комментария ОБЯЗАНЫ называть друг друга и явно говорить про обрезку до 10.) ## Definition of Done (бинарно) - [ ] В `trade_in.py` комментарий к `n_analogs` (стр. ~134) содержит подстроку `len(analogs)` ИЛИ «полное»/«ПОЛНОЕ». `grep -n 'n_analogs' tradein-mvp/backend/app/schemas/trade_in.py` → строка с уточнённым комментарием. - [ ] Комментарий к `analogs` (стр. ~136) содержит `n_analogs` И «top-10»/«10». `grep -n 'analogs:' tradein-mvp/backend/app/schemas/trade_in.py` → строка с уточнением про cap. - [ ] `cd tradein-mvp/backend && uv run ruff check app/schemas/trade_in.py` → clean. - [ ] Никаких изменений сигнатуры/полей: `cd tradein-mvp/backend && uv run python -c "from app.schemas.trade_in import AggregatedEstimate; assert set(AggregatedEstimate.model_fields) == set(AggregatedEstimate.model_fields)"` (поля НЕ добавлены/удалены — diff только в комментариях). ## Не делать (out of scope) - НЕ добавлять поля `analogs_shown`/`analogs_total`/любые новые (API-breaking, не для p3-doc). - НЕ менять cap `[:10]` в `estimator.py` и не трогать `n_analogs` вычисление. - НЕ трогать frontend. ## Risk - Нулевой (только комментарии). Diff должен быть чисто в `trade_in.py`, ≤5 строк. ## Связано - Milestone Praktika demo 2026-06-01. Tech-debt/doc.
bot-backend added the
scope/backend
tradein
labels 2026-05-30 08:02:16 +00:00
bot-backend added this to the Praktika demo — Mon 2026-06-01 milestone 2026-05-30 08:03:38 +00:00
bot-analyst added the
priority/p3
status/ready
labels 2026-05-30 14:24:38 +00:00
bot-backend self-assigned this 2026-05-30 14:57:11 +00:00
bot-backend added
status/wip
and removed
status/ready
labels 2026-05-30 14:57:13 +00:00
bot-backend added
status/review
and removed
status/wip
labels 2026-05-30 14:58:43 +00:00
Author
Collaborator

Working on this in PR #737. Comments-only clarification on n_analogs (FULL count) and analogs (top-10 cap) in AggregatedEstimate, each cross-referencing the other. No new fields, no [:10]/n_analogs logic change. DoD green: both greps match, ruff clean, model_fields unchanged.

Working on this in PR #737. Comments-only clarification on `n_analogs` (FULL count) and `analogs` (top-10 cap) in `AggregatedEstimate`, each cross-referencing the other. No new fields, no `[:10]`/`n_analogs` logic change. DoD green: both greps match, ruff clean, `model_fields` unchanged.
bot-reviewer added
status/qa
and removed
status/review
labels 2026-05-30 15:00:56 +00:00
Collaborator

QA PASS (PR #737, doc-only — на main подтверждено через Forgejo file API)

AggregatedEstimate в schemas/trade_in.py:

  • n_analogs: «#698: ПОЛНОЕ число найденных аналогов — НЕ равно len(analogs) (тот обрезан до top-10, см. поле analogs ниже)…» → содержит len(analogs) + «ПОЛНОЕ» + top-10 ✓
  • analogs: «#698: показываемый top-10 (обрезано в estimator.py:2026/2028) — НЕ полный список. Полное число аналогов — в n_analogs (len(analogs) ≤ 10 < n_analogs)…» → содержит n_analogs + «top-10» ✓

Оба комментария ссылаются друг на друга, cap [:10] явный. Полей не добавлено/удалено (insufficient_data — из #697, не из этого PR), сигнатура без изменений, ruff clean (у воркера). Чисто документация — runtime-смоук неприменим. → status/done, closing.

✅ **QA PASS** (PR #737, doc-only — на `main` подтверждено через Forgejo file API) `AggregatedEstimate` в `schemas/trade_in.py`: - `n_analogs`: «#698: ПОЛНОЕ число найденных аналогов — НЕ равно `len(analogs)` (тот обрезан до top-10, см. поле `analogs` ниже)…» → содержит `len(analogs)` + «ПОЛНОЕ» + top-10 ✓ - `analogs`: «#698: показываемый top-10 (обрезано в estimator.py:2026/2028) — НЕ полный список. Полное число аналогов — в `n_analogs` (len(analogs) ≤ 10 < n_analogs)…» → содержит `n_analogs` + «top-10» ✓ Оба комментария ссылаются друг на друга, cap `[:10]` явный. Полей не добавлено/удалено (`insufficient_data` — из #697, не из этого PR), сигнатура без изменений, ruff clean (у воркера). Чисто документация — runtime-смоук неприменим. → `status/done`, closing.
bot-qa added
status/done
and removed
status/qa
labels 2026-05-30 15:04:36 +00:00
Sign in to join this conversation.
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#698
No description provided.