23 KiB
Context
После выкатки #108 (25.10.2026) владелец посмотрел «Бэклог», «Спринт» и «Kanban» на живой доске AWPCA (4216, три спринта) и записал 10 замечаний в sdlc-hub#112. Владелец попросил не проводить brainstorming-вопросы и писать дизайн по тексту issue, поэтому всё, что в issue не сказано прямо, — решения агента (раздел «Decisions made without discussion»).
Текущее состояние (web/src/modules/jira/agile/): BacklogPage рисует секции Panel без свёртки, эпики идут строками
наравне с задачами; SprintPage показывает один активный спринт, переключатель Segmented — только между активными;
BoardColumns — flex-ряд с align-items:flex-start и overflow-x:auto; TypeIcon знает три вида (эпик —
IconBoard, ошибка — IconCritical (молния), прочее — IconCheck). Фильтров нет. Все нужные данные уже приходят в
GET /agile (AgileIssue: issue_type, assignee, epic_key, done, rank, status) — сервер не меняется.
Goals / Non-Goals
Цели — 10 пунктов #112 и попутно веб-маркеры из hub#111 (M-6, T10.3, T9.4, T12.2–T12.4). Не цели — правки Jira из веба, изменения API/схемы/агента/MCP, настройки доски AWPCA в Jira, серверные пункты hub#111.
Decisions
-
Фильтры — на клиенте, чистой моделью. Новый модуль
agile/filters.ts: тип состояния страницы (q,assignee,epic,hideDone,collapsed,hiddenColumns,epicsPanel), функция «видна ли задача» (поиск поkeyиsummaryбез учёта регистра;assignee:""— все,"-"— без исполнителя;epic:""— все,"-"— без эпика, иначеepic_key === epic;hideDone), списки вариантов исполнителей и эпиков. Страницы и компоненты только рисуют. Модель покрыта unit-тестами, страницы — тестами поведения. -
Запоминание — один ключ
sdlc-hub-agile. JSON{ "<метка>": { "backlog": {...}, "sprint": {...}, "kanban": {...} } }; хранится всё, кромеqи выбора спринтов. Чтение и запись — вtry/catch(закрытое хранилище, мусор, чужая форма — значения по умолчанию), какsidebarPref/legendPref. Миграцияjira-hub-не нужна — ключ новый. Свёрнутые секции — по id спринта и"backlog"; id закрытых/удалённых спринтов при чтении не мешают (просто не совпадают). Скрытые колонки — по имени колонки ("Без колонки"— тоже имя). -
Панель фильтров — общий компонент
AgileToolbarдля трёх страниц, набор элементов — пропсами. Используются готовыеSearchInput,Select,Checkbox/Button aria-pressed,Dropdown/Menuизweb/src/ui; новые элементы UI-кита не вводятся, кроме значков (п. 7). Устаревшее значение исполнителя/эпика остаётся в списке (какwithCurrentу списка задач), чтобы пустой результат объяснялся видимым фильтром. -
Свёртка секций «Бэклога». Заголовок секции —
<button aria-expanded aria-controls>с шевроном (IconChevronDown/Up) и прежним содержимым заголовка; свёрнутая секция показывает только заголовок с итогами. «Прошлые спринты» остаются<details>(не запоминаются — как сейчас). -
Эпики на «Бэклоге». Эпик — задача, у которой
TypeIconопределяет вид «эпик» (одна функцияtypeKindдля значка и фильтра). Строки эпиков убираются из всех секций «Бэклога» (и из счёта «N задач» секции «Бэклог», который считается на клиенте). Панель — колонка слева шириной ~240 px в сетке страницы; при контейнереpageуже 900 px —Select «Эпик»в панели фильтров. Число у эпика — задачи с этимepic_keyв активных, будущих спринтах и «Бэклоге» без учёта остальных фильтров. На «Спринте» и «Kanban» эпики не трогаются (в issue речь только о бэклоге). -
Итоги секций — факты спринта. Заголовок спринта показывает серверные
count/points/unestimated; фильтры их не меняют, добавляется «показано K», когда видно меньше задач секции. Так ретро-цифры спринта не «плавают» от фильтра. Числа в заголовках колонок доски — по видимым карточкам. -
Значки типов по образцу Jira.
typeKind(issue_type)→epic | story | task | bug | subtask | other; значок — скруглённый квадрат 16 px цвета вида с белым символом (эпик — молния, история — закладка, задача — галочка, ошибка — круг, подзадача — два квадрата, прочее — нейтральный серый квадрат с точкой). Новые символы — вweb/src/ui/icons.tsxтем жеmake(...); цвета — токенами дизайн-системы (эпик —--k-ui, история —--color-status-success, задача —--color-action-primary, ошибка —--color-status-error, подзадача и прочее — нейтральные), контраст белого символа проверить в обеих темах. При завершении — перенести значки в kit скиллаaura-design. -
Выбор спринтов на «Спринте».
Dropdownс отметками (активные, затем будущие поstart_date, без даты — в конце), адрес?sprint=<id>[,<id>…]сreplace(без записи истории). Задачи доски — объединение задач выбранных спринтов без повторов по ключу, порядок — поrank(строка LexoRank сравнивается как строка;null— в конце, затем по ключу). Заголовков столько, сколько выбрано спринтов, компактной строкой каждый; «осталось N дн.» — только у активного. Прежний одиночный?sprint=<id>остаётся рабочим адресом. -
Колонки одной высоты и прокрутка (пп. 8 и 10). Гипотеза по багу (подтвердить воспроизведением в начале задачи, superpowers:systematic-debugging): горизонтальная полоса
.agile-columnsесть, но лежит под самой длинной колонкой, далеко ниже окна (и скрыта macOS до прокрутки), поэтому правые колонки на 2560 px выглядят обрезанными. Исправление: страницы доски растягиваются на высоту основной области оболочки (flex:1; min-height:0по цепочке, доскаmin-height:360px),.agile-columns—align-items:stretchи своя высота, у колонки прокручивается список (overflow-y:auto). Тогда полоса горизонтальной прокрутки всегда у нижнего края окна, колонки одной высоты. Если воспроизведение покажет другую причину — чинится причина, требование спеки то же. -
Скрытие колонок — меню «Колонки» с отметками на «Спринте» и «Kanban»; последнюю видимую снять нельзя; число скрытых —
Badgeна кнопке. Скрытие — только вид,columnsOfне меняется, фильтруется результат. -
Попутные маркеры hub#111. M-6 —
fmtSpокругляет до двух знаков и убирает хвостовые нули (веб-сторона; MCP:gне трогаем, расхождение для дробных до сотых исчезает). T10.3 —h3в заголовках колонок. T9.4 — тесты загрузки и ошибкиAgileGateи пункта «Kanban» kanban-проекта в меню. T12.2–T12.4 — e2e доски: фиксированныйjira_updatedв сиде, строгие локаторы по роли и тексту, без зависимости от порядка DOM. -
Тестовые данные. Сид e2e (
web/scripts/test-hub.shи фикстуры агента) дополняется так, чтобы были: эпик с задачами в спринте и бэклоге, задачи без эпика и без исполнителя, будущий спринт с задачами, доска с числом колонок и карточек, достаточным для широкой доски из сценария «Широкая доска».
Risks / Trade-offs
- Высота доски от оболочки. Растяжение по высоте зависит от цепочки flex в
shell.css/Layout.tsx; нельзя сломать прокрутку других страниц — e2e «страница без горизонтальной прокрутки» и сценарии оболочки остаются зелёными. - Объединение спринтов. Задача может числиться и в активном, и в будущем спринте (перенос) — без дедупликации карточка задвоится; дедупликация по ключу — в п. 8.
- Распознавание эпика по имени типа. Тип зависит от локали Jira; список имён — один на значок и фильтр, расширяется в одном месте.
Decisions made without discussion
Все — 25.10.2026, владелец попросил писать дизайн по issue без вопросов. Нумерация рулингов R-n — с R-1 в пределах этой фичи.
- R-1 (design #2): фильтры и свёртка запоминаются отдельно по странице (
backlog/sprint/kanban) и проекту, поиск и выбор спринтов — не запоминаются. Обоснование: как в Jira — поиск разовый, выбор спринтов живёт в адресе. Цена ошибки — сделать исполнителя общим для страниц или запоминать поиск: правка одного модуляfilters.ts. - R-2 (design #5): эпики убираются строками только на «Бэклоге»; на «Спринте» и «Kanban» остаются карточками. Обоснование: в issue речь о бэклоге. Цена ошибки — тот же фильтр на доске, одна строка.
- R-3 (design #5): фильтр по эпику действует и на прошлые спринты; число у эпика — без учёта других фильтров и без прошлых спринтов. Цена ошибки — правка подсчёта в модели.
- R-4 (design #6): итоги секций спринта не зависят от фильтров, добавляется «показано K»; числа колонок доски — по видимым. Цена ошибки — пересчитывать итоги на клиенте.
- R-5 (spec): «Скрыть выполненные» не действует на прошлые спринты и на «Kanban» (у kanban последняя колонка — уже «за 14 дней»). Цена ошибки — включить флагом.
- R-6 (design #8): выбор спринтов — несколько сразу (по умолчанию все активные), в адресе. Формулировка issue («выбор отображаемых спринтов: и активные, и будущие») допускает и одиночный выбор; множественный — надмножество. Цена ошибки — заменить список отметок одиночным выбором.
- R-7 (spec): поиск и исполнитель — на всех трёх страницах, включая «Kanban», хотя в issue названы «Бэклог» и доска спринта: общий компонент, единообразие. Цена ошибки — скрыть два поля на «Kanban».
- R-8 (design #7): набор видов значков и их цвета (Jira: эпик фиолетовый с молнией, история зелёная с закладкой, задача синяя с галочкой, ошибка красная с кругом, подзадача). Цена ошибки — перерисовать значки.
- R-9 (design #9): причина бага прокрутки — гипотеза, подлежит проверке воспроизведением; починка — через растяжение доски на высоту окна, совмещённую с п. 8. Цена ошибки — другая починка того же требования.
- R-10 (proposal): из hub#111 взяты только веб-маркеры M-6 (веб-сторона), T10.3, T9.4, T12.2–T12.4; hub#111 после merge остаётся открытой с комментарием о закрытых маркерах. Цена ошибки — взять/отложить другие пункты.
- R-11 (spec): узкий экран — панель эпиков превращается в выбор при контейнере уже 900 px. Цена ошибки — подобрать порог.
- R-12 (plan, Task 7): на страницах доски («Спринт», «Kanban») страница не ограничена
max-width: 1440pxу.page— на 2560 px колонки используют ширину окна (комментарий вagile.cssуже называл «Спринт» страницей во всю ширину, а ограничение оставалось). Обоснование: замечание владельца о 2560 px. Цена ошибки — вернуть ограничение одной строкой. - R-13 (plan, Task 1): значок задачи без типа подписан «Тип не указан» (сейчас — «Задача»), вид — нейтральный. Цена ошибки — вернуть прежнюю подпись.
- R-14 (controller, 25.10.2026, design #34): сид
WIDE_E2E(Task 8 Step 1) делается в Task 7 Step 1 — как воспроизводящая широкая доска для баги прокрутки; Task 8 Step 1 остаётся проверкой прочих e2e и T12.2. Обоснование: без сида воспроизведение невозможно, порядок плана противоречив. Цена ошибки — сид приезжает на коммит раньше. - R-15 (controller, 25.10.2026, design #35): рулинги контроллера нумеруются с R-14 (R-13 занят дизайном; в плане T9 написано «R-13…»). Цена ошибки — нулевая.
- R-16 (controller, 25.10.2026, design #36, из ревью T4.2/T4.3/T4.4): (а) у прошлого спринта при активных фильтрах
в сводке добавляется « · показано K» (спека описывает «показано K» только для активных и будущих; строка
сценария «Прошлый спринт» без фильтров не меняется); (б) список исполнителей строится по всем задачам-не-эпикам
страницы, включая прошлые спринты (исполнитель фильтрует и их); (в) «N задач» секции спринта — серверное
count(включает эпики, R-4), а строки и «показано K» считаются по задачам-не-эпикам, поэтому спринт с эпиком может показать «N задач» больше числа строк. Цена ошибки — правка двух выражений в BacklogPage.tsx. - R-17 (controller, 25.10.2026, design #37, Task 7 Step 1): гипотеза R-9/R-12 о причине бага прокрутки не подтвердилась
воспроизведением (systematic-debugging).
max-width:1440pxу.pageстраниц доски уже снят (.page--board), доска на 2560 px шире 1440 px. Настоящая причина: у.agile-columnsне было ограничения по высоте — высота доски равна самой длинной колонке (3326 px), горизонтальная полоса прокрутки лежала на y=3616 при окне 1300 px, колонки были разной высоты (align-items:flex-start), список колонки не прокручивался. Починка:.agile--wideвысотой окна, колонкиstretch, прокрутка у.agile-col__list, горизонтальная — у.agile-columns. R-12 в части снятияmax-widthтеряет силу (править нечего). Цена ошибки — нулевая: снятие ограничения не делалось. - R-18 (controller, 25.10.2026, design #38, из отчёта Task 7): раскрытый «Бэклог (N)» на «Kanban» ограничен по высоте (40dvh) с прокруткой; меню «Колонки» включает «Без колонки», если такая есть. Цена ошибки — правка CSS/списка меню.
- R-19 (controller, 25.10.2026, design #39, из I-1 финального ревью): цвета значков типов — эпик
--k-ui, история--color-status-success, задача--k-dev, подзадача--k-analytics, ошибка--color-status-error, прочее--color-text-secondary; символ —--color-text-on-primary(в тёмной теме тёмный, контраст ≥ 3:1 во всех парах, рассчитан по tokens.css). Прежний выбор плана (задача на--color-action-primary) давал один зелёный с историей, что противоречило «у каждого вида свои цвет и символ»; фраза спеки «белый символ» заменена на «символ цвета--color-text-on-primary». Цена ошибки — пересадить два токена в agile.css. - R-20 (controller, 25.10.2026, design #40, из I-3): на окне уже 640 px минимальная высота доски 240 px (а не 360): при 360 px полоса прокрутки доски уходит ниже окна (810 и 838 против 800 на 390×800, замеры Task 8 и волны финального ревью), а требование «полоса прокрутки в пределах окна» важнее. Спека поправлена (240 px на узком окне). Цена ошибки — вернуть 360 px и принять полосу ниже окна.
- R-21 (controller, 25.10.2026, design #41, из I-3): (а) последняя отмеченная позиция в выборе спринтов недоступна (нельзя снять); (б) скрытая колонка, которой нет на доске, в меню «Колонки» не показывается и на кнопке не считается, а если скрыты все колонки — не скрыто ничего (доска не пустеет молча; список имён меню строится по нефильтрованным задачам); (в) подпись поля поиска для экранного диктора — «Поиск по ключу или теме», видимая — «Ключ или тема»; (г) подпись «Исполнитель» — inline слева от выбора (подпись сверху сдвигала выбор относительно поиска). Review Focus 2 плана («значение остаётся видимым и снимаемым») для колонок трактуется так: значение, которого нет в данных, не нужно показывать, потому что оно ни на что не влияет. Цена ошибки — показывать «призрачные» колонки в меню.