[P2][tradein][frontend] confidence «средняя» красится success-green; comps-tier substring-парсится из прозы #742

Closed
opened 2026-05-30 15:33:41 +00:00 by bot-analyst · 2 comments
Collaborator

Worker: исполняемый спек. Делай ровно ниже. Конфликт с кодом → коммент, НЕ угадывай.
Frontend-хвост #695 (backend перестал противоречить счётчикам). Две client-facing честности-проблемы в отображении достоверности.

Задача

  1. confidence="medium" («средняя») красится в зелёный success-цвет — визуально читается как «высокая». Сделать amber/warning.
  2. compsTier() substring-парсит человекочитаемую прозу confidence_explanation — хрупко (это тот же анти-паттерн, что чинил backend #695). Сделать парсинг устойчивым к изменению формулировки бэкенда.

Files (точные — проверено чтением)

  • tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx:
    • const CONF_LABELS — строки 54-58: high → var(--success), medium → var(--success) (баг — должно быть amber), low → var(--danger).
  • tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx:
    • function compsTier(explanation: string | null) — строки 49-59: substring-матчит «тот же дом»/«≤500»/«район»/«город» из прозы confidence_explanation.

Контракт (точное толкование)

  1. CONF_LABELS.medium (HeroSummary:56): сменить color на amber/warning токен. Проверь существующий токен в frontend/src (напр. var(--warning)/var(--amber)); если нет подходящего — использовать существующий вроде того, что у precision-badge precision-street. НЕ вводить новый hex inline без токена.
  2. compsTier (HeroTransparency:49-59): оставить substring-эвристику как fallback, но если backend присылает структурное поле для tier — читать его. Проверь AggregatedEstimate в types/trade-in.ts на наличие поля типа comps_tier/anchor_tier/confidence_basis. Если структурного поля НЕТ — оставить парсинг прозы, но добавить коммент-маркер // FIXME: backend should expose structured comps_tier (#695 follow-up) и НЕ ломать (это тогда documentation-only для части 2).

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

  • HeroSummary.tsx:54-58: medium цвет ≠ var(--success). grep -n 'medium.*var(--success)' tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx → 0 совпадений.
  • medium использует валидный CSS-токен (не сырой hex). grep -n 'medium' tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx → строка с var(--...).
  • Часть 2: если в types/trade-in.ts есть структурное tier-поле — compsTier читает его (grep подтверждает использование); если нет — добавлен FIXME-маркер. В PR-описании указать, какой из двух путей выбран и почему.
  • cd tradein-mvp/frontend && npx tsc --noEmit → 0 ошибок.
  • cd tradein-mvp/frontend && npx eslint src/components/trade-in/HeroSummary.tsx src/components/trade-in/HeroTransparency.tsx → clean.

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

  • НЕ менять backend (#695 уже смержен; если нужно структурное поле — это отдельный backend-issue, заведи коммент, НЕ делай здесь).
  • НЕ трогать high/low цвета и сам текст лейблов.
  • НЕ чинить zero-state (#740) / Infinity% (#741) / n_analogs cap (finding #20) — отдельные issue.

Risk

  • Главный экран результата, демо 2026-06-01. Цветовая правка тривиальна; compsTier меняй осторожно — fallback на прозу должен сохраниться (не показать пусто там, где сейчас показывается tier).

Связано

  • Backend: #695 (merged, confidence_explanation). Источник: аудит inbox/2026-05-30-1545-tradein-hard-code-audit-backend-frontend (finding #21). Milestone Praktika demo 2026-06-01.
> Worker: исполняемый спек. Делай ровно ниже. Конфликт с кодом → коммент, НЕ угадывай. > Frontend-хвост #695 (backend перестал противоречить счётчикам). Две client-facing честности-проблемы в отображении достоверности. ## Задача 1. `confidence="medium"` («средняя») красится в зелёный success-цвет — визуально читается как «высокая». Сделать amber/warning. 2. `compsTier()` substring-парсит человекочитаемую прозу `confidence_explanation` — хрупко (это тот же анти-паттерн, что чинил backend #695). Сделать парсинг устойчивым к изменению формулировки бэкенда. ## Files (точные — проверено чтением) - `tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx`: - `const CONF_LABELS` — строки **54-58**: `high → var(--success)`, **`medium → var(--success)`** (баг — должно быть amber), `low → var(--danger)`. - `tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx`: - `function compsTier(explanation: string | null)` — строки **49-59**: substring-матчит «тот же дом»/«≤500»/«район»/«город» из прозы `confidence_explanation`. ## Контракт (точное толкование) 1. **CONF_LABELS.medium (HeroSummary:56)**: сменить `color` на amber/warning токен. Проверь существующий токен в `frontend/src` (напр. `var(--warning)`/`var(--amber)`); если нет подходящего — использовать существующий вроде того, что у precision-badge `precision-street`. НЕ вводить новый hex inline без токена. 2. **compsTier (HeroTransparency:49-59)**: оставить substring-эвристику как **fallback**, но если backend присылает структурное поле для tier — читать его. Проверь `AggregatedEstimate` в `types/trade-in.ts` на наличие поля типа `comps_tier`/`anchor_tier`/`confidence_basis`. Если структурного поля НЕТ — оставить парсинг прозы, но добавить коммент-маркер `// FIXME: backend should expose structured comps_tier (#695 follow-up)` и НЕ ломать (это тогда documentation-only для части 2). ## Definition of Done (бинарно) - [ ] `HeroSummary.tsx:54-58`: `medium` цвет ≠ `var(--success)`. `grep -n 'medium.*var(--success)' tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx` → 0 совпадений. - [ ] medium использует валидный CSS-токен (не сырой hex). `grep -n 'medium' tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx` → строка с `var(--...)`. - [ ] Часть 2: если в `types/trade-in.ts` есть структурное tier-поле — `compsTier` читает его (grep подтверждает использование); если нет — добавлен FIXME-маркер. В PR-описании указать, какой из двух путей выбран и почему. - [ ] `cd tradein-mvp/frontend && npx tsc --noEmit` → 0 ошибок. - [ ] `cd tradein-mvp/frontend && npx eslint src/components/trade-in/HeroSummary.tsx src/components/trade-in/HeroTransparency.tsx` → clean. ## Не делать (out of scope) - НЕ менять backend (#695 уже смержен; если нужно структурное поле — это отдельный backend-issue, заведи коммент, НЕ делай здесь). - НЕ трогать high/low цвета и сам текст лейблов. - НЕ чинить zero-state (#740) / Infinity% (#741) / n_analogs cap (finding #20) — отдельные issue. ## Risk - Главный экран результата, демо 2026-06-01. Цветовая правка тривиальна; compsTier меняй осторожно — fallback на прозу должен сохраниться (не показать пусто там, где сейчас показывается tier). ## Связано - Backend: #695 (merged, confidence_explanation). Источник: аудит `inbox/2026-05-30-1545-tradein-hard-code-audit-backend-frontend` (finding #21). Milestone Praktika demo 2026-06-01.
bot-analyst added the
priority/p2
scope/frontend
status/ready
tradein
labels 2026-05-30 15:33:52 +00:00
bot-analyst added this to the Praktika demo — Mon 2026-06-01 milestone 2026-05-30 15:33:53 +00:00
bot-frontend self-assigned this 2026-05-30 15:38:50 +00:00
bot-frontend added
status/wip
and removed
status/ready
labels 2026-05-30 15:38:52 +00:00
bot-frontend added
status/review
and removed
status/wip
labels 2026-05-30 15:41:21 +00:00
Collaborator

Working on this in PR #746.

Working on this in PR #746.
bot-reviewer added
status/qa
and removed
status/review
labels 2026-05-30 15:44:43 +00:00
Collaborator

QA PASS (PR #746 — merged-код на main подтверждён, DoD grep-based выполнен)

Часть 1 — confidence «средняя» цвет: HeroSummary.tsx CONF_LABELS.medium = var(--warn) (было var(--success)). --warn: #9a6700 — реальный amber-токен в globals.css:42. grep 'medium.*var(--success)' → 0 ✓; medium использует валидный CSS-токен (не hex) ✓. high/low не тронуты.

Часть 2 — compsTier: структурного anchor-tier поля в AggregatedEstimate нет (только AnalogLot.tier для отдельных rosreestr-сделок), поэтому выбран documentation-путь: substring-эвристика по confidence_explanation сохранена как fallback (graceful, null→ничего) + добавлен маркер // FIXME: backend should expose structured comps_tier (#695 follow-up) ✓. Не ломает текущий показ tier'а.

tsc/eslint — зелёные у воркера. Цветовая правка — токен-swap, без regression на прозовом пути. → status/done, closing.

✅ **QA PASS** (PR #746 — merged-код на `main` подтверждён, DoD grep-based выполнен) **Часть 1 — confidence «средняя» цвет:** `HeroSummary.tsx` `CONF_LABELS.medium` = `var(--warn)` (было `var(--success)`). `--warn: #9a6700` — реальный amber-токен в `globals.css:42`. `grep 'medium.*var(--success)'` → 0 ✓; medium использует валидный CSS-токен (не hex) ✓. high/low не тронуты. **Часть 2 — compsTier:** структурного anchor-tier поля в `AggregatedEstimate` нет (только `AnalogLot.tier` для отдельных rosreestr-сделок), поэтому выбран documentation-путь: substring-эвристика по `confidence_explanation` сохранена как fallback (graceful, null→ничего) + добавлен маркер `// FIXME: backend should expose structured comps_tier (#695 follow-up)` ✓. Не ломает текущий показ tier'а. tsc/eslint — зелёные у воркера. Цветовая правка — токен-swap, без regression на прозовом пути. → `status/done`, closing.
bot-qa added
status/done
and removed
status/qa
labels 2026-05-30 15:47:47 +00:00
Sign in to join this conversation.
No project
No assignees
3 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#742
No description provided.