129 lines
16 KiB
Markdown
129 lines
16 KiB
Markdown
## 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
|
||
|
||
1. **Фильтры — на клиенте, чистой моделью.** Новый модуль `agile/filters.ts`: тип состояния страницы
|
||
(`q`, `assignee`, `epic`, `hideDone`, `collapsed`, `hiddenColumns`, `epicsPanel`), функция «видна ли задача»
|
||
(поиск по `key` и `summary` без учёта регистра; `assignee`: `""` — все, `"-"` — без исполнителя; `epic`: `""` — все,
|
||
`"-"` — без эпика, иначе `epic_key === epic`; `hideDone`), списки вариантов исполнителей и эпиков. Страницы и
|
||
компоненты только рисуют. Модель покрыта unit-тестами, страницы — тестами поведения.
|
||
|
||
2. **Запоминание — один ключ `sdlc-hub-agile`.** JSON `{ "<метка>": { "backlog": {...}, "sprint": {...},
|
||
"kanban": {...} } }`; хранится всё, кроме `q` и выбора спринтов. Чтение и запись — в `try/catch` (закрытое
|
||
хранилище, мусор, чужая форма — значения по умолчанию), как `sidebarPref`/`legendPref`. Миграция `jira-hub-` не нужна
|
||
— ключ новый. Свёрнутые секции — по id спринта и `"backlog"`; id закрытых/удалённых спринтов при чтении не мешают
|
||
(просто не совпадают). Скрытые колонки — по имени колонки (`"Без колонки"` — тоже имя).
|
||
|
||
3. **Панель фильтров** — общий компонент `AgileToolbar` для трёх страниц, набор элементов — пропсами. Используются
|
||
готовые `SearchInput`, `Select`, `Checkbox`/`Button aria-pressed`, `Dropdown`/`Menu` из `web/src/ui`; новые элементы
|
||
UI-кита не вводятся, кроме значков (п. 7). Устаревшее значение исполнителя/эпика остаётся в списке (как
|
||
`withCurrent` у списка задач), чтобы пустой результат объяснялся видимым фильтром.
|
||
|
||
4. **Свёртка секций «Бэклога».** Заголовок секции — `<button aria-expanded aria-controls>` с шевроном
|
||
(`IconChevronDown`/`Up`) и прежним содержимым заголовка; свёрнутая секция показывает только заголовок с итогами.
|
||
«Прошлые спринты» остаются `<details>` (не запоминаются — как сейчас).
|
||
|
||
5. **Эпики на «Бэклоге».** Эпик — задача, у которой `TypeIcon` определяет вид «эпик» (одна функция `typeKind` для
|
||
значка и фильтра). Строки эпиков убираются из всех секций «Бэклога» (и из счёта «N задач» секции «Бэклог», который
|
||
считается на клиенте). Панель — колонка слева шириной ~240 px в сетке страницы; при контейнере `page` уже 900 px —
|
||
`Select «Эпик»` в панели фильтров. Число у эпика — задачи с этим `epic_key` в активных, будущих спринтах и «Бэклоге»
|
||
без учёта остальных фильтров. На «Спринте» и «Kanban» эпики не трогаются (в issue речь только о бэклоге).
|
||
|
||
6. **Итоги секций — факты спринта.** Заголовок спринта показывает серверные `count`/`points`/`unestimated`; фильтры их
|
||
не меняют, добавляется «показано K», когда видно меньше задач секции. Так ретро-цифры спринта не «плавают» от фильтра.
|
||
Числа в заголовках колонок доски — по видимым карточкам.
|
||
|
||
7. **Значки типов по образцу 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`.
|
||
|
||
8. **Выбор спринтов на «Спринте».** `Dropdown` с отметками (активные, затем будущие по `start_date`, без даты — в
|
||
конце), адрес `?sprint=<id>[,<id>…]` с `replace` (без записи истории). Задачи доски — объединение задач выбранных
|
||
спринтов без повторов по ключу, порядок — по `rank` (строка LexoRank сравнивается как строка; `null` — в конце, затем
|
||
по ключу). Заголовков столько, сколько выбрано спринтов, компактной строкой каждый; «осталось N дн.» — только у
|
||
активного. Прежний одиночный `?sprint=<id>` остаётся рабочим адресом.
|
||
|
||
9. **Колонки одной высоты и прокрутка (пп. 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`). Тогда полоса горизонтальной прокрутки всегда у нижнего края окна, колонки одной высоты. Если
|
||
воспроизведение покажет другую причину — чинится причина, требование спеки то же.
|
||
|
||
10. **Скрытие колонок** — меню «Колонки» с отметками на «Спринте» и «Kanban»; последнюю видимую снять нельзя; число
|
||
скрытых — `Badge` на кнопке. Скрытие — только вид, `columnsOf` не меняется, фильтруется результат.
|
||
|
||
11. **Попутные маркеры hub#111.** M-6 — `fmtSp` округляет до двух знаков и убирает хвостовые нули (веб-сторона;
|
||
MCP `:g` не трогаем, расхождение для дробных до сотых исчезает). T10.3 — `h3` в заголовках колонок. T9.4 — тесты
|
||
загрузки и ошибки `AgileGate` и пункта «Kanban» kanban-проекта в меню. T12.2–T12.4 — e2e доски: фиксированный
|
||
`jira_updated` в сиде, строгие локаторы по роли и тексту, без зависимости от порядка DOM.
|
||
|
||
12. **Тестовые данные.** Сид 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): значок задачи без типа подписан «Тип не указан» (сейчас — «Задача»), вид — нейтральный.
|
||
Цена ошибки — вернуть прежнюю подпись.
|