From c4beee29ffa6ee23ff24ae9de9efd585cd57c779 Mon Sep 17 00:00:00 2001
From: bot-backend
Date: Mon, 31 Aug 2026 13:02:45 +0500
Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B1=D0=B8=D0=B7=D0=BD?=
=?UTF-8?q?=D0=B5=D1=81=D0=B0:=20=D1=83=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20?=
=?UTF-8?q?=D0=BE=D0=B1=D0=B5=D1=89=D0=B0=D0=BD=D0=B8=D1=8F,=20=D0=BA?=
=?UTF-8?q?=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D1=85=20=D0=BD=D0=B5=D1=82=20?=
=?UTF-8?q?=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=82=D1=83=D1=80=D0=B5;=20=D0=B3?=
=?UTF-8?q?=D0=B5=D0=B9=D1=82=20=D1=87=D0=B8=D1=81=D0=B5=D0=BB=20=D0=BD?=
=?UTF-8?q?=D0=B0=D0=BA=D1=80=D1=8B=D0=BB=20=D0=BF=D0=BE=D0=B4=D1=81=D1=82?=
=?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Снимает два замечания ревью.
1. КОПИЯ ОБЕЩАЛА НЕСУЩЕСТВУЮЩЕЕ. «Расчёты по потоку адресов», «не для одной
сделки, а потоком», «по вашему потоку адресов» — всё это подразумевает
массовую загрузку, которой в контуре нет: ни CSV, ни импорта, ни пакетной
ручки. Проверено grep-ом по src/app/v2.
Что там ЕСТЬ на самом деле и теперь названо: учётные записи команды
(app/api/v1/team.py), история своих расчётов (useEstimateHistory, оверлей
«Предыдущие оценки»), месячный лимит на аккаунт (account_quota_overrides,
monthly_limit/unlimited), выдача доступа вручную.
Это ровно тот дефект, который на этом лендинге выкорчёвывали весь день:
величина или возможность, которой никто не мерил и не делал, в продуктовом
голосе. Новая страница не имеет права начинать заново.
2. ГЕЙТ ЧИСЕЛ НЕ ВИДЕЛ НОВУЮ СТРАНИЦУ. Сканер знал два места: корневой
page.tsx и каталог _components/v3. Публичная /business под него не попадала —
правило держалось на памяти автора. Теперь подстраницы находятся ОБХОДОМ
каталога, а не списком: список — снимок, следующую страницу в него снова
забудут вписать.
Юридические страницы (оферта, политика, возврат, документы) исключены явно и
с обоснованием: они состоят из ссылок на законы («Закон РФ от 07.02.1992
№ 2300-1», «152-ФЗ», «ст. 18.1»), а по форме это те же числа, что и замеры.
Отличить регулярным выражением нельзя, и правило гейта к ним не относится —
там числа цитируются из нормативных актов, а не утверждаются о рынке.
Расширение проверено: включение этих страниц давало 4 ложных срабатывания.
Фальсификация: вписанные в /business «42 700 квартир» роняют гейт по значению
с указанием файла. 150 passed, tsc и eslint чисто.
---
.../__tests__/landing-numbers-gate.test.ts | 49 +++++++++++++++++++
.../src/app/mera-public/business/page.tsx | 17 ++++---
2 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/tradein-mvp/frontend/src/app/mera-public/__tests__/landing-numbers-gate.test.ts b/tradein-mvp/frontend/src/app/mera-public/__tests__/landing-numbers-gate.test.ts
index 369ba1a0..328fbf4d 100644
--- a/tradein-mvp/frontend/src/app/mera-public/__tests__/landing-numbers-gate.test.ts
+++ b/tradein-mvp/frontend/src/app/mera-public/__tests__/landing-numbers-gate.test.ts
@@ -79,8 +79,57 @@ const V3_DIR = "_components/v3";
const GENERATED = ["ekb-districts.ts"];
const GENERATED_MARK = "СГЕНЕРИРОВАН";
+/**
+ * ПОДСТРАНИЦЫ ПЕРИМЕТРА тоже под гейтом, а не только корень и v3-секции.
+ *
+ * 31.08.2026 завели `/business`, и ревьюер заметил, что новая ПУБЛИЧНАЯ
+ * страница чисел ничем не сторожится: сканер знал ровно два места — корневой
+ * `page.tsx` и каталог `_components/v3`. Чисел там тогда не было, но правило
+ * держалось на том, что автор о нём помнил.
+ *
+ * Каталоги перечисляются ОБХОДОМ, а не списком: список — снимок, и следующую
+ * страницу в него снова забудут вписать. Обход находит её сам.
+ */
+/**
+ * ЮРИДИЧЕСКИЕ СТРАНИЦЫ ПОД ЭТОТ ГЕЙТ НЕ ПОПАДАЮТ — и это не послабление.
+ *
+ * Гейт ищет ФОРМУ величины: «14,5 %», «42 700», «150 ₽». Тексты оферты,
+ * политики и возврата состоят из ссылок на законы, и по форме они те же самые:
+ *
+ * Закон РФ от 07.02.1992 № 2300-1 «О защите прав потребителей»
+ * Федеральный закон от 27.07.2006 № 152-ФЗ
+ * ст. 18.1 152-ФЗ
+ *
+ * Отличить номер закона от замера рынка регулярным выражением нельзя, а
+ * подгонять под них исключения по одному значило бы дырявить сам сканер.
+ * Правило, которое гейт защищает, к этим страницам и не относится: там числа
+ * ЦИТИРУЮТСЯ из нормативных актов, а не утверждаются о рынке.
+ *
+ * Список ЯВНЫЙ и короткий: молчаливое расширение (например «все страницы с
+ * длинным текстом») однажды укроет и маркетинговую.
+ */
+const LEGAL_PAGES = new Set(["oferta", "privacy", "refund", "docs"]);
+
+const PAGE_DIRS = readdirSync(ROOT, { withFileTypes: true })
+ .filter(
+ (e) =>
+ e.isDirectory() &&
+ e.name !== "__tests__" &&
+ e.name !== "_components" &&
+ !LEGAL_PAGES.has(e.name),
+ )
+ .map((e) => e.name)
+ .sort();
+
+const SUBPAGES = PAGE_DIRS.flatMap((dir) =>
+ readdirSync(join(ROOT, dir))
+ .filter((name) => /^page\.tsx?$/u.test(name))
+ .map((name) => `${dir}/${name}`),
+);
+
const V3_SOURCES = [
LANDING_ROOT,
+ ...SUBPAGES,
...readdirSync(join(ROOT, V3_DIR))
.filter((name) => /\.tsx?$/u.test(name) && !GENERATED.includes(name))
.sort()
diff --git a/tradein-mvp/frontend/src/app/mera-public/business/page.tsx b/tradein-mvp/frontend/src/app/mera-public/business/page.tsx
index 38de70c0..a56fcfcf 100644
--- a/tradein-mvp/frontend/src/app/mera-public/business/page.tsx
+++ b/tradein-mvp/frontend/src/app/mera-public/business/page.tsx
@@ -61,9 +61,9 @@ export default function BusinessPage() {
ДЛЯ БИЗНЕСА
МЕРА для бизнеса
- Оценка квартиры по живым объявлениям — не для одной сделки, а
- потоком: для агентства, застройщика или компании, которая принимает
- квартиры в зачёт.
+ Оценка квартир по живым объявлениям под своей учётной записью —
+ для агентства, застройщика или компании, которая принимает квартиры
+ в зачёт.
@@ -75,8 +75,8 @@ export default function BusinessPage() {
Тем, кто считает не одну квартиру, а много и регулярно: агентствам
недвижимости, отделам продаж застройщиков, компаниям с программами
трейд-ин. Расчёт идёт по тем же источникам, что и бесплатная
- проверка на сайте, — но по вашему потоку адресов и под вашими
- учётными записями.
+ проверка на сайте, — но под учётными записями вашей команды, с
+ сохранением истории и месячным лимитом на аккаунт.
Если задача разовая — квартира одна, и нужно понять цену, — идти
@@ -101,9 +101,10 @@ export default function BusinessPage() {
Бизнес-контур
- Закрытый контур с доступом по учётной записи: расчёты по потоку
- адресов и история по ним. Доступ выдаётся вручную, после
- разговора, — самостоятельной регистрации в нём нет
+ Закрытый контур с доступом по учётной записи: история своих
+ расчётов, учётные записи команды, месячный лимит на аккаунт.
+ Доступ выдаётся вручную, после разговора, — самостоятельной
+ регистрации в нём нет