2026-10-24 00:18:31 +04:00

77 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 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`; перед миграцией сделана копия базы