From 5a3e820f5368fbbba5153e4baff39f7e51c528cb Mon Sep 17 00:00:00 2001 From: Light1YT Date: Wed, 27 May 2026 18:15:32 +0500 Subject: [PATCH] =?UTF-8?q?feat(tradein):=20tier=20badge=20=D0=BD=D0=B0=20?= =?UTF-8?q?DealsCard=20rows=20(PR=20M=20follow-up=20#564)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR M (#600) добавил confidence tier field в backend AnalogLot.actual_deals. Этот PR показывает его UI: - types/trade-in.ts: AnalogLot.tier?: string (T0_per_house / T1_per_street) - DealsCard.tsx: DealRow рендерит badge рядом с источником * T0 «по дому» — var(--success) (кадастровый match) * T1 «по улице» — var(--fg-tertiary) (street-level default) - trade-in.css: .tier-badge + .tier-t0 + .tier-t1 (token-only) Current state: все rosreestr deals = T1 (open dataset не имеет kadastr_num). Когда появится ЕГРН direct feed — высветятся T0. Tests: tsc --noEmit clean. Refs #564. --- .../src/components/trade-in/DealsCard.tsx | 13 +++++++++++ .../src/components/trade-in/trade-in.css | 23 +++++++++++++++++++ tradein-mvp/frontend/src/types/trade-in.ts | 4 ++++ 3 files changed, 40 insertions(+) diff --git a/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx b/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx index 4731ba91..846ecea2 100644 --- a/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx @@ -149,6 +149,14 @@ function DealRow({ deal }: { deal: AnalogLot }) { const dot = SOURCE_DOTS[src] ?? "dom"; const label = SOURCE_LABELS[src] ?? src; + // Tier badge для rosreestr deals (PR M / #564 Phase 3). + // T0_per_house — точный кадастровый match (high confidence). + // T1_per_street — улица-уровень (open dataset default). + const tierBadge = + deal.tier === "T0_per_house" ? { text: "по дому", className: "tier-badge tier-t0" } + : deal.tier === "T1_per_street" ? { text: "по улице", className: "tier-badge tier-t1" } + : null; + return ( @@ -166,6 +174,11 @@ function DealRow({ deal }: { deal: AnalogLot }) { {label} + {tierBadge ? ( + + {tierBadge.text} + + ) : null} {fmtRub(deal.price_per_m2)} {fmtRub(deal.price_rub)} diff --git a/tradein-mvp/frontend/src/components/trade-in/trade-in.css b/tradein-mvp/frontend/src/components/trade-in/trade-in.css index e54febf1..0c3dbb0e 100644 --- a/tradein-mvp/frontend/src/components/trade-in/trade-in.css +++ b/tradein-mvp/frontend/src/components/trade-in/trade-in.css @@ -1691,3 +1691,26 @@ .listing-cell { min-width: 0; max-width: none; } .listing-link { flex-direction: column; align-items: flex-start; gap: 2px; } } + +/* ── PR M (#564 Phase 3) — Tier badge for rosreestr deals ────────────────── */ +.tier-badge { + display: inline-block; + margin-left: 6px; + padding: 1px 6px; + border-radius: 4px; + font-size: 10px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + vertical-align: middle; +} +.tier-t0 { + /* T0_per_house — точный кадастровый match (high confidence) */ + background: var(--success-soft); + color: var(--success); +} +.tier-t1 { + /* T1_per_street — улица-уровень (open dataset default) */ + background: var(--bg-card-alt); + color: var(--fg-tertiary); +} diff --git a/tradein-mvp/frontend/src/types/trade-in.ts b/tradein-mvp/frontend/src/types/trade-in.ts index 361e271f..30190ce5 100644 --- a/tradein-mvp/frontend/src/types/trade-in.ts +++ b/tradein-mvp/frontend/src/types/trade-in.ts @@ -44,6 +44,10 @@ export interface AnalogLot { source: string | null; // 'avito' / 'cian' / 'domklik' / 'rosreestr' source_url: string | null; // ссылка на оригинал distance_m: number | null; // расстояние до целевой квартиры в метрах + // ── PR M (#564 Phase 3) — confidence tier для rosreestr deals ── + // 'T0_per_house' — kadastr_num exact match (currently not available in open dataset) + // 'T1_per_street' — street-level only (default for all rosreestr deals) + tier?: string | null; } export interface CianValuationSummary {