From 5a4b1cc3a4a5be89cad4bcfcc3829fc2359f0c04 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Sat, 30 May 2026 22:58:42 +0300 Subject: [PATCH] =?UTF-8?q?fix(tradein):=20seed=20sales-vs-listings=20?= =?UTF-8?q?=E2=86=92=20StreetDealsCard=20=D1=80=D0=B5=D0=BD=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D1=81=D1=8F=20(1:1)=20(#801)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StreetDealsCard фетчит /sales-vs-listings (не из estimate prop) → без засева queryKey возвращал null (секция «По вашей улице» отсутствовала). Добавлен FIXTURE_SALES (SalesVsListingsResponse, street+pairs) + seed ["trade-in","sales-vs-listings",address,area,rooms]. Теперь все 17 секций 1:1 с page.tsx (verified локально: 11 section-kicker'ов вкл. «По вашей улице»). Refs #801. --- .../src/app/ui-preview/estimate/fixture.ts | 55 +++++++++++++++++++ .../src/app/ui-preview/estimate/page.tsx | 12 ++++ 2 files changed, 67 insertions(+) diff --git a/tradein-mvp/frontend/src/app/ui-preview/estimate/fixture.ts b/tradein-mvp/frontend/src/app/ui-preview/estimate/fixture.ts index d58bd1a9..b9aad584 100644 --- a/tradein-mvp/frontend/src/app/ui-preview/estimate/fixture.ts +++ b/tradein-mvp/frontend/src/app/ui-preview/estimate/fixture.ts @@ -12,6 +12,7 @@ import type { HouseInfoForEstimate, IMVBenchmarkResponse, PlacementHistoryItem, + SalesVsListingsResponse, SellTimeSensitivityResponse, TradeInEstimateInput, } from "@/types/trade-in"; @@ -356,3 +357,57 @@ export const FIXTURE_SELLTIME: SellTimeSensitivityResponse = { { price_premium_label: "plus10", price_premium_pct: 10, median_exposure_days: 270, p25_days: 150, p75_days: 360, n_lots: 6 }, ], }; + +// Секция 12: StreetDealsCard — useSalesVsListings(address, area_m2, rooms). +// Guard: street != null И pairs.length > 0 — иначе return null. +export const FIXTURE_SALES: SalesVsListingsResponse = { + street: "Репина", + period_months: 24, + window_days: 180, + area_tolerance: 0.15, + total_deals: 9, + deals_with_listings: 5, + linkage_rate_pct: 55.6, + median_discount_pct: -6.2, + data_quality: "house_linked", + pairs: [ + { + deal_id: 9001, + deal_date: "2026-04-18", + deal_price_rub: 8_900_000, + deal_price_per_m2: 161_818, + deal_area_m2: 55, + deal_rooms: 2, + deal_floor: 6, + deal_address: "Екатеринбург, ул. Репина, 75/2", + listing_id: 50001, + listing_source: "avito", + listing_source_url: "https://www.avito.ru/ekaterinburg/kvartiry/preview-d1", + listing_date: "2026-03-20", + listing_price_rub: 9_500_000, + listing_price_per_m2: 172_727, + listing_area_m2: 55, + days_listing_to_deal: 29, + discount_pct: -6.3, + }, + { + deal_id: 9002, + deal_date: "2026-02-27", + deal_price_rub: 9_100_000, + deal_price_per_m2: 159_649, + deal_area_m2: 57, + deal_rooms: 2, + deal_floor: 9, + deal_address: "Екатеринбург, ул. Репина, 73", + listing_id: 50002, + listing_source: "cian", + listing_source_url: "https://www.cian.ru/sale/flat/preview-d2", + listing_date: "2026-01-30", + listing_price_rub: 9_700_000, + listing_price_per_m2: 170_175, + listing_area_m2: 57, + days_listing_to_deal: 28, + discount_pct: -6.2, + }, + ], +}; diff --git a/tradein-mvp/frontend/src/app/ui-preview/estimate/page.tsx b/tradein-mvp/frontend/src/app/ui-preview/estimate/page.tsx index 5c858e1b..aa9ae30f 100644 --- a/tradein-mvp/frontend/src/app/ui-preview/estimate/page.tsx +++ b/tradein-mvp/frontend/src/app/ui-preview/estimate/page.tsx @@ -67,6 +67,7 @@ import { FIXTURE_IMV, FIXTURE_INPUT, FIXTURE_PLACEMENT, + FIXTURE_SALES, FIXTURE_SELLTIME, } from "./fixture"; @@ -100,6 +101,17 @@ function PreviewContent() { qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "sell-time-sensitivity"], FIXTURE_SELLTIME); // Секция 10: ListingsCard — useEstimateCianPriceChanges (пустой = graceful) qc.setQueryData(["trade-in", "estimate", PREVIEW_ID, "cian-price-changes"], []); + // Секция 12: StreetDealsCard — useSalesVsListings(address, area_m2, rooms) + qc.setQueryData( + [ + "trade-in", + "sales-vs-listings", + FIXTURE_ESTIMATE.target_address, + FIXTURE_ESTIMATE.area_m2, + FIXTURE_ESTIMATE.rooms, + ], + FIXTURE_SALES, + ); return qc; });