Files
portal/app/tests/Frontend/layoutMasking.spec.ts
T
Дмитрий 8e687f99c1 feat: сквозной путь клиента от рекламного клика до Вебвизора
Путь человека рвался пополам: лендинг и кабинет считали разные счётчики,
а вход и регистрация не писались вообще. Почему люди бросают регистрацию,
узнать было нельзя.

Счётчик лендинга 110476275 становится счётчиком полного пути и грузится
на всех страницах кабинета. Прежний счётчик кабинета 110494416 не тронут,
его история цела, на страницах кабинета работают оба.

Что сделано:
- загрузчик Метрики поднимает счётчики по области: public или app
- белый список раскладок: новая раскладка Метрику НЕ получает по умолчанию
- формы входа и регистрации закрыты от записи классом ym-hide-content
- метка utm не теряется при заходе сразу в кабинет минуя лендинг

Найдено при исполнении и закрыто:
- почта выводится в заголовке ДВУХ экранов, то есть вне формы: класс на форме
  её не накрывал, утекла бы в записи открытым текстом. Замаскирована точечно
- Метрика, единожды запустившись, пишет дальше сама и роутером не выключается.
  Админ входит через общий /login и идёт в админку к чужим телефонам.
  Корни админки и портала продаж закрыты ym-hide-content
- ключ metrika в config/services.php был объявлен ДВАЖДЫ: раздвоил его мой
  же merge 42e907c8 от 14.07. PHP молча берёт последний, правка первого блока
  не дала бы ничего и не выругалась. Дубль вычищен, прочие конфиги проверены

В кабинете Метрики включена галочка «включая поддомены»: счётчик принимал
данные только с liderra.ru и молча выбрасывал бы всё из кабинета.

Заодно погашен долг по статанализу: 63 ошибки держали коммит. Все до одной
в тестах, в боевом коде ноль. Природа ложная — анализатор не понимает
устройство Pest и ругается на обычный вызов внутри теста. Их гасят списком
игнора, а список пересобирали 18.07, тогда как тесты добавлялись 19-20.07,
в том числе мои по рекламной аудитории. Список пересобран, стало 0 ошибок.
Долг накопился в том числе потому, что вчера я обошёл эту проверку.

Тесты: 27 новых, все проверены вырезанием защиты. Полный набор 202 файла зелёный.

План: docs/superpowers/plans/2026-07-20-skvoznoy-put-do-vebvizora.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 16:47:19 +03:00

36 lines
2.2 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
/**
* Админка и портал продаж не должны попадать в записи Вебвизора: там чужие
* персональные данные — телефоны клиентов, сделки, карточки.
*
* Белого списка раскладок (metrikaScope) для этого НЕ ХВАТАЕТ. Он управляет
* только отправкой заходов. Сама Метрика, единожды запустившись на странице
* (например на общем /login, откуда входит администратор), продолжает писать
* автономно при переходах внутри приложения — роутер её остановить не может.
*
* Поэтому на корне обеих раскладок обязан висеть ym-hide-content: запись
* продолжится, но содержимое в ней будет размыто.
*
* Найдено 20.07.2026 при исполнении плана 2026-07-20-skvoznoy-put-do-vebvizora:
* до включения Метрики на странице входа этой дыры не существовало, правка
* создавала бы её сама.
*/
const RASKLADKI = ['AdminLayout.vue', 'SalesLayout.vue'];
describe('раскладки с чужими ПДн закрыты от Вебвизора', () => {
it.each(RASKLADKI)('%s несёт ym-hide-content на корневом v-app', (fayl) => {
const put = resolve(__dirname, '../../resources/js/layouts', fayl);
const ishodnik = readFileSync(put, 'utf-8');
// Именно на корне, а не где-то в файле: класс должен накрыть всё
// поддерево раскладки, включая экраны, которые в неё подставляются.
const koren = ishodnik.split('\n').find((s) => s.includes('<v-app'));
expect(koren, `не нашёл корневой <v-app> в ${fayl}`).toBeDefined();
expect(koren).toContain('ym-hide-content');
});
});