22 KiB
22 KiB
type, work_item_id, title, version, status, created_at, authors
| type | work_item_id | title | version | status | created_at | authors | |
|---|---|---|---|---|---|---|---|
| tech-risks | ET-009 | Технические риски — ET-009: Активация EnduroRussia + Wikiloc | 1 | approved | 2026-06-01 |
|
Технические риски — ET-009
Технические риски этапа активации двух новых GPS-источников. Бизнес-риски —
в BRD §6 ET-009. Многие риски наследуются от ET-008 (R-1, R-5, R-9 из
docs/work-items/ET-008/10-tech-risks.md); здесь — специфика ET-009.
Шкала: вероятность (Н/С/В) × влияние (Н/С/В).
R-1 — Wikiloc меняет HTML → парсер возвращает 0 треков
- Описание: Парсер Wikiloc опирается на regex-извлечение
<a href="/trails/…/<id>">и<h1>для названия. Wikiloc может в любой момент изменить разметку (новый шаблон, JS-rendering) → парсер вернёт 0 треков. - Вероятность / Влияние: В / С.
- Митигация:
- Парсер уже спроектирован graceful:
returnбезraiseпри отсутствии match'ей regex (см.wikiloc.py::_extract_track_paths). - Health-эндпоинт показывает
tracks_by_source.wikiloc = 0после прогона → видимый сигнал оператору. - Unit-тест UT-WL-01 на снимке
wikiloc-search-page1.html— при смене разметки CI зелёным быть не сможет, разработчик обновит фикстуру + парсер за 1 итерацию. gps_sources.yaml::wikiloc.enabled: false— мгновенное отключение без deploy при критической поломке.
- Парсер уже спроектирован graceful:
- Наследник от: ET-008 R-1 (general).
R-2 — Wikiloc банит IP mva154
- Описание: Скрейпер с фиксированного IP может попасть в чёрный список Wikiloc'а (особенно при ошибках rate-limit или накоплении 1000+ запросов в сутки). Pipeline начнёт получать 403/429 на все запросы → новых треков не будет.
- Вероятность / Влияние: С / В.
- Митигация:
rate_limit_sec: 10— самый консервативный rate в проекте.max_tracks_per_run: 50— soft-cap на первом прогоне; ≤ 150 запросов на одну активацию.User-Agentс контактным URL — платформа может связаться через email до бана.- Graceful-stop на 403/429 — не агрессивный retry, не вызывает дополнительных запросов.
- Мониторинг первых 3 прогонов оператором; при систематических
403 →
enabled: false+ новый ADR-update «Wikiloc deprecated». - Запрет использования прокси через сторонний IP (нарушает дух прозрачности; см. ET-008 R-5).
R-3 — EnduroRussia API меняет схему ответа
- Описание:
enduro_russia.py::_parse_gpxожидает поляid,name,difficulty,created_atв JSON-items. Платформа может добавить/переименовать поля. - Вероятность / Влияние: Н / С.
- Митигация:
- Парсер использует
.get()с дефолтами — отсутствие необязательных полей не валит. - Отсутствие
id→ запись пропускается (continue), не валит весь прогон. - Контрактный smoke-тест
tests/contract/test_endurorussia_api_smoke.pyс маркером@pytest.mark.network— запускается nightly или вручную, сигнализирует о поломке внешнего API до пропущенного cron-прогона. - Pipeline-error не лоадит всю БД:
errors_jsonфиксирует, оператор видит через/health.
- Парсер использует
R-4 — Расхождение конфига enduro-russia.ru (с дефисом) vs
реального endurorussia.ru (без дефиса)
- Описание: До ET-009
gps_sources.yaml::enduro_russia.base_urlсодержитhttps://enduro-russia.ru(с дефисом), но реальный домен —https://endurorussia.ru(без дефиса; парсер по default использует именно его). При активацииenabled: trueбез фикса URL парсер использовал бы default из кода, ноexternal_urlсохранённых треков опирался бы наbase_urlиз конфига → fragmentation external_url'ов между «корректным» и «дефис-вариантом». - Вероятность / Влияние: Случилось (известный bug в конфиге) / В (при активации).
- Митигация:
- F-01 в BRD/TRZ — фикс URL в одно изменение.
- Регрессионный тест UT-ER-05 — проверяет, что парсер
сохраняет URL без дефиса при передаче
base_urlбез дефиса. - One-shot UPDATE для существующих треков (опционально, см.
07-infra-requirements.md§4.1).
R-5 — EnduroRussia и Wikiloc — двойник одного и того же трека → массовые дубли
- Описание: Авторы часто публикуют одну и ту же поездку и на
Wikiloc, и на EnduroRussia (Wikiloc даже сохраняет
creator=Wikilocв GPX мета-теге, что подтверждается на практике). Без правильно работающего dedup'а в БД появятся два трека с одинаковой геометрией. - Вероятность / Влияние: В / С.
- Митигация:
compute_dedup_key(ADR-006) основан наbbox+length+date, который при достаточно похожих координатах и одной дате попадает в один bucket → upsert ON CONFLICT мержит.- Интеграционный тест IT-DEDUP-01 — задаёт фикстуру
wikiloc-track.gpxс координатами, совпадающими с одним из EnduroRussia-треков; проверяет итоговое объединениеsources_json=['enduro_russia','wikiloc']. - Метаданные при merge — берутся от source с большим
source_priority(enduro_russia=80 > wikiloc=70);external_urls— оба сохраняются. - Если на практике dedup пропускает (например, точное время / точный bbox slightly off): план отступления ADR-006 §8 (сузить length-bucket, добавить activity).
R-6 — Cron первого прогона превышает окно из-за rate-limit Wikiloc
- Описание: При больших cap'ах
max_tracks_per_runи rate-limit 10 сек × 3 запроса/трек первый прогон Wikiloc может занять часы. - Вероятность / Влияние: С / Н.
- Митигация:
max_tracks_per_run: 50— soft-cap → ≤ 25 минут на прогон Wikiloc.- EnduroRussia при rate-limit 5 сек × 305 треков ≈ 25 минут — окей.
- Cron автоматизация отложена до отдельного DevOps-task'а после двух успешных ручных прогонов; оператор контролирует длительность.
- Опционально:
timeout 21600 docker compose ...в cron (ET-008 R-11 уже фиксирует).
R-7 — UI-фильтр «Источник» не подхватывает новые ID
- Описание: Если в ET-008 UI-фильтр (
#gps-source-grid) построен с захардкоженным списком[osm], новые источники не появятся как чекбоксы. - Вероятность / Влияние: Н / С.
- Митигация:
- Дизайн ET-008: UI строит фильтр динамически из ответа
/api/gps-tracks/health.tracks_by_source(источники с count > 0). После первого прогона ET-009 — фильтр сам покажет 3 чекбокса. - UI-тест TC-UI-04 (в
04b-ui-test-cases.mdET-008) расширен для ET-009: проверяет наличие 3 чекбоксов после двух прогонов. - Маппинг
SOURCE_LABELS(вgps_tracks.js) расширяется явно в ET-009 — даёт корректные читаемые названия.
- Дизайн ET-008: UI строит фильтр динамически из ответа
R-8 — Цветовая палитра в style.json / style-dark.json не содержит новых ID → линии серые
- Описание: В ET-008 match-expression
line-colorможет содержать толькоosm; новые источники получат fallback-серый. - Вероятность / Влияние: В / Н.
- Митигация:
- REQ-F-13 явно требует обновить match-expression с тремя источниками + fallback.
- Code-review-чеклист: проверить наличие
enduro_russia,wikilocвpaint.line-colorобоих стилей. - При пропуске: визуальный регресс легко заметен в smoke-тесте (TC-UI-05).
R-9 — Дамп БД (резервная копия с старым URL) — orphan записи
- Описание: Если на test-сервере есть резервная копия БД, в которой
external_urls_jsonсодержитenduro-russia.ru(с дефисом), то после фикса URL новые treki будут иметьendurorussia.ru(без дефиса), а старые —enduro-russia.ru. Это не криминал, но фрагментация атрибуции. - Вероятность / Влияние: Н / Н.
- Митигация:
- На практике
enduro_russiaдо ET-009 былenabled: false→ таких записей нет. Риск гипотетический. - Опциональный one-shot
UPDATE tracks SET external_urls_json = REPLACE(...)— фиксируется в14-deploy-log.mdесли применяется.
- На практике
R-10 — ADR-010 / ADR-012 регрессировали в proposed
- Описание: Между моментом написания BRD/TRZ ET-009 и моментом
активации (merge → deploy) кто-то откатил статус ADR в
proposed. Pipeline-guard заблокирует source сskipped_license. - Вероятность / Влияние: Н / В.
- Митигация:
- F-03 / REQ-F-05 — pre-check перед активацией:
Оба должны вернуть
grep -E "^status:" docs/work-items/ET-008/06-adr/ADR-010-enduro-russia-licensing.md grep -E "^status:" docs/work-items/ET-008/06-adr/ADR-012-wikiloc-licensing.mdaccepted. Иначе — STOP и эскалация архитектору. - Интеграционный тест IT-LIC-01 проверяет работу pipeline-guard'а:
подменяет
accepted → proposedв копии ADR-010 и убеждается, что pipeline скипает source сstatus='skipped_license'.
- F-03 / REQ-F-05 — pre-check перед активацией:
- Наследник от: ET-008 R-9.
R-11 — Пользовательский opt-in для новых источников
- Описание: Пользователи с уже сохранённым
localStorage['gps-tracks-sources'] = ["osm"]после ET-009 не увидят треки EnduroRussia/Wikiloc на своих устройствах — клиент сохраняет старое значение, новые источники по умолчанию не enabled в UI. - Вероятность / Влияние: В / Н.
- Митигация:
- Это сознательное решение UX (см.
08-data-requirements.md§4.2): добавление источников без согласия пользователя — нарушение принципа без сюрпризов. - Чекбоксы новых источников появятся в
#sheet-gps-filtersautomatically (через health-endpoint), пользователь может включить их вручную. - В release-notes (если они есть в проекте) — фиксируем «появились два новых источника, активация в фильтре».
- Это сознательное решение UX (см.
R-12 — Wikiloc-парсер сохраняет описание / автора несмотря на ADR-012
- Описание: ADR-012 §3 явно запрещает сохранять
descriptionиuserдля Wikiloc. Если реализация парсера не уважает этот запрет (например,TrackInsert.descriptionзаполняется), нарушение licensing-условий. - Вероятность / Влияние: Н / В.
- Митигация:
- Текущая реализация:
wikiloc.py::_parse_gpxвозвращаетTrackInsert(description=None, user=None)(зашито в коде). - Unit-тест UT-WL-05 проверяет, что
description=Noneиuser=Noneв возвращаемомTrackInsert. - Code-review checklist в
12-review.md: при любом изменении парсера Wikiloc убедиться, что эти поля остаются null.
- Текущая реализация:
R-13 — Тестовые фикстуры устаревают
- Описание: Снимки HTML/JSON, использованные в unit-тестах, отражают состояние API/HTML на момент снятия. Через 6-12 месяцев платформа может изменить разметку, и фикстуры станут неактуальны. Тесты пройдут (фикстура соответствует тесту), но парсер не будет работать в production.
- Вероятность / Влияние: С / С.
- Митигация:
- Контрактный smoke-тест
test_endurorussia_api_smoke.py(@pytest.mark.network, nightly) — проверяет реальную схему API, ловит расхождение. - Аналогичный smoke для Wikiloc не делаем (риск бана IP при регулярных запросах; ETC-009 §«REQ-F-16»).
- Health-эндпоинт показывает
tracks_by_source.wikilocпосле каждого продакшн-прогона; устойчивое 0 — сигнал. - При устаревании фикстуры — снимаем заново (1 час работы), парсер обновляем (1-3 часа).
- Контрактный smoke-тест
R-14 — Производительность endpoint деградирует при росте кол-ва треков
- Описание: REQ-NF-02 ET-008 фиксирует p95 ≤ 300 мс на bbox с ≤ 500 треков. После ET-009 в БД появятся ещё ≤ 250 треков — пренебрежимо относительно 5000 OSM.
- Вероятность / Влияние: Н / Н.
- Митигация:
- R-tree индекс по
geom(ADR-005) → O(log n) bbox-prefetch. - AC-20 — нагрузочный тест 100 запросов после первого прогона.
- При деградации — анализ EXPLAIN QUERY PLAN; добавление индекса
idx_tracks_sourceопционально (out of scope ET-009).
- R-tree индекс по
R-15 — Конфликт MAPPING-таблиц для одной активности
- Описание: EnduroRussia маппит
motorcycle → moto, Wikiloc тожеmotorcycle → moto— корректно. Но: EnduroRussia при отсутствии match'а в MAPPING возвращаетenduro(fallback), Wikiloc —moto. Для одного и того же трека (попавшего в оба источника) при merge получимactivity_typeот source с большимsource_priority=enduro_russia→enduro. Это OK: priority делает выбор детерминированным. - Вероятность / Влияние: Н / Н.
- Митигация:
- Принято as is. Уточнение в
08-data-requirements.md§3.4. - Unit-тесты UT-ER-04 и UT-WL-06 проверяют отдельные MAPPING'и.
- Принято as is. Уточнение в
R-16 — Регрессия e2e-тестов ET-008
- Описание: Расширение
style.json/gps_tracks.jsатрибуцией и цветами может случайно сломать существующие selectors / визуальные тесты ET-008. - Вероятность / Влияние: Н / С.
- Митигация:
- AC-19 — все e2e ET-008 (E-01..E-41) должны пройти после мерджа ET-009.
- Регрессионный прогон
pytest tests/e2e/ -v— обязательный шаг CI.
R-17 — Pipeline скипает source из-за неправильного license_adr path
- Описание: Pipeline-guard
_check_license_adrчитает YAML front-matter файла по пути изlicense_adr. Если путь опечатан (например,ADR-12-...вместоADR-012-...), guard вернёт false →status='skipped_license'. - Вероятность / Влияние: Н / В.
- Митигация:
- Pre-deploy check: убедиться, что
license_adrуказывает на реально существующий файл сstatus: accepted. - При первом запуске pipeline в test-среде оператор смотрит
pipeline_runs[-1].status; еслиskipped_license— диагностирует и исправляет до merge в main. - Pydantic-валидация
gps_sources.yamlв pipeline ET-008 уже требует обязательноеlicense_adrполе; отсутствие — exception при старте.
- Pre-deploy check: убедиться, что
- Наследник от: ET-008 R-9.
Сводная таблица
| ID | Риск | Вер. | Влияние | Класс | Статус |
|---|---|---|---|---|---|
| R-1 | Wikiloc меняет HTML | В | С | Высокий | принят + graceful + быстрое отключение |
| R-2 | Wikiloc банит IP mva154 | С | В | Высокий | rate-limit 10s + cap 50 + UA + monitor |
| R-3 | EnduroRussia API меняет схему | Н | С | Низкий | smoke-тест + graceful + health |
| R-4 | Расхождение URL enduro-russia vs endurorussia |
Случилось | В | Высокий | F-01 фикс + UT-ER-05 |
| R-5 | Дубли EnduroRussia/Wikiloc | В | С | Средний | dedup-key + IT-DEDUP-01 |
| R-6 | Cron первого прогона долго | С | Н | Низкий | max_tracks_per_run=50 + ручной прогон |
| R-7 | UI-фильтр не подхватит | Н | С | Низкий | динамика из health + SOURCE_LABELS |
| R-8 | Стили без новых цветов | В | Н | Низкий | REQ-F-13 + review + smoke |
| R-9 | Orphan записи с старым URL | Н | Н | Низкий | гипотетический (БД чистая); опц UPDATE |
| R-10 | ADR-010/012 регрессировали в proposed | Н | В | Высокий | pre-check + IT-LIC-01 |
| R-11 | Пользовательский opt-in для новых источников | В | Н | Низкий | сознательный UX-compromise |
| R-12 | Wikiloc сохраняет description/user | Н | В | Высокий | parser-design + UT-WL-05 + review |
| R-13 | Фикстуры устаревают | С | С | Средний | smoke-test + health + ручной refresh |
| R-14 | Деградация endpoint | Н | Н | Низкий | R-tree + AC-20 |
| R-15 | Конфликт MAPPING | Н | Н | Низкий | source_priority детерминирует |
| R-16 | Регрессия ET-008 e2e | Н | С | Низкий | AC-19 + pytest e2e |
| R-17 | Неправильный license_adr path |
Н | В | Высокий | pre-deploy check + Pydantic |
Высокие классы:
- R-1, R-2 — операционные, ожидаемые для скрейп-источника Wikiloc; митигация — multi-layer (graceful + monitor + конфиг-kill-switch).
- R-4 — known bug в конфиге, прямо адресован REQ-F-01.
- R-10, R-17 — критичны для legal compliance; митигация многослойная (pre-check + integration-тест + Pydantic).
- R-12 — критичен для соблюдения ADR-012; митигация через design + UT-WL-05 + review.
Блокирующих рисков нет. Высокие классы требуют внимания на этапе разработки и code review.
Эскалация
- arch:major-change — не выставляется (см. ADR-013 §«Классификация»). Изменение не вводит новых архитектурных компонентов.
- back-to:analysis — не требуется. ТЗ полное, BRD ясный,
open-questions в
TRZ §6закрыты дефолтными решениями. - Эскалация архитектору требуется только при срабатывании R-10
(ADR в
proposedна момент активации). Тогда задача останавливается до повторного апрува ADR.