Andrey Epifancev dc71d4e025 Архив OpenSpec: projects (#61)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 23:04:05 +04:00

10 KiB
Raw Blame History

ADDED Requirements

Requirement: Проект в приложении

Доска и список задач SHALL показывать один проект — текущий. Текущий проект SHALL задаваться параметром project в адресе /app/board и /app/issues; без параметра — последний выбранный в этом браузере (localStorage), если он есть в GET /projects, иначе первый из GET /projects; выбранный проект записывается в адрес без новой записи истории. Проекта из адреса нет в GET /projects — страница SHALL показывать «проект <метка> не найден» и выпадающий список проектов вместо данных. Проектов нет — доска и список SHALL показывать приглашение создать проект («+ Новый проект…»). Переходы «Доска» / «Задачи» SHALL сохранять текущий проект. Карточка задачи (/app/issues/{key}) от проекта не зависит.

Доска SHALL загружать GET /board?project=<текущий>; «Обновить из Jira» — как прежде, POST /refresh {full: true}, обновляет все проекты. Раскладка, дорожки и фильтры доски в localStorage SHALL храниться отдельно для каждого проекта; у проекта AWPCA — на прежних ключах (раскладка, сделанная до проектов, сохраняется). Фильтр спринтов SHALL показываться, только если хотя бы у одной своей задачи снимка (neighbor = false) есть спринт; иначе — «колонки «Спринт» нет — показаны все задачи».

Форма «Новый проект» (пункт «+ Новый проект…» выпадающего списка) SHALL открываться окном поверх страницы: метка, название, номер доски Jira (необязательно; подсказка «scrum или kanban определится сам»). «Создать» — POST /projects с автором viewer; ошибка хаба 409/422 — текст detail рядом с кнопкой, окно остаётся открытым; успех — окно закрывается, текущим становится новый проект, доска подхватывает пакет обновления (refresh автора viewer) и показывает его ход.

Scenario: Первый вход после выкатки

  • WHEN открыт /app/board без project, в localStorage выбора нет, проекты AWPCA и STOCKS_DRRK
  • THEN адрес — /app/board?project=AWPCA, доска — GET /board?project=AWPCA с прежней раскладкой карточек

Scenario: Переключение проекта

  • WHEN на доске AWPCA в выпадающем списке выбран STOCKS_DRRK, затем открыт раздел «Задачи»
  • THEN доска — GET /board?project=STOCKS_DRRK со своей раскладкой; адрес «Задач» — /app/issues?project=STOCKS_DRRK

Scenario: Неизвестный проект в адресе

  • WHEN открыт /app/issues?project=NOPE
  • THEN «проект NOPE не найден» и список проектов; запроса GET /issues нет

Scenario: Создание проекта из формы

  • WHEN в форме введены STOCKS_DRRK, «Запасы ДРРК», доска пусто; нажато «Создать»
  • THEN POST /projects {label: "STOCKS_DRRK", name: "Запасы ДРРК", author: "viewer"}; текущий проект — STOCKS_DRRK; шапка доски показывает «пакет #N выполняется»

Scenario: Метка занята

  • WHEN в форме введена метка awpca, хаб ответил 409
  • THEN окно открыто, рядом с «Создать» — текст ошибки хаба

Scenario: Канбан-проект

  • WHEN текущий проект — STOCKS_DRRK, ни у одной своей задачи снимка нет спринта (у соседа из AWPCA спринт есть)
  • THEN вместо фильтра спринтов — «колонки «Спринт» нет — показаны все задачи»

MODIFIED Requirements

Requirement: Оболочка и адреса

Приложение SHALL открываться под префиксом /app/ и иметь страницы /app/board (доска связей), /app/issues (список задач) и /app/issues/{key} (карточка задачи — окно поверх страницы, требование «Карточка задачи»); /app и /app/ SHALL вести на /app/board, неизвестный путь — на страницу «не найдено» со ссылками на разделы. Верхняя панель SHALL содержать выпадающий список проектов рядом с названием («<метка> — <название>», текущий отмечен, в конце «+ Новый проект…»; требование «Проект в приложении»), переходы «Доска», «Задачи» и действие «Сменить токен». Неожиданная ошибка отрисовки страницы SHALL показываться сообщением с кнопкой «Перезагрузить», не пустым экраном.

Scenario: Переход между разделами

  • WHEN на доске выбран раздел «Задачи»
  • THEN адрес — /app/issues с текущим проектом, показан список задач; «назад» возвращает на доску

Requirement: Список задач

Страница /app/issues SHALL показывать задачи текущего проекта из GET /issues?project=<текущий> таблицей: ключ (открывает карточку задачи окном поверх списка), тема, тип, статус Jira, исполнитель, спринт, срок (planned_end, иначе duedate), эпик (имя эпика, иначе ключ), вид работы, признак «сосед» (относительно проекта); статуса по факту в списке нет. Фильтры SHALL соответствовать параметрам GET /issues (спринт, исполнитель, вид работы, статус Jira, метка, эпик, только соседи, поиск по ключу или теме, скрыть закрытые), храниться в query-строке адреса вместе с project и применяться сервером; варианты выпадающих списков SHALL браться из снимка GET /board?project=<текущий>; значение фильтра из адреса, которого нет среди вариантов, SHALL показываться в списке с пометкой «(нет на доске)». Флажок «скрыть закрытые» SHALL быть включён по умолчанию (в адресе ничего), снятый — closed=1 в адресе; включённый — запрос с hide_closed=1, кроме случая, когда в фильтре «Статус Jira» выбран статус из closed_statuses. Параметр fact_status в адресе игнорируется. Задачи SHALL загружаться порциями по 50 строк; «Показать ещё» SHALL быть доступна, пока последняя порция полная.

Scenario: Фильтр в адресе

  • WHEN выбран спринт «AWPCA_Спринт 2» и исполнитель
  • THEN адрес содержит project=, sprint= и assignee=, таблица — результат GET /issues с этими параметрами; открытие этого адреса в новой вкладке показывает ту же выборку

Scenario: Конец списка

  • WHEN вторая порция вернула 17 задач
  • THEN в таблице 67 задач, «Показать ещё» не показана

Scenario: Фильтр по закрытому спринту

  • WHEN открыт адрес /app/issues?project=AWPCA&sprint=AWPCA_Спринт 0, а в снимке доски такого спринта нет
  • THEN выпадающий список «Спринт» показывает «AWPCA_Спринт 0 (нет на доске)» выбранным, таблица — по этому фильтру

Scenario: Карточка поверх списка

  • WHEN список отфильтрован по спринту, прокручен и догружен «Показать ещё», открыта карточка задачи и окно закрыто
  • THEN адрес списка с тем же фильтром, в таблице те же строки, прокрутка та же

Scenario: Закрытые скрыты по умолчанию

  • WHEN открыт /app/issues, в зеркале задачи в статусах «В работе», «Готово», «Снято»
  • THEN флажок «скрыть закрытые» включён, запрос GET /issues с hide_closed=1, в таблице только «В работе»; после снятия флажка адрес содержит closed=1, в таблице все три

Scenario: Выбран закрытый статус

  • WHEN флажок «скрыть закрытые» включён и в «Статус Jira» выбрано «Готово»
  • THEN запрос GET /issues?status=Готово без hide_closed, в таблице задачи в статусе «Готово»