## Context Страницы /candidates и /selected (FastAPI + Jinja2 + Bootstrap, шаблоны web/templates/candidates.html и selected.html) имеют общий паттерн: слева список постов с чекбоксами массового выбора (form bulk-form, input name=ids), справа детали открытого поста. Открытие поста — обычная GET-навигация (?selected=N), которая перезагружает страницу: сервер отдаёт checked только для текущего поста, остальные отметки теряются. Серверный код (web/app.py) менять не требуется — фикс чистого frontend. ## Goals / Non-Goals **Goals:** - Сохранять отметки чекбоксов между перезагрузками страницы (навигация по постам) на /candidates и /selected. - Восстанавливать отметки при загрузке; считать sel-count по восстановленному состоянию. - Сбрасывать состояние после успешной отправки bulk-формы. **Non-Goals:** - Не менять серверный рендеринг, API, БД. - Не делать мульти-выбор «как в трекере» со сложным состоянием на сервере — только сохранение существующих чекбоксов. ## Decisions 1. **Хранилище — sessionStorage браузера (не localStorage, не сервер).** - Отметки нужны только в рамках текущей вкладки/сессии просмотра, серверное состояние не требуется (список кандидатов меняется от краула, ids в sessionStorage «протухнут» — это ок, чекбокс просто не найдётся). - localStorage переживал бы вкладки и захламлялся бы; серверное состояние = лишний API + потеря при «назад». - Ключ: `vesti_bulk_` где page ∈ {candidates, selected}. Изоляция страниц (требование спеки) — автоматически через разные ключи. 2. **JS-инициализация в конце body (block scripts), как существующий скрипт подсчёта.** - После загрузки DOM: прочитать sessionStorage, проставить checked всем чекбоксам ids из сохранённого Set, затем вызвать upd() для счётчика. - Перехват change на чекбоксах: перезапись Set в sessionStorage (add/delete по value). - Перехват submit bulk-form: очистить sessionStorage (отметки отправлены — состояние больше не нужно). 3. **Чекбокс открытого поста** продолжает получать `checked` от сервера (существующая логика `{% if selected and selected.id == p.id %}checked{% endif %}`) — сохраняется текущее поведение; поверх него восстанавливаются остальные. ## Risks / Trade-offs - [Отметки «протухают» при повторном использовании страницы позже] → ок: sessionStorage живёт до закрытия вкладки; ids не найденных постов игнорируются. - [Дублирование кода в двух шаблонах] → приёмлемо: шаблоны уже дублируют bulk-логику; выносить общий JS в static-файл можно позже отдельным change-ом. - [Отключённый JS] → до фикса поведение было «отметки сбрасываются при навигации»; после фикса без JS — то же самое, регрессии нет.