77 lines
7.0 KiB
Markdown
77 lines
7.0 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Журнал синхронизаций и статус агента
|
||
Таблица `sync_run` SHALL хранить каждую загрузку состояния: `started_at`, `finished_at`, `kind` (`keys | jql`), `query`,
|
||
`issues_count`, `links_count`, `jira_calls`, `rate_limited`, `command_id`. При повторной выдаче команды `refresh` хаб
|
||
SHALL обнулить `issues_count` и `links_count` её `sync_run` (`started_at` не меняется); при переводе `refresh` в `failed`
|
||
по пределу выдач — проставить `finished_at`. Таблица `agent_status` SHALL хранить по строке на агента (ключ `agent` —
|
||
имя модуля, см. `modules`, «Агенты модулей»): `last_seen_at`, `agent_version`, `settings_version`, `current_command_id`,
|
||
`last_call_at` (время последнего обращения агента к внешней системе; от jira-agent приходит полем `last_jira_call_at`).
|
||
Через API и MCP статус агента SHALL отдаваться с признаком `online` (истина, если `last_seen_at` моложе 5 минут) и
|
||
списком `redelivered` — команд его модуля в `claimed`, выданных больше одного раза (`id`, `type`, `claimed_at`,
|
||
`deliveries`).
|
||
|
||
#### Scenario: Агент давно не выходил на связь
|
||
- **WHEN** `last_seen_at` агента `jira` старше 5 минут
|
||
- **THEN** `agent_status` через API и MCP отдаётся с `online = false`
|
||
|
||
#### Scenario: Довыдача refresh не удваивает счётчики
|
||
- **WHEN** `refresh` загрузил 150 задач, отчёт потерян, команда выдана снова и загрузила те же 150
|
||
- **THEN** у её `sync_run` `issues_count = 150`
|
||
|
||
#### Scenario: refresh сдался по пределу выдач
|
||
- **WHEN** `refresh` переведён в `failed` «агент не отчитался после 3 выдач»
|
||
- **THEN** у его `sync_run` проставлен `finished_at`
|
||
|
||
#### Scenario: Статусы агентов раздельно
|
||
- **WHEN** агент `jira` выходил на связь минуту назад, агент `wiki` — никогда
|
||
- **THEN** `GET /agents` отдаёт `jira` с `online = true` и `wiki` с `online = false`, `last_seen_at = null`
|
||
|
||
### Requirement: Проекты
|
||
Таблица `project` SHALL хранить проекты моста — подмножества задач Jira-проекта `project_key`, выделенные меткой:
|
||
`label` (PK, метка Jira), `name`, `created_at`. Метка SHALL быть непустой строкой до 100 символов без пробельных и
|
||
управляющих символов (категория Unicode `Cc`), запятых, кавычек, скобок и обратной косой черты; две метки, совпадающие
|
||
без учёта регистра, MUST NOT существовать одновременно. Название SHALL быть непустым после обрезки пробелов, до 100
|
||
символов. Метку и название после создания хаб не меняет (переименования и удаления нет).
|
||
|
||
Доска проекта SHALL храниться в таблице модуля jira `jira_project`: `label` (PK, ссылка на проект), `board_id` (номер
|
||
доски Jira или `NULL`), `board_type` (`scrum` | `kanban` | `NULL` — тип ещё не известен). `board_id` — целое больше нуля
|
||
или `NULL`, после создания не меняется; `board_type` SHALL записываться только по результату `refresh` от агента (см.
|
||
`agent`). Миграция v7 SHALL перенести `board_id` и `board_type` всех проектов из `project` в `jira_project`. Базовая JQL
|
||
SHALL вычисляться из проектов: `project = <project_key> AND labels in ("<метка>", …)` — каждая метка в двойных
|
||
кавычках, метки по created_at, затем label, через `, `; без проектов базовой JQL нет (`null`).
|
||
|
||
Для проекта P задачи зеркала делятся на *свои* — с меткой P в `labels` (точное совпадение) — и *соседей* — задачи без
|
||
метки P, связанные со своей связью `issue_link` в любую сторону, и эпики своих (`epic_key` своей задачи), если они есть в
|
||
зеркале. Признак `neighbor` в выдаче в разрезе проекта SHALL считаться относительно P: `false` у своих, `true` у соседей.
|
||
|
||
#### Scenario: Базовая JQL из двух проектов
|
||
- **WHEN** заведены проекты `AWPCA` (раньше) и `STOCKS_DRRK`, `project_key = AURORA`
|
||
- **THEN** базовая JQL — `project = AURORA AND labels in ("AWPCA", "STOCKS_DRRK")`
|
||
|
||
#### Scenario: Свои и соседи
|
||
- **WHEN** у AURORA-1 метка `STOCKS_DRRK` и эпик AURORA-9 (метка `AWPCA`), связь AURORA-1 → AURORA-2 (метка `AWPCA`),
|
||
у AURORA-3 метка `AWPCA` без связей с проектом `STOCKS_DRRK`
|
||
- **THEN** в разрезе `STOCKS_DRRK` свои — AURORA-1, соседи — AURORA-2 и AURORA-9; AURORA-3 в разрез не входит
|
||
|
||
#### Scenario: Метка с пробелом
|
||
- **WHEN** создаётся проект с меткой `STOCKS DRRK`
|
||
- **THEN** отказ с указанием поля `label`, проекта нет
|
||
|
||
#### Scenario: Метка с обратной косой чертой или управляющим символом
|
||
- **WHEN** создаётся проект с меткой `A\B` или `A<перевод строки>B`
|
||
- **THEN** отказ с указанием поля `label`, проекта нет
|
||
|
||
#### Scenario: Метка — зарезервированное слово JQL
|
||
- **WHEN** заведён проект с меткой `EMPTY`
|
||
- **THEN** базовая JQL — `project = AURORA AND labels in ("EMPTY")`, метка не расширяет выборку
|
||
|
||
#### Scenario: Та же метка другим регистром
|
||
- **WHEN** есть проект `AWPCA`, создаётся проект `awpca`
|
||
- **THEN** отказ «проект с такой меткой уже есть», проект один
|
||
|
||
#### Scenario: Доски после миграции v7
|
||
- **WHEN** база v6 с проектами `AWPCA` (`board_id = 4216`, `scrum`) и `sfm_kedr` (без доски) мигрирует в v7
|
||
- **THEN** в `project` нет колонок `board_id`, `board_type`; в `jira_project` — `AWPCA` 4216 `scrum` и `sfm_kedr` `NULL`
|
||
`NULL`; перед миграцией сделана копия базы
|