## Context `main` 78a0d78. Веб-приложение — React 19 + TanStack Query, страницы рисует `shell/Layout.tsx` по `shell/pages.tsx`, разделы — `shell/Sidebar.tsx` (`SECTIONS`), проект — `ProjectGate`, карточка — окно `IssueModal` поверх страницы (`IssueLink`/`useOpenIssue` с `openCardState`). Запросы — `api/queries.ts` (`qk`), перечитывание после «Обновить из Jira» — `shell/RefreshProvider.tsx`. Хаб: `GET /changes` (`since`/`until` — ISO со смещением, иначе 422; `kinds`, `project`, `limit` ≤ 2000, ответ `{since, until, truncated, changes}`), `GET /issues/{key}.changes`. ## Decisions 1. **Модуль `web/src/feed/`**: `events.ts` — чистые функции (границы периода, разбор `kinds` из адреса, текст события, группировка по задаче), `EventList.tsx` — список событий (лента и карточка), `FeedPage.tsx` — страница, `feed.css`. 2. **Период — переключатель из четырёх, а не календарь**: покрывает «за пару часов» и «за сегодня» владельца; «Вчера» и «7 дней» — утренний разбор и неделя. Границы считаются по местному времени браузера, в запрос уходят `toISOString()` (UTC с `Z`) — хаб принимает `Z`, пояс не теряется. 3. **`limit` = 2000** (максимум хаба) — неделя активного проекта помещается; иначе `truncated` с подсказкой. 4. **Подписи прочих полей** — словарь в `events.ts`; незнакомые — имя поля Jira. 5. **Комментарий в ленте — простой текст** (300 символов одной строкой), без вики-разметки: лента — обзор, полный текст — в карточке. 6. **История в карточке — 10 последних с «Показать все»**; блок в основной колонке после комментариев. 7. **Перечитывание**: ключ запроса `["changes", {project, period, kinds}]`, границы периода считаются в момент запроса (окно всегда «до сейчас»); `RefreshProvider` после пакета инвалидирует `["changes"]`; при возврате на вкладку — `refetchOnWindowFocus: true` у `useChanges` (в клиенте приложения по умолчанию оно выключено). Подзаголовок берёт окно из ответа хаба. ## Decisions made without discussion 1. 2026-10-22 — **все решения выше (1–7) — мои**: владелец сказал «начинай» без обсуждения интерфейса. Цена ошибки: переделка вёрстки страницы; бэкенд не затронут. 2. 2026-10-22 — **R-1: смена проекта на ленте сохраняет `period` и `kinds`** (`Layout.select`). Обоснование: они от проекта не зависят; фильтры доски и списка по-прежнему сбрасываются. Цена ошибки: нет. 3. 2026-10-22 — **R-2: снятые все флажки пишутся в адрес как `kinds=none`.** Обоснование: пустое значение означало бы набор по умолчанию. Цена ошибки: «none» виден в адресе. 4. 2026-10-22 — **R-3: в e2e флажок — щелчок и ожидание `toBeChecked`, а не `locator.check`.** Обоснование: флажок управляемый, состояние приходит из адреса после навигации роутера. Цена ошибки: нет. 5. 2026-10-22 — **R-4 (по C-1/C-2 финального ревью): границы периода — в момент запроса, ключ кэша без них; `refetchOnWindowFocus: true` у ленты.** Обоснование: замороженная при открытии граница «до» не давала перечитыванию показать новые события, а фокус вкладки в приложении не перечитывал ничего. Цена ошибки: лишний запрос `/changes` при возврате на вкладку (не чаще раза в 30 с — `staleTime`). 6. 2026-10-22 — **R-5 (follow-up M-5 финального ревью): адрес без единого известного вида — набор по умолчанию, а не пустой; пустой набор — только явное `kinds=none`.** Обоснование: ссылка с устаревшим видом не должна открывать пустую ленту. Цена ошибки: нет.