Загрузка данных
Работаем в project-manager-tools.
Контекст:
Финальная текущая версия уже проверена на рабочей сети.
Сейчас работает:
- создание Release через POST /rest/api/unit/v2/release/create
- создание Epic через POST /rest/api/unit/v2/epic/create
- создание Story через POST /rest/api/unit/v2/story/create
- создание Task через POST /rest/api/unit/v2/task/create
- создание Bug через POST /rest/api/unit/v2/bug/create
- создание связей через POST /rest/api/unit/v1/link
- links работают с HTTP 201
- dry-run режим работает
- sbertrack_write_enabled возвращается в false
- UnitCache уже создан и хранит created IDs локально
- action sbertrack_cache_status работает
- action sbertrack_plan_full_release_safe работает
- action sbertrack_create_full_release_from_yaml_ensure уже добавлен
- blocker НЕ трогать на этом этапе
Текущая цель:
Доделать Jira-like поведение по порядку:
ЭТАП 1 — PATCH/update по code.
ЭТАП 2 — remote search по summary, если cache пустой.
ЭТАП 3 — ensure_unit_by_summary должен работать по схеме:
cache -> remote search -> update/create.
Важно:
Сейчас blocker не реализуем и не тестируем.
Не делать реальный blocker POST.
Не делать git push.
Не выводить секреты.
Не выводить полный .env.
Не ломать уже работающее создание release/epic/story/task/bug/link.
Все реальные write-запросы только после отдельного подтверждения.
Сначала dry-run и диагностика.
Перед изменениями:
1. Создай backup файлов:
- src/sbertrack_api.py
- src/sbertrack_planner.py
- src/unit_cache.py
- src/main.py
2. Проверь, что:
- sbertrack_write_enabled=false
- секреты не выводятся
- git status не обязателен, потому что папка может быть не git repo
Что нужно сделать:
==================================================
1. Найти подтверждённый endpoint для update
==================================================
Проверь в текущем проекте и доступных локальных источниках, есть ли уже упоминания:
- update_unit_by_code
- unit.update
- issue.update
- client.patch
- client.put
- PATCH /rest/api/unit/v2
- PATCH /rest/api/unit/v2/{code}
- PATCH /rest/api/unit/v2/update
- PATCH /rest/api/unit/v2/update/{code}
- PUT /rest/api/unit/v2/{code}
- /rest/api/unit/v2/update
- /rest/api/unit/v2/{unit_code}
Также проверь, установлен ли пакет sbertrack_python_api:
python -c "import sbertrack_python_api; print(sbertrack_python_api.__file__)"
Если установлен, найди исходники:
python -c "import sbertrack_python_api, os; print(os.path.dirname(sbertrack_python_api.__file__))"
По исходникам пакета безопасно поискать:
- class SbertrackClient
- def patch
- def put
- unit.update
- issue.update
- update(
- /rest/api/unit/v2/update
- /rest/api/unit/v2/{code}
- /rest/api/unit/v2
Ничего не выполнять через POST/PATCH/PUT/DELETE на этапе поиска.
Нужно вывести:
- найден ли update endpoint;
- найден ли готовый метод в sbertrack_python_api;
- какой payload ожидается;
- можно ли безопасно подключить его в наш проект;
- если endpoint не подтверждён, update оставить только dry-run stub.
==================================================
2. Реализовать update_unit_by_code
==================================================
В src/sbertrack_api.py добавить или доработать метод:
update_unit_by_code(code, payload)
Требования:
- Если sbertrack_write_enabled=false:
- НЕ выполнять PATCH/PUT.
- Вывести dry-run информацию:
- code
- endpoint, который был бы использован
- sanitized payload
- Вернуть структуру результата вида:
{
"dry_run": True,
"code": code,
"updated": False,
"reason": "sbertrack_write_enabled=false"
}
- Если sbertrack_write_enabled=true:
- выполнять только подтверждённый endpoint.
- Если endpoint не подтверждён — не выполнять реальный PATCH/PUT, а вернуть RuntimeError или понятное сообщение:
"update endpoint is not confirmed"
- Не выводить секреты.
- Не выводить полный .env.
- Обработать HTTP status и response body.
- После ошибки не оставлять write_enabled=true.
Важно:
Если endpoint update не подтверждён документацией или кодом sbertrack_python_api, НЕ придумывать endpoint.
Лучше оставить update в dry-run режиме и явно написать, что нужен endpoint от наставника.
==================================================
3. Найти remote search по summary
==================================================
Нужно выяснить, можно ли искать unit в SberTrack по summary/name/title/query.
Проверить в текущем проекте, документации и sbertrack_python_api:
- unit.search
- unit.find
- unit.find_9
- search_units
- find_units
- issue.getByKey
- issue.find
- query
- title
- name
- summary
- TQL
- filter
- /rest/api/unit/v2/search
- /rest/api/unit/v2/find
- /rest/api/unit/v2/all
- /rest/api/unit/v2
- /rest/api/user/v1/search
- POST search
- client.post(...search...)
- client.get(...query...)
Нужно найти:
- есть ли endpoint/метод поиска unit по пространству и summary;
- можно ли фильтровать по space/project;
- можно ли фильтровать по unit type;
- можно ли искать через TQL;
- какой payload нужен;
- какой response возвращается.
Реальные POST/GET поиска можно делать только если это read-only операция.
Если GET/POST search безопасный и не создаёт сущности — можно выполнить тестовый read-only запрос.
Но:
- не выводить токены;
- не выводить полный .env;
- не делать create/update/delete.
==================================================
4. Реализовать find_unit_by_summary
==================================================
В src/sbertrack_api.py добавить или доработать метод:
find_unit_by_summary(space, unit_type, summary)
Логика:
1. Сначала нормализовать summary:
- trim
- lower
- схлопнуть повторные пробелы
2. Сначала проверить UnitCache:
- если найден code, дополнительно попробовать get_unit_by_code(code)
- если get_unit_by_code успешен, вернуть найденный unit/code
- если get_unit_by_code недоступен или ошибка, не падать, а перейти к remote search
3. Если cache miss:
- выполнить remote search, если endpoint подтверждён
- искать по space + unit_type + summary
- если найдено ровно одно совпадение — вернуть code
- если найдено несколько совпадений — вывести предупреждение и выбрать самое точное совпадение по нормализованному summary, если оно одно
- если точного совпадения нет — вернуть None
- если endpoint не подтверждён — вернуть None и явно написать, что remote search не подтверждён
4. Никакого auto-create внутри find_unit_by_summary делать нельзя.
==================================================
5. Реализовать ensure_unit_by_summary
==================================================
В src/sbertrack_api.py добавить или доработать метод:
ensure_unit_by_summary(unit_type, summary, payload, space=None)
Логика как в Jira:
1. Проверить cache.
2. Если cache hit:
- проверить get_unit_by_code(code), если метод доступен.
- если unit существует:
- вызвать update_unit_by_code(code, payload)
- вернуть code.
3. Если cache miss:
- выполнить remote search по summary.
- если найден существующий unit:
- сохранить code в cache.
- вызвать update_unit_by_code(code, payload), если update подтверждён.
- вернуть code.
4. Если ничего не найдено:
- создать новый unit через существующие рабочие create_release/create_epic/create_story/create_task/create_bug.
- сохранить created code в cache.
- вернуть code.
Важное ограничение:
- Если sbertrack_write_enabled=false:
- create не выполняется.
- update не выполняется.
- показывается план действий.
- Если sbertrack_write_enabled=true:
- create выполняется только для реально отсутствующих сущностей.
- update выполняется только если endpoint update подтверждён.
- если update endpoint не подтверждён, существующую сущность не обновлять, только вернуть warning.
==================================================
6. Обновить planner
==================================================
В src/sbertrack_planner.py:
Доработать create_full_release_from_yaml_ensure так, чтобы он не создавал дубли:
- Release:
ensure_unit_by_summary("release", summary, release_payload, space)
- Epic:
ensure_unit_by_summary("epic", epic_summary, epic_payload, space)
- Story:
ensure_unit_by_summary("story", story_summary, story_payload, space)
- Task:
ensure_unit_by_summary("task", task_summary, task_payload, space)
- Bug:
ensure_unit_by_summary("bug", bug_summary, bug_payload, space)
Связи создавать после получения актуальных code.
Перед созданием связи:
- не создавать связь, если source или destination отсутствует;
- желательно использовать существующую безопасную проверку, чтобы не падать на дублях;
- если SberTrack возвращает "already exists" / HTTP 570, считать это ожидаемым предупреждением, а не критической ошибкой.
==================================================
7. Обновить main.py
==================================================
Добавить/проверить actions:
1. sbertrack_cache_status
- read-only
- показывает cache
2. sbertrack_plan_full_release_safe
- всегда dry-run
- ничего не создаёт
- показывает план
3. sbertrack_create_full_release_from_yaml_ensure
- использует ensure pattern
- при sbertrack_write_enabled=false только dry-run
- при true создаёт только отсутствующее
- update выполняет только если endpoint подтверждён
4. Добавить отдельный безопасный action для проверки поиска:
sbertrack_find_unit_by_summary
Пример параметров:
--unit_type release
--summary "testic"
--space TST123456
Он должен:
- сначала смотреть cache;
- потом remote search, если подтверждён;
- ничего не создавать;
- ничего не обновлять;
- вывести найденный code или "not found".
==================================================
8. Тесты
==================================================
Выполнить только безопасные команды сначала:
1. Проверка синтаксиса:
python -m py_compile src/sbertrack_api.py src/sbertrack_planner.py src/unit_cache.py src/main.py src/yaml_reader.py
2. Проверка .env без секретов:
grep -E 'sbertrack_write_enabled|sbertrack_project_key|sbertrack_base_url' .env
3. Cache status:
python src/main.py --tracker sbertrack --action sbertrack_cache_status --project luch --service luch-pprb
4. Safe plan:
python src/main.py --tracker sbertrack --action sbertrack_plan_full_release_safe --project luch --service luch-pprb
5. Find by summary dry/read-only:
python src/main.py --tracker sbertrack --action sbertrack_find_unit_by_summary --project luch --service luch-pprb --unit_type release --summary "testic" --space TST123456
6. Ensure dry-run:
python src/main.py --tracker sbertrack --action sbertrack_create_full_release_from_yaml_ensure --project luch --service luch-pprb
Если всё успешно и sbertrack_write_enabled=false, реальных POST/PATCH/PUT/DELETE быть не должно.
Реальный запуск делать только после отдельного подтверждения.
==================================================
9. Финальный отчёт
==================================================
В конце выведи финальный отчёт:
## 1. Какие файлы изменены
Таблица:
Файл | Что изменено | Backup создан
## 2. Update/PATCH
- endpoint найден: да/нет
- метод библиотеки найден: да/нет
- реальный PATCH/PUT выполнялся: да/нет
- если нет — почему
## 3. Remote search по summary
- endpoint найден: да/нет
- метод библиотеки найден: да/нет
- read-only поиск выполнялся: да/нет
- найден ли testic по summary: да/нет
- какой code найден
## 4. Ensure pattern
Покажи итоговую логику:
cache -> remote search -> update/create
## 5. Проверка безопасности
Подтверди:
- sbertrack_write_enabled=false в конце
- секреты не выводились
- полный .env не выводился
- POST без подтверждения не выполнялся
- PATCH/PUT/DELETE без подтверждения не выполнялись
- git push не выполнялся
- blocker не трогался
## 6. Что осталось
Отдельно перечисли:
- что осталось уточнить у наставника по PATCH/update
- что осталось уточнить по remote search/TQL
- что осталось уточнить по blocker