Загрузка данных


Работаем в project-manager-tools.

Контекст:
Мы подтвердили real POST для blocker в SberTrack.

Рабочий endpoint:
POST /rest/api/unit/v2/blocker/create

Результат:
HTTP 200, blocker создаётся.

Blocker — отдельный unit type / suit code:
blocker

Рабочий payload:

{
  "summary": "TEST blocker summary",
  "description": "Optional description",
  "space": "TST123456",
  "attributes": {
    "priority": "low",
    "workflow_status": {
      "command": "NEW"
    },
    "reporter": "23865613",
    "reason_for_blocking": {
      "code": "external_wait"
    },
    "sber_configuration_item": [
      {
        "code": "CI02298102"
      }
    ]
  }
}

Важные выводы:
- reason_for_blocking обязательно передавать как объект {"code": "..."}.
- priority можно low/blocker/high/mid/critical.
- workflow_status формат такой же, как у остальных unit: {"command": "NEW"}.
- sber_configuration_item передаётся стандартно массивом объектов [{"code": "..."}].
- blocker не bug и не defect, а отдельный unit type.
- Тестовые blocker уже созданы:
  - TST123456-102
  - TST123456-104
Их не трогать, не удалять.

Задача:
Доработать проект так, чтобы blocker был полноценной частью SberTrack YAML planner, но без выполнения новых реальных POST-запросов.

Строгие ограничения:
- НЕ делать реальный POST.
- НЕ делать PATCH.
- НЕ делать PUT.
- НЕ делать DELETE.
- НЕ создавать новые release/epic/story/task/bug/blocker.
- НЕ создавать links.
- НЕ делать git push.
- НЕ выводить секреты.
- НЕ выводить полный .env.
- sbertrack_write_enabled должен оставаться false.
- Работать только dry-run/read-only.

Что нужно реализовать:

## 1. Backup

Перед изменениями создать backup файлов:
- src/sbertrack_api.py
- src/sbertrack_planner.py
- src/main.py
- src/unit_cache.py
- projects/YAML_TEMPLATE.md

Backup назвать с суффиксом:
.backup_before_blocker_integration

## 2. src/sbertrack_api.py

Добавить полноценный метод:

create_blocker(payload)

Логика должна быть аналогична create_release/create_epic/create_story/create_task/create_bug.

Endpoint:
POST /rest/api/unit/v2/blocker/create

Поведение:
- если sbertrack_write_enabled=false:
  - не выполнять POST;
  - вывести dry-run endpoint;
  - вывести payload без секретов;
  - вернуть dry-run результат.
- если sbertrack_write_enabled=true:
  - выполнить POST;
  - вернуть created code/id;
  - обработать HTTP 200/201 как success;
  - HTTP 570 показать с понятным текстом ошибки.

Важно:
Не ломать существующий create_blocker_dry_run(), если он уже есть. Можно переиспользовать его внутри create_blocker.

## 3. build_blocker_payload()

Проверить и поправить build_blocker_payload().

Он должен строить payload в таком формате:

{
  "summary": "...",
  "description": "...",
  "space": "...",
  "attributes": {
    "priority": "...",
    "workflow_status": {"command": "NEW"},
    "reporter": "...",
    "reason_for_blocking": {"code": "..."},
    "sber_configuration_item": [{"code": "..."}]
  }
}

Правила:
- reason_for_blocking:
  - если в YAML строка, например external_wait, преобразовать в {"code": "external_wait"};
  - если уже объект {"code": "..."} — оставить как есть.
- priority:
  - если не указано, ставить "low".
- workflow_status:
  - если не указано, ставить {"command": "NEW"}.
- reporter:
  - брать из YAML, config или текущего пользователя, как уже сделано в проекте.
- sber_configuration_item:
  - брать из YAML/blocker, если есть;
  - если нет, брать из release/root yaml ci_code, как для bug/task/release;
  - формат всегда [{"code": "..."}].

## 4. ensure_unit_by_summary()

Добавить поддержку blocker в create_methods:

"blocker": self.create_blocker

То есть ensure должен работать для blocker так же, как для:
- release
- epic
- story
- task
- bug

Логика:
cache -> get_unit_by_code verify -> remote search -> create_blocker only if write_enabled=true.

При write_enabled=false create не выполнять, только dry-run.

## 5. src/sbertrack_planner.py

Добавить обработку секции blockers в YAML.

Ожидаемый YAML формат:

blockers:
  - summary: "Название блокера"
    description: "Описание блокера"
    reason_for_blocking: "external_wait"
    priority: "low"
    reporter: "23865613"
    team: "Команда"
    assignee: "23865613"
    ci_code: "CI02298102"

Нужно:
- добавить preview blockers в dry-run;
- добавить create blockers в create_full_release_from_yaml / create_full_release_from_yaml_ensure;
- blocker создавать через ensure_unit_by_summary("blocker", summary, payload);
- сохранять code blocker в cache;
- не создавать links для blocker на этом этапе, если модель связей blocker ещё не утверждена.

## 6. YAML_TEMPLATE.md

Добавить пример секции blockers:

blockers:
  - summary: "Название блокера"
    description: "Описание блокера"
    reason_for_blocking: "external_wait"
    priority: "low"
    reporter: "23865613"
    ci_code: "CI02298102"

Добавить комментарии:
- reason_for_blocking передаётся в API как {"code": "..."}.
- blocker создаётся как отдельный unit type.
- link type blocks пока не создаётся автоматически до отдельного подтверждения направления связи.

## 7. src/main.py

Если есть choices по unit_type, добавить:
blocker

Если есть action для find/create/ensure, убедиться, что blocker поддерживается.

Новые реальные POST не выполнять.

## 8. Проверки

Выполнить только безопасные проверки:

1. py_compile:
python -m py_compile src/sbertrack_api.py src/sbertrack_planner.py src/unit_cache.py src/main.py src/yaml_reader.py

2. Dry-run preview:
python src/main.py --tracker sbertrack --action sbertrack_plan_full_release_safe --project luch --service luch-pprb

3. Dry-run ensure:
python src/main.py --tracker sbertrack --action sbertrack_create_full_release_from_yaml_ensure --project luch --service luch-pprb

4. Cache status:
python src/main.py --tracker sbertrack --action sbertrack_cache_status --project luch --service luch-pprb

Проверить:
- blockers отображаются в dry-run;
- payload blocker полный;
- reason_for_blocking преобразован в {"code": "..."};
- sber_configuration_item передан;
- при sbertrack_write_enabled=false POST не выполняется.

## 9. Финальный отчёт

Вывести:

### 1. Какие файлы изменены
Таблица:
Файл | Что изменено | Backup создан

### 2. Blocker implementation
Показать:
- endpoint;
- payload format;
- обязательные поля;
- dry-run behavior;
- ensure behavior.

### 3. Проверки
Таблица:
Проверка | Результат

### 4. Безопасность
Подтвердить:
- sbertrack_write_enabled=false
- real POST не выполнялся
- PATCH не выполнялся
- PUT не выполнялся
- DELETE не выполнялся
- links не создавались
- git push не выполнялся
- секреты не выводились
- полный .env не выводился

### 5. Что осталось
Честно написать:
- blocker create подтверждён;
- blocker как unit type подтверждён;
- link type blocks подтверждён;
- автоматическое создание связи blocks пока не включено, потому что нужно отдельно подтвердить направление source/destination.