feat(tradein/estimate): юр-строка «Ориентировочный расчёт. Не является официальной оценкой.»
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m3s

Блок 4.1 юр-требований владельца (14.08.2026): под диапазоном цены на
экране результата обязана быть эта строка. Вынесена в новый модуль
lib/legal-copy.ts (SHORT_ESTIMATE_DISCLAIMER, без импортов) — используется
и в v2/ResultPanel.tsx (боевой экран /v2), и в HeroSummary.tsx (legacy-контур
/trade-in/ui-preview/estimate), первым предложением в уже существующем
абзаце-дисклеймере про рыночный разброс. В ResultPanel.tsx подрезаны
lineHeight/marginTop/padding соседнего блока, чтобы новая строка не сжимала
плитки "ИСТОЧНИКИ ДАННЫХ" на фиксированной высоте артборда.
This commit is contained in:
bot-backend 2026-08-14 15:25:58 +03:00
parent b0776cd01d
commit 1b7e047210
3 changed files with 55 additions and 7 deletions

View file

@ -5,6 +5,9 @@
/**
* HeroSummary Секция 1 «Сводка» из mockup tradein.html.
* Показывает медиану + достоверность CV + параметры объекта + 2 ценовых бара (объявления / сделки).
*
* hero-duo__hint под диапазоном сделок несёт юр-требование владельца от
* 14.08.2026 (блок 4.1): SHORT_ESTIMATE_DISCLAIMER см. `lib/legal-copy.ts`.
*/
import { useState } from "react";
import type { AggregatedEstimate, TradeInEstimateInput, HouseType, RepairState, ConfidenceLevel } from "@/types/trade-in";
@ -12,6 +15,7 @@ import { asHouseType, asRepairState } from "@/types/trade-in";
import { useActiveBrandSlug, useBrand } from "@/lib/useBrand";
import { sourceDot, sourceLabel } from "@/lib/source-registry";
import { dealsAsOfLabel } from "@/lib/rosreestr";
import { SHORT_ESTIMATE_DISCLAIMER } from "@/lib/legal-copy";
import { HeroTransparency } from "./HeroTransparency";
interface Props {
@ -478,6 +482,9 @@ export function HeroSummary({ estimate, input, onResubmit, isResubmitting = fals
</div>
)}
<p className="hero-duo__hint">
{/* Блок 4.1 (владелец, 14.08.2026) юр-строка идёт первым
предложением абзаца-дисклеймера, не отдельным блоком. */}
{SHORT_ESTIMATE_DISCLAIMER}{" "}
Диапазон отражает разброс цен по рынку, а не погрешность оценки.
{/* #2209: честное раскрытие точности замеренное покрытие бэктестом
по реальным ДКП Росреестра (2026-07: n=276, coverage 81.5%).

View file

@ -1,9 +1,14 @@
"use client";
/**
* §1.2-дисклеймер под ценовыми карточками несёт юр-требование владельца от
* 14.08.2026 (блок 4.1): SHORT_ESTIMATE_DISCLAIMER см. `lib/legal-copy.ts`.
*/
import { Fragment } from "react";
import type { Ref } from "react";
import { tokens } from "./tokens";
import type { ResultPanelData } from "./mappers";
import { SHORT_ESTIMATE_DISCLAIMER } from "@/lib/legal-copy";
const {
accent,
@ -557,20 +562,29 @@ export default function ResultPanel({
})}
</div>
{/* §1.2 честный разброс: диапазоны цен = рыночный спред, НЕ погрешность
оценки. Ставим сразу под ценовыми карточками, чтобы широкий диапазон
не читался как «неуверенность расчёта». */}
{/* §1.2 честный разброс + юр-дисклеймер (владелец, 14.08.2026, блок 4.1):
SHORT_ESTIMATE_DISCLAIMER идёт первым предложением, "разброс цен"
вторым, один абзац (три отдельных оговорки подряд читались бы
как шум). Ставим сразу под ценовыми карточками, чтобы широкий
диапазон не читался как «неуверенность расчёта».
Компенсация высоты: этот блок стал на строку выше, чем до
SHORT_ESTIMATE_DISCLAIMER (776px средняя колонка узкая для двух
предложений в одну строку) lineHeight/marginTop подрезаны, и
padding у "ranges + radar" box ниже уменьшен по вертикали, чтобы
не сжимать плитки "ИСТОЧНИКИ ДАННЫХ" (flex:1 ниже). Высота
артборда (1536×1024, v2/page.tsx) не менялась. */}
<div
style={{
// M3 — было 10px muted-микропринт; повышено до 12px body, чтобы
// ключевая honest-оговорка о разбросе читалась, а не терялась.
fontSize: 12,
lineHeight: 1.5,
lineHeight: 1.4,
color: body,
marginTop: -4,
marginTop: -6,
}}
>
Диапазоны показывают разброс цен на рынке, а не погрешность оценки.
{SHORT_ESTIMATE_DISCLAIMER} Диапазоны показывают разброс цен на рынке,
а не погрешность оценки.
</div>
{/* ranges + radar */}
@ -581,7 +595,9 @@ export default function ResultPanel({
backdropFilter: "blur(6px)",
border: `1px solid ${line2}`,
borderRadius: 8,
padding: "18px 20px",
// было "18px 20px" — вертикаль подрезана на 4px сверху/снизу, см.
// комментарий к дисклеймеру выше (компенсация высоты под #4.1).
padding: "14px 20px",
display: "grid",
gridTemplateColumns: "1fr 1fr",
gap: 24,

View file

@ -0,0 +1,25 @@
/**
* Юридические короткие оговорки для экранов расчёта «Меры».
*
* Источник: юр-требование владельца от 14.08.2026 (блок 4.1) прямо под
* диапазоном цены на экране результата обязана быть строка «Ориентировочный
* расчёт. Не является официальной оценкой.».
*
* Модуль НАМЕРЕННО без импортов (кроме типов) используется и из закрытого
* контура (`components/trade-in/v2/ResultPanel.tsx`,
* `components/trade-in/HeroSummary.tsx`), и потенциально из `/mera-public`,
* где действует isolation-guard
* (`scripts/check-mera-public-isolation.mjs`) любой транзитивный импорт
* закрытого контура (useMe / lib/api / lib/sessionId / isPathAllowed) в
* публичный бандл провалит проверку.
*
* В репозитории уже есть соседние, но НЕ идентичные дисклеймеры не путать
* и не плодить пятый/шестой литерал с той же сутью:
* - `src/app/mera-public/content.ts` DELIVERABLES_DISCLAIMER (135-ФЗ)
* - `src/app/mera-public/_components/SiteFooter.tsx:109`
* - `src/app/oferta/page.tsx:253`
* - `backend/app/services/trade_in_pdf.py` (версия для PDF-отчёта)
*/
export const SHORT_ESTIMATE_DISCLAIMER =
"Ориентировочный расчёт. Не является официальной оценкой.";