72 lines
7.3 KiB
Markdown
72 lines
7.3 KiB
Markdown
## MODIFIED Requirements
|
||
|
||
### Requirement: Чтение состояния
|
||
`refresh` SHALL выполняться запросом `search` (`jql`, `fields` = поля зеркала включая `issuelinks`, `comment`, `attachment` и спринт,
|
||
`maxResults = 100`, постранично) и отправляться хабу пачками по 100 задач со связями; ключи из `issuelinks`, которых нет
|
||
в выборке и в зеркале хаба (хаб сообщает список известных), агент SHALL дочитать одним `search` по `key in (...)`
|
||
и отправить с признаком `neighbor`. Ошибка хаба при запросе известных ключей или отправке пачки SHALL попадать в
|
||
`error` с префиксом «хаб: »; недоступность хаба и его 5xx повторяются, как обрыв связи, с источником «хаб».
|
||
Каждая задача в состоянии (с v10) SHALL нести `comments` — все комментарии задачи в порядке Jira, каждый
|
||
`{id, author, created, updated, body}`: `id` — строка; `author` — отображаемое имя автора, иначе его логин, иначе `null`;
|
||
`created`, `updated` — время Jira как есть; `body` — текст как есть (пустой — `""`). Если `search` отдал у задачи меньше
|
||
комментариев, чем `comment.total`, агент SHALL дочитать комментарии этой задачи через `GET /issue/{key}/comment`
|
||
постранично (`maxResults = 100`) и передать полный список. Комментарий без `id` или с пустым `id` агент SHALL отбросить
|
||
с записью в лог (ключ задачи), остальные передать. Если дочитывание комментариев задачи вернуло 403 или 404, агент SHALL
|
||
передать задачу без поля `comments` (хаб оставит прежние комментарии) с записью в лог; `refresh` продолжается.
|
||
Каждая задача в состоянии (с v14) SHALL нести `attachments` — все вложения задачи из поля `attachment` ответа `search`
|
||
в порядке Jira, каждое `{id, filename, size, mime_type, author, created}`: `id` — строка; `filename` — имя как есть;
|
||
`size` — целое (байт) или `null`; `mime_type` — `mimeType` Jira или `null`; `author` — как у комментария; `created` —
|
||
время Jira как есть. Содержимое вложений при `refresh` MUST NOT скачиваться. Вложение без `id` агент SHALL отбросить с
|
||
записью в лог (ключ задачи). Нет поля `attachment` в ответе (поле скрыто настройками Jira) — `attachments = []`.
|
||
|
||
#### Scenario: Полная синхронизация
|
||
- **WHEN** `refresh {jql: "project = AURORA AND labels = AWPCA"}` при 180 задачах
|
||
- **THEN** 2 вызова `search` + 1 на соседей; `sync_run.issues_count = 180 + соседи`
|
||
|
||
#### Scenario: Хаб не ответил при отправке состояния
|
||
- **WHEN** `refresh` через папку, реле не ответило на отправку пачки ни в одной из 4 попыток
|
||
- **THEN** отчёт `failed` с ошибкой «результат неизвестен (обрыв связи с хабом), повтор безопасен: хаб: не ответил через
|
||
папку …»; в логе повторов — «обрыв связи с хабом»
|
||
|
||
#### Scenario: Комментарии в состоянии
|
||
- **WHEN** у AURORA-1620 в Jira два комментария, автор первого — `{name: "petrov", displayName: "Петров Пётр"}`, у автора
|
||
второго нет `displayName`, его `name` — `ivanov`
|
||
- **THEN** в состоянии AURORA-1620 `comments` из двух элементов в порядке Jira, `author` — «Петров Пётр» и «ivanov»; число
|
||
вызовов `search` не изменилось
|
||
|
||
#### Scenario: Неполный список комментариев
|
||
- **WHEN** `search` вернул у AURORA-1620 20 комментариев при `comment.total = 130`
|
||
- **THEN** агент дочитал комментарии двумя вызовами `GET /issue/AURORA-1620/comment`; в состоянии 130 комментариев
|
||
|
||
#### Scenario: Комментарий без id
|
||
- **WHEN** у задачи два комментария, у второго `id = null`
|
||
- **THEN** в состоянии один комментарий; в логе строка с ключом задачи; пачка принята хабом
|
||
|
||
#### Scenario: Нет доступа к комментариям
|
||
- **WHEN** `GET /issue/AURORA-1620/comment` при дочитывании вернул 403
|
||
- **THEN** AURORA-1620 в состоянии без поля `comments`; остальные задачи пачки с комментариями; `refresh` — `done`
|
||
|
||
#### Scenario: Задача без комментариев
|
||
- **WHEN** у задачи в Jira нет комментариев
|
||
- **THEN** в её состоянии `comments = []`
|
||
|
||
#### Scenario: Вложения в состоянии
|
||
- **WHEN** у AURORA-1650 в Jira два вложения: «скрин 1.png» (`mimeType = image/png`, 240000 байт, автор
|
||
`{name: "potapova", displayName: "Потапова Анна"}`) и «ОСВ 60.xlsx»
|
||
- **THEN** в состоянии AURORA-1650 `attachments` из двух элементов в порядке Jira, у первого `filename = "скрин 1.png"`,
|
||
`size = 240000`, `mime_type = "image/png"`, `author = "Потапова Анна"`; число вызовов `search` не изменилось, обращений
|
||
к содержимому вложений нет
|
||
|
||
## ADDED Requirements
|
||
|
||
### Requirement: Скачивание вложения
|
||
Агент v14 SHALL выполнять `fetch_attachment` по контракту `commands` («Скачивание вложения по запросу»). Метод `JiraClient`
|
||
для содержимого SHALL отдавать байты ответа без разбора JSON, с тем же счётом вызовов, повтором 429/503 и учётом времени
|
||
последнего вызова, что и прочие вызовы Jira. Отправка хабу — `HubClient` (`POST /agent/files`), работает и через общую
|
||
папку. В журнал агента (`journal.jsonl`) и в лог содержимое файла MUST NOT попадать — только id, имя, размер и sha256.
|
||
|
||
#### Scenario: Скачивание через общую папку
|
||
- **WHEN** агент с `hub_url = folder:…` выполняет `fetch_attachment` вложения 3 МБ
|
||
- **THEN** содержимое уходит хабу одним запросом `POST /agent/files` через папку (тело ≈ 4 МБ base64); отчёт `done` с
|
||
`file` и `size`; в `journal.jsonl` нет содержимого файла
|