## MODIFIED Requirements ### Requirement: Оболочка и адреса Приложение SHALL открываться под префиксом `/app/` и иметь страницы `/app/board` (доска связей), `/app/issues` (список задач), `/app/feed` (лента изменений, требование «Лента изменений») и `/app/issues/{key}` (карточка задачи — окно поверх страницы, требование «Карточка задачи»); `/app` и `/app/` SHALL вести на `/app/board`, неизвестный путь — на страницу «не найдено» со ссылками на разделы. Боковая панель SHALL быть закреплена у левого края окна на всю его высоту и MUST NOT прокручиваться вместе со страницей; страница занимает остальную ширину. Сверху вниз панель SHALL содержать: название «Хаб Jira» и кнопку «Свернуть панель»; выпадающий список проектов («<метка> — <название>», текущий отмечен, в конце «+ Новый проект…»; требование «Проект в приложении»); разделы «Доска связей», «Задачи» и «Лента» — вертикальным списком ссылок со значками (текущий отмечен `aria-current="page"`); внизу — блок данных Jira с действием «Обновить из Jira» (требование «Обновление из Jira»), переключатель темы (требование «Тема») и меню с действием «Сменить токен». Свёрнутая панель SHALL быть узкой полосой с теми же действиями значками: «Развернуть панель», метка текущего проекта, разделы, «Обновить из Jira» с точкой состояния агента, тема, меню; названия — в подсказках и `aria-label`. Свёртка SHALL храниться в `localStorage` под ключом `jira-hub-sidebar` (`collapsed`; без записи — развёрнута). На экранах уже 640 px панели в потоке нет: сверху SHALL быть закреплена строка с кнопкой «Меню», названием и кнопкой «Обновить из Jira»; «Меню» открывает развёрнутую панель поверх страницы, панель закрывается выбором раздела, клавишей Escape или щелчком мимо неё. Горизонтальной прокрутки страницы на любой ширине нет. Неожиданная ошибка отрисовки страницы SHALL показываться сообщением с кнопкой «Перезагрузить», не пустым экраном. #### Scenario: Переход между разделами - **WHEN** на доске в боковой панели выбран раздел «Задачи» - **THEN** адрес — `/app/issues` с текущим проектом, показан список задач; «назад» возвращает на доску #### Scenario: Раздел «Лента» - **WHEN** на доске в боковой панели выбран раздел «Лента» - **THEN** адрес — `/app/feed` с текущим проектом, показана лента изменений за сегодня; раздел отмечен в панели #### Scenario: Сменить токен - **WHEN** в меню боковой панели выбрано «Сменить токен» - **THEN** токен очищен, показан экран входа #### Scenario: Панель на месте при прокрутке - **WHEN** доска прокручена до самого низа - **THEN** боковая панель видна целиком на прежнем месте: разделы и «Обновить из Jira» доступны без прокрутки вверх #### Scenario: Свёрнутая панель - **WHEN** нажата «Свернуть панель», страница перезагружена - **THEN** панель свёрнута в полосу значков, доска шире; значок «Задачи» открывает список задач; «Развернуть панель» возвращает полную панель #### Scenario: Узкий экран - **WHEN** ширина окна 390 px, нажата «Меню», в панели выбран раздел «Задачи» - **THEN** панель открылась поверх страницы, после выбора закрыта, показан список задач; горизонтальной прокрутки нет ## ADDED Requirements ### Requirement: Лента изменений Страница `/app/feed?project=<метка>` SHALL показывать события журнала изменений своих задач текущего проекта за период (`GET /changes` с `project`, `since`, `until`, `kinds`). Период SHALL выбираться переключателем «2 часа» / «Сегодня» / «Вчера» / «7 дней» (по умолчанию «Сегодня»; границы — по местному времени браузера: «Сегодня» — с начала текущих суток до сейчас, «Вчера» — с начала прошлых суток до начала текущих) и храниться в адресе (`period=2h|today|yesterday|7d`; «Сегодня» в адрес не пишется). Виды событий SHALL выбираться флажками «Статусы», «Описание», «Сроки», «Комментарии», «Прочие поля» (по умолчанию все, кроме «Прочие поля») и храниться в адресе (`kinds=` через запятую; набор по умолчанию в адрес не пишется; в адресе нет ни одного известного вида — набор по умолчанию); снятые все флажки — сообщение «выберите хотя бы один вид», запроса нет. События SHALL быть сгруппированы по задаче; задачи — по времени последнего события, новые сверху. У группы: ключ — ссылка на карточку задачи (окно поверх ленты, требование «Карточка задачи»), тема и текущий статус; под ней события по времени, новые сверху, каждое — время (`ЧЧ:ММ`, с датой `ДД.ММ`, если событие не в текущих сутках), автор и текст: статус — «статус «было» → «стало»»; описание — «описание изменено»; срок, плановое начало и окончание — «срок ДД.ММ → ДД.ММ» (дата по значению `from_value`/`to_value`, иначе строка журнала; пустое — «—»); комментарий — «комментарий:» и первые 300 символов текста одной строкой с «…»; прочие поля — «<название поля>: «было» → «стало»» (значения до 80 символов с «…»), где название — подпись из словаря приложения (исполнитель, спринт, метки, приоритет, тема, эпик, связь, вложение, резолюция), иначе имя поля Jira. Подзаголовок страницы — число событий и границы периода. Событий нет — сообщение «за период изменений нет»; `truncated` — сообщение «показаны последние N событий — выберите период короче». Ошибка хаба — сообщение с кнопкой «Повторить». Ленту SHALL перечитывать завершение «Обновить из Jira» (вместе со списками задач) и возврат на вкладку браузера. #### Scenario: Что закрылось за два часа - **WHEN** открыта лента проекта AWPCA, выбран период «2 часа», сняты все флажки, кроме «Статусы» - **THEN** адрес — `/app/feed?project=AWPCA&period=2h&kinds=status`; запрос `GET /changes?project=AWPCA&since=<сейчас − 2 ч>&kinds=status`; задачи сгруппированы, у каждой — события «ЧЧ:ММ автор: статус «В работе» → «Готово»» #### Scenario: Карточка из ленты - **WHEN** в ленте нажат ключ AURORA-9002 - **THEN** поверх ленты открыто окно карточки AURORA-9002; закрытие окна возвращает ленту с тем же периодом #### Scenario: Пустой период - **WHEN** за выбранный период событий нет - **THEN** показано «за период изменений нет» #### Scenario: Вчера - **WHEN** выбран период «Вчера», сейчас 22.10 14:05 местного времени - **THEN** запрос с `since` = 21.10 00:00 и `until` = 22.10 00:00 местного времени ### Requirement: История в карточке задачи Карточка задачи SHALL показывать в основной колонке после комментариев блок «История (N)» — события `changes` из `GET /issues/{key}` (все виды, новые сверху) в том же виде, что в ленте, всегда с датой. Видны 10 последних событий, остальные — по кнопке «Показать все (N)»; без событий — подсказка «изменений нет»; ответ хаба без поля `changes` — блока нет. #### Scenario: Карточка с историей - **WHEN** открыта карточка задачи с 12 событиями журнала - **THEN** блок «История (12)» показывает 10 последних событий и кнопку «Показать все (12)»; после нажатия — все 12