---
type: trz
work_item_id: ET-001
title: "ТЗ: Чекбокс показа/скрытия POI в кнопке рельефа"
version: 3
status: proposed
created_at: 2026-06-14
updated_at: 2026-06-14
author: "agent:analyst"
relates_to: ET-002
---

# Техническое задание — ET-001: Видимость POI

> Поведение, описанное ниже, **уже реализовано в рамках ET-002**. ТЗ
> служит спецификацией для **верификации** существующей реализации плюс
> единственной новой правки — подписи чекбокса (REQ-F-01). Описание
> текущей реализации приведено как **контекст для тестирования**, а не
> как предлагаемая архитектура.

## 1. Функциональные требования

### REQ-F-01 — Подпись чекбокса «Показывать POI» (НОВАЯ ПРАВКА)
- В попапе рельефа (`#terrain-popup`) чекбокс `#poi-visible-cb` должен
  иметь текстовую подпись **«Показывать POI»**.
- Текущее состояние: подпись — «POI» (`src/web/index.html:88`, узел
  `<span>POI</span>` рядом с `#poi-visible-cb`).
- **Жёсткая связь с существующим тестом (важно для исполнителя):** правка
  ломает регресс ET-002 `tests/unit/test_poi_toggle.py:54` —
  `assert "<span>POI</span>" in html`. Эту проверку нужно обновить на
  `<span>Показывать POI</span>` **в том же коммите**, иначе `make test`
  упадёт. (JS-тест `tests/unit/poi_toggle.test.js` текст подписи **не**
  проверяет — он извлекает поведенческий блок по маркерам и подписи не
  касается.)
- Приёмка: видимый текст подписи равен «Показывать POI»; layout попапа не
  ломается (одна строка, без обрезки) на desktop и mobile.

### REQ-F-02 — Чекбокс присутствует в попапе рельефа
- Чекбокс находится внутри `#terrain-popup`, открываемого кнопкой
  `#terrain-toggle` (`toggleTerrainPopup()`).

### REQ-F-03 — Включён по умолчанию
- При первом заходе (ключ `localStorage['poi-visible']` отсутствует)
  чекбокс отмечен, POI видны.

### REQ-F-04 — Снятие чекбокса скрывает POI
- Снятие `#poi-visible-cb` скрывает все маркеры POI: слои `poi-circles`
  и `poi-labels` получают `visibility: none`.

### REQ-F-05 — Установка чекбокса возвращает POI
- Обратная установка возвращает `visibility: visible` тем же слоям.

### REQ-F-06 — Персистентность между сессиями
- Выбор сохраняется в браузере и применяется при следующей загрузке
  страницы (наблюдаемо: после перезагрузки состояние совпадает).

### REQ-F-07 — Устойчивость к смене темы
- Смена темы (`#btn-theme`, пересоздание стиля карты) не сбрасывает
  выбранную видимость POI; чекбокс и слои остаются в согласованном
  состоянии.

## 2. Нефункциональные требования

### REQ-NF-01 — Без новых зависимостей
- Реализация остаётся клиентской, без новых npm/python пакетов
  (ограничение инфраструктуры, ET-002 `07-infra-requirements.md`).

### REQ-NF-02 — Без изменения серверного контракта
- Эндпоинты `/api/tiles/{z}/{x}/{y}.mvt` и слой `poi` в MVT не меняются.
  Управление видимостью — только переключение `visibility` слоёв
  MapLibre на клиенте.

### REQ-NF-03 — Согласованность состояния
- Единый источник истины в рантайме — `layerState.poi`; чекбокс,
  `localStorage` и фактическая видимость слоёв не расходятся.

## 3. Текущая реализация (контекст для верификации)

> Информативно. Изменять требуется только подпись (REQ-F-01).

- `src/web/index.html`
  - стр. ~86–89: `<input type="checkbox" id="poi-visible-cb"
    onchange="onPoiCheckbox()" checked>` и `<span>POI</span>` внутри
    `#terrain-popup`.
- `src/web/app.js`
  - `layerState.poi` (стр. ~406) и `layerGroups.poi = ['poi-circles',
    'poi-labels']` (стр. ~410).
  - `applyPoiVisibility(visible)` — переключает `visibility` слоёв POI и
    синхронизирует `layerState.poi`.
  - `onPoiCheckbox()` — пишет `localStorage['poi-visible']` ('1'/'0') и
    вызывает `applyPoiVisibility()`.
  - `restorePoiState()` — восстановление при загрузке и после смены темы;
    дефолт (ключ отсутствует или '1') — POI видимы.
  - Блок-маркеры `>>> ET-002 POI visibility block <<<`.
- ADR: `docs/work-items/ET-002/06-adr/adr-0001-poi-visibility-client-side.md`.

## 4. Объём изменений для ET-001

1. `src/web/index.html:88`: заменить текст подписи `<span>POI</span>` →
   `<span>Показывать POI</span>` у `#poi-visible-cb`.
2. **Синхронно** обновить ожидание текста в существующем регресс-тесте
   ET-002 `tests/unit/test_poi_toggle.py:54` (`assert "<span>POI</span>"
   in html` → `assert "<span>Показывать POI</span>" in html`). Без этого
   `make test` упадёт. *(Уточнение: текст подписи проверяет именно
   python-тест; JS-тест `poi_toggle.test.js` его не трогает.)*
3. Прогнать регрессию по REQ-F-02…REQ-F-07 (поведение ET-002 не должно
   измениться).

## 5. Зависимости и ограничения

- Не править артефакты ET-002 и заархивированной барьерной задачи.
- Не закрывать ET-001 самостоятельно — закрытие за Owner/CI.
- Если Owner решит, что переименование не нужно — ТЗ аннулируется,
  ET-001 закрывается как дубликат ET-002 (см. `09-analyst-decision-required.md`).
