fix(mera): кликабельная ссылка на политику ПДн в чекбоксе согласия + синхронизация версии (блоки 2, 5.4) #2886

Merged
lekss361 merged 2 commits from fix/mera-consent-policy-link into main 2026-08-14 12:48:34 +00:00
Owner

Юр-документ владельца от 14.08.2026, блоки 2 и 5.4. Требование (позиция РКН): текст рядом с чекбоксом должен быть кликабельной ссылкой на сам документ, а не упоминанием его существования.

Что было по факту. Аудит показал: чекбокс не предустановлен ✓, отправка без галочки невозможна ✓ (early-return на фронте + Literal[True] → 422 на бэке + CHECK-констрейнт в БД), а вот рядом с чекбоксом стоял простой текст со ссылкой на закон — ни одного href в файле не было. Плюс версия политики в БД писалась как 2026-07, при том что политика утверждена 13 августа.

Что сделано

  • Текст чекбокса → формулировка владельца: «Согласен(-на) на обработку персональных данных в соответствии с Политикой обработки персональных данных», где выделенное — next/link на /mera-public/privacy, target="_blank" (клик не должен сбрасывать заполненную форму).
  • _CONSENT_POLICY_VERSION2026-08-13, выведена из PRIVACY_APPROVAL — версия обязана указывать на редакцию документа, на который согласие теперь фактически ссылается.
  • _CONSENT_TEXT_SNAPSHOT обновлён под новый текст (плоский, без разметки).
  • PRIVACY_PATH вынесен в lib/legal-copy.ts (модуль без импортов), content.ts его ре-экспортирует — существующие потребители не тронуты. Так B2B-виджет не тянет модуль лэндинга с реквизитами и банковскими данными.

Тесты — главная ловушка этой правки. test_consent_text_frontend_sync.py вытаскивал текст регэкспом <span>(.*?)</span> и сравнивал побайтово с бэкендовым снапшотом: любая разметка внутри <span> его роняла. Экстрактор починен (снимает {" "}-спейсеры, JSX-комментарии и теги, нормализует пробелы) и не ослаблен — при расхождении текстов по-прежнему падает. Добавлено: 2 юнит-теста на сам экстрактор и новый test_consent_policy_version_matches_privacy_approval_date, который парсит дату утверждения из content.ts и падает при рассинхронизации версии — ровно та тихая ловушка, которую нашёл аудит.

Ссылка через next/link, а не <a> — намеренно: в проде basePath="/trade-in", голый <a href="/mera-public/privacy"> вёл бы в 404.

Легаси HeroTransparency.tsx (недостижим с живого маршрута) приведён к той же формулировке без ссылки, чтобы тексты не разъехались.

Проверено: бэк — test_consent_text_frontend_sync.py + test_trade_in_lead.py 20 passed, test_estimate_consent_gate.py 14 passed, ruff чисто; фронт — tsc --noEmit, next lint, vitest 29/29, check:mera-public-isolation (18 файлов).

Конфликт при мерже: lib/legal-copy.ts создаётся и в PR #2884 — файлы сольются вручную (там SHORT_ESTIMATE_DISCLAIMER, здесь PRIVACY_PATH).

Что этот PR НЕ закрывает: IP пишется из первого хопа X-Forwarded-For без проверки доверенного прокси, то есть подделываем клиентом — для доказательной силы это стоит закрыть отдельно (Caddy наш). И у соседнего контура согласия — на саму оценку (_ESTIMATE_CONSENT_*) — фронтового чекбокса нет вовсе.

Юр-документ владельца от 14.08.2026, блоки 2 и 5.4. Требование (позиция РКН): текст рядом с чекбоксом должен быть **кликабельной ссылкой на сам документ**, а не упоминанием его существования. **Что было по факту.** Аудит показал: чекбокс не предустановлен ✓, отправка без галочки невозможна ✓ (early-return на фронте + `Literal[True]` → 422 на бэке + CHECK-констрейнт в БД), а вот рядом с чекбоксом стоял простой текст со ссылкой на *закон* — ни одного `href` в файле не было. Плюс версия политики в БД писалась как `2026-07`, при том что политика утверждена 13 августа. **Что сделано** - Текст чекбокса → формулировка владельца: «Согласен(-на) на обработку персональных данных в соответствии с **Политикой обработки персональных данных**», где выделенное — `next/link` на `/mera-public/privacy`, `target="_blank"` (клик не должен сбрасывать заполненную форму). - `_CONSENT_POLICY_VERSION` → `2026-08-13`, выведена из `PRIVACY_APPROVAL` — версия обязана указывать на редакцию документа, на который согласие теперь фактически ссылается. - `_CONSENT_TEXT_SNAPSHOT` обновлён под новый текст (плоский, без разметки). - `PRIVACY_PATH` вынесен в `lib/legal-copy.ts` (модуль без импортов), `content.ts` его ре-экспортирует — существующие потребители не тронуты. Так B2B-виджет не тянет модуль лэндинга с реквизитами и банковскими данными. **Тесты — главная ловушка этой правки.** `test_consent_text_frontend_sync.py` вытаскивал текст регэкспом `<span>(.*?)</span>` и сравнивал побайтово с бэкендовым снапшотом: любая разметка внутри `<span>` его роняла. Экстрактор починен (снимает `{" "}`-спейсеры, JSX-комментарии и теги, нормализует пробелы) и **не ослаблен** — при расхождении текстов по-прежнему падает. Добавлено: 2 юнит-теста на сам экстрактор и новый `test_consent_policy_version_matches_privacy_approval_date`, который парсит дату утверждения из `content.ts` и падает при рассинхронизации версии — ровно та тихая ловушка, которую нашёл аудит. **Ссылка через `next/link`, а не `<a>`** — намеренно: в проде `basePath="/trade-in"`, голый `<a href="/mera-public/privacy">` вёл бы в 404. Легаси `HeroTransparency.tsx` (недостижим с живого маршрута) приведён к той же формулировке без ссылки, чтобы тексты не разъехались. Проверено: бэк — `test_consent_text_frontend_sync.py` + `test_trade_in_lead.py` 20 passed, `test_estimate_consent_gate.py` 14 passed, `ruff` чисто; фронт — `tsc --noEmit`, `next lint`, `vitest` 29/29, `check:mera-public-isolation` (18 файлов). **Конфликт при мерже:** `lib/legal-copy.ts` создаётся и в PR #2884 — файлы сольются вручную (там `SHORT_ESTIMATE_DISCLAIMER`, здесь `PRIVACY_PATH`). **Что этот PR НЕ закрывает:** IP пишется из первого хопа `X-Forwarded-For` без проверки доверенного прокси, то есть подделываем клиентом — для доказательной силы это стоит закрыть отдельно (Caddy наш). И у соседнего контура согласия — на саму оценку (`_ESTIMATE_CONSENT_*`) — фронтового чекбокса нет вовсе.
lekss361 added 1 commit 2026-08-14 12:33:53 +00:00
fix(tradein/lead): кликабельная ссылка на политику ПДн в чекбоксе согласия
All checks were successful
CI Trade-In / changes (pull_request) Successful in 11s
CI / changes (pull_request) Successful in 11s
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 1m6s
CI Trade-In / backend-tests (pull_request) Successful in 4m31s
74e7969ef9
РКН/владелец: рядом с чекбоксом согласия должна быть ссылка на сам документ
политики обработки ПДн, а не упоминание закона. Чекбокс в LeadForm.tsx
(v2, живой /trade-in/v2) теперь линкует "Политикой обработки персональных
данных" на /mera-public/privacy (target=_blank, чтобы не терять заполненную
форму). Путь вынесен в новый src/lib/legal-copy.ts (модуль без импортов) —
content.ts ре-экспортирует оттуда, чтобы B2B-виджет не тянул B2C-лэндинг-модуль
целиком.

_CONSENT_TEXT_SNAPSHOT/_CONSENT_POLICY_VERSION в lead.py обновлены под новый
плоский текст и дату утверждения политики (PRIVACY_APPROVAL: 2026-08-13).
test_consent_text_frontend_sync.py: экстрактор теперь снимает JSX-теги/{" "}
спейсеры перед сравнением (иначе сломался бы на разметке ссылки) + новый тест
держит _CONSENT_POLICY_VERSION в синхроне с PRIVACY_APPROVAL из content.ts,
чтобы версия не расходилась молча с редакцией документа.

Легаси-дубль в HeroTransparency.tsx (недостижим с живого роута) — текст
приведён в соответствие без ссылки: компонент не смонтирован нигде, и нет
теста, который держал бы там ссылку в актуальном состоянии.
bot-backend added 1 commit 2026-08-14 12:41:38 +00:00
merge main: объединить legal-copy.ts (PRIVACY_PATH + SHORT_ESTIMATE_DISCLAIMER)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 10s
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 1m29s
CI Trade-In / backend-tests (pull_request) Successful in 4m49s
f1491068f4
Оба модуля были созданы параллельно в разных ветках под один и тот же файл:
здесь — путь к политике ПДн для ссылки в чекбоксе согласия (блок 2),
в #2884 — короткая оговорка под диапазоном цены (блок 4.1). Обе константы
живут в одном модуле-без-импортов, шапка объединена.
lekss361 merged commit 0f0a3bbd79 into main 2026-08-14 12:48:34 +00:00
lekss361 deleted branch fix/mera-consent-policy-link 2026-08-14 12:48:34 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2886
No description provided.