Files
enduro-trails/docs/work-items/ET-008/01-brd.md
claude-bot 9c81ebd653
All checks were successful
CI / lint (push) Successful in 4s
CI / test (push) Successful in 6s
CI / build (push) Successful in 1s
analyst(ET): auto-commit from analyst run_id=25
2026-05-31 17:13:21 +00:00

10 KiB
Raw Blame History

type, work_item_id, title, version, status, created_at, updated_at, authors
type work_item_id title version status created_at updated_at authors
brd ET-008 BRD: Smoke test analyst integration 1 draft 2026-05-31 2026-05-31
agent:analyst

BRD — ET-008: Smoke test analyst integration

1. Цель

Подтвердить, что цепочка агентов analyst → architect → coder → tester работоспособна end-to-end: аналитик выдаёт валидные артефакты, архитектор по ним строит план, кодер минимально его реализует, тестировщик прогоняет автотесты (включая Playwright) и автоматически закрывает задачу.

Полезной фичи для конечного пользователя нет — это намеренно технический smoke. Минимальное изменение во фронтенде нужно лишь как «отпечаток сборки», который Playwright увидит и подтвердит.

2. Контекст

  • Веб-приложение: MapLibre GL JS 4.7 + vanilla JS, без фреймворка.
  • Базовая страница: src/web/index.html; стили — src/web/app.css; логика — src/web/app.js (НЕ ТРОГАТЬ в рамках ET-008).
  • ET-007 (Спутниковая карта) уже использовал такую же idea-pipeline для dry-run; ET-008 — следующая итерация, ещё минимальнее: ноль JS, ноль внешних зависимостей, ноль localStorage.
  • Имеется работающая Playwright-инфра (tests/web/e2e/), которая умеет открывать тест-окружение и снимать скриншоты.

3. Scope

In scope

# Функция
F-01 DOM-элемент #pipeline-smoke с текстом «ET-008 ✓» в src/web/index.html
F-02 CSS-правила для #pipeline-smoke в src/web/app.css (скрыт по умолчанию)
F-03 CSS-правила для body.smoke-mode #pipeline-smoke (видим в smoke-режиме)
F-04 Инлайн-скрипт в <head> src/web/index.html, добавляющий smoke-mode к <body> по URL-условию
F-05 Условие активации: location.search.includes('smoke=et-008') ИЛИ location.hash.includes('smoke=et-008')
F-06 По умолчанию (без параметра) маркер физически в DOM, но display:none
F-07 Маркер aria-hidden="true" / role="presentation" — не попадает в screen reader
F-08 Позиционирование: position: fixed; left: 8px; bottom: 8px; z-index ниже sheets/popup'ов
F-09 Совместимость с тёмной и светлой темами — собственные цвета, не наследует темовые переменные

Out of scope

  • JavaScript-логика в src/web/app.js, units.js, gpx.js.
  • Любой backend / БД / OSRM / тайлы.
  • Сохранение состояния (localStorage / sessionStorage / cookies).
  • Видимость по нажатию кнопки / shortcut'у клавиатуры / тапу — только URL.
  • Локализация (текст «ET-008 ✓» одинаков для всех языков).
  • Анимации появления / скрытия.
  • Управление через query API (REST/IPC).
  • Мобильный layout-tuning (маркер одинаков на desktop и mobile).
  • Любые другие work item identifiers, кроме et-008.

4. Метрики успеха

Метрика Критерий
Наличие маркера в DOM На любой загрузке document.querySelector('#pipeline-smoke') не null
Скрытость по умолчанию На ? (без параметра) getComputedStyle(...).display === 'none'
Видимость в smoke-режиме На ?smoke=et-008 или #smoke=et-008 маркер визуально различим в левом нижнем углу
Контент маркера textContent.trim() === 'ET-008 ✓'
Корректность ARIA aria-hidden="true", role="presentation"
Отсутствие конфликтов Маркер не перекрывает #map-controls-r, sheets, .maplibregl-ctrl-attrib
Стабильность тем После toggleTheme() маркер остаётся видим/скрыт согласно своему правилу
Отсутствие регрессий Все существующие E2E (ET-001..ET-007) остаются зелёными
Время от клика до отображения После загрузки страницы маркер показан до DOMContentLoaded end (инлайн-скрипт)
Отсутствие сетевых запросов ET-008 не порождает ни одного нового HTTP-запроса
Откатываемость Полный откат — 3 диффа (HTML head + HTML body + CSS блок), 1 коммит

5. Риски

Риск Вероятность Влияние Митигация
Инлайн-скрипт в <head> ломает CSP Низкая Среднее CSP не настроен сейчас. Если когда-то будет — переключить на data-атрибут + CSS-only
#pipeline-smoke перекрывает важный UI (например .maplibregl-ctrl-scale) Низкая Низкое z-index: 1 — ниже всех плавающих контролов; позиция фиксирована подальше
Маркер случайно засветился пользователю (например shared link с ?smoke=et-008) Низкая Низкое Текст нейтральный, не раскрывает ничего внутреннего; стиль ненавязчивый
Body-класс smoke-mode конфликтует с будущим классом темы Низкая Низкое Префикс smoke- зарезервирован; в проекте сейчас нет похожих имён
ARIA-атрибуты «protect» сломаются при mutation observer на body Низкая Низкое aria-hidden ставится статически в HTML, не из JS
Маркер ломает Playwright-снимки других тестов Низкая Низкое По умолчанию display:none — на скриншоте не виден, BB-rect = 0
Лишний div снижает производительность DOM Очень низкая Очень низкое 1 элемент, без подписок, без обработчиков
Старые браузеры не поддерживают includes на строках Очень низкая Низкое String.prototype.includes — ES2015, поддержано во всех целевых браузерах

6. Зависимости

  • Внешние сервисы: нет.
  • Внутренние: только src/web/index.html, src/web/app.css.
  • Не зависит от ET-005 / ET-006 / ET-007.
  • Не блокирует ни одну фазу (PH-1..PH-9).
  • Не вносит изменений в app.js, units.js, gpx.js.
  • Не меняет style.json, style-dark.json.
  • Backend, БД, OSRM, миграции, контейнеры — не затрагиваются.
  • CI/CD — не меняется. Только новые E2E-тесты для самого маркера в tests/web/e2e/pipeline-smoke.spec.ts.

7. Критерии smoke-успеха (для пайплайна)

Эта работа считается завершённой, когда:

  1. Все 5 артефактов аналитика (00..04b) присутствуют и валидны.
  2. Архитектор выдаёт минимум один план в 05-architecture.md или эквивалент.
  3. Кодер вносит изменения только в src/web/index.html + src/web/app.css (по diff'у видно).
  4. Все тесты UT/IT/E2E зелёные на test-окружении.
  5. Tester автоматически закрывает задачу.

Само наличие зелёного smoke-прогона важнее, чем визуальная эстетика маркера.