fix(mera/b2c): подсказка дублировала адрес, а числа в результате спорили
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
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 1m0s

Оба дефекта найдены проходом клиентского пути на проде 27.08.

ПОДСКАЗКА АДРЕСА печатала одно и то же дважды. Строка списка состоит из
главной строки (`label`) и пояснительной (`full_address`), но подсказчик
для дома отдаёт их совпадающими буква в букву — проверено на проде:

    {"label":"Свердловская область, г. Екатеринбург, ул. Малышева, д. 51",
     "full_address":"Свердловская область, г. Екатеринбург, ул. Малышева, д. 51"}

Человек видел адрес продублированным в каждой строке выпадающего списка.
Показываем вторую строку только когда она отличается: замысел (короткое имя
сверху, полный адрес под ним) сохраняется, если подсказчик когда-нибудь
начнёт их различать.

ЧИСЛА В РЕЗУЛЬТАТЕ спорили друг с другом. Плитка сверху: «30 похожих
квартир продаётся в радиусе 1 км». Плитка под ней: «столько в среднем висит
объявление из этих 6». Слово «этих» указывает на 30, а стоит рядом 6 —
читается как ошибка в расчёте.

Шесть — это те объявления, у которых известна дата публикации; медиана
считается только по ним. Теперь доля названа явно («дата известна у 6 из
30»), а когда известна у всех — не упоминается вовсе, чтобы «30 из 30» не
шумело. Честное имя величины сохранено: это возраст активного объявления,
а не срок продажи (тест на это как был, так и остался).

Проверено: 27 тестов mera-public зелёные, tsc --noEmit чист.
This commit is contained in:
bot-backend 2026-08-27 14:29:19 +03:00
parent d18a2d607b
commit e85cafd9a9
3 changed files with 35 additions and 2 deletions

View file

@ -45,6 +45,24 @@ describe("describeCoverage", () => {
expect(ageTile.label).not.toMatch(/продаётся|продаются|срок продажи|уходят/i);
});
it("подпись под возрастом не показывает число, спорящее с плиткой выше", () => {
// На проде 27.08: сверху «30 похожих квартир», под ней «из этих 6».
// Слово «этих» указывало на 30, и человек читал два разных числа об
// одном и том же. Долю называем явно — либо не называем вовсе.
const [cohortTile, ageTile] = describeCoverage(
probe({ n_listings: 30, n_with_age: 6 }),
).tiles;
expect(cohortTile.value).toBe("30");
expect(ageTile.label).toContain("6 из 30");
expect(ageTile.label).not.toMatch(/этих/);
});
it("когда дата известна у всех — доля не упоминается вовсе", () => {
// «дата известна у 30 из 30» — шум: доля есть, но она ничего не сообщает.
const [, ageTile] = describeCoverage(probe({ n_listings: 30, n_with_age: 30 })).tiles;
expect(ageTile.label).toBe("столько в среднем висит объявление");
});
it("город вне покрытия — говорим прямо и не предлагаем платный шаг", () => {
const verdict = describeCoverage(probe({ status: "not_covered", city: "", n_listings: 0 }));
expect(verdict.offerPaidStep).toBe(false);

View file

@ -345,7 +345,14 @@ export function EstimateFlow() {
onClick={() => choose(item)}
>
<span className={styles.estSuggestMain}>{item.label}</span>
<span className={styles.estSuggestSub}>{item.full_address}</span>
{/* Вторая строка только когда она что-то добавляет.
Подсказчик отдаёт `label` и `full_address` порознь,
но для дома они сплошь и рядом совпадают буква в
букву, и человек видел один и тот же адрес дважды в
каждой строке списка. Найдено на проде 27.08. */}
{item.full_address !== item.label && (
<span className={styles.estSuggestSub}>{item.full_address}</span>
)}
</button>
</li>
))}

View file

@ -64,10 +64,18 @@ function tilesFor(probe: CoverageProbe): CoverageTile[] {
];
if (probe.median_listing_age_days !== null) {
// Медиана считается НЕ по всей когорте, а только по тем объявлениям, у
// которых известна дата публикации. Прежняя подпись — «из этих N» —
// указывала словом «этих» на число в плитке выше (в проде: 30 квартир,
// а рядом «из этих 6»), и человек читал два спорящих числа. Называем
// долю явно, когда она меньше целого. Найдено на проде 27.08.
const partial = probe.n_with_age < probe.n_listings;
tiles.push({
value: `${probe.median_listing_age_days} дн.`,
// Формулировка запинена тестом — см. шапку модуля.
label: `столько в среднем висит объявление из этих ${probe.n_with_age}`,
label: partial
? `столько в среднем висит объявление; дата известна у ${probe.n_with_age} из ${probe.n_listings}`
: "столько в среднем висит объявление",
});
}