4.7 KiB
4.7 KiB
Dev Report: M-6 — work_item_id из Plane sequence_id
Дата: 2026-06-03 Статус: DONE (запушено, PR #8 открыт; НЕ мержено — мерж за Стримом после живой проверки)
Задача
Источник правды для номера work_item_id — Plane sequence_id, маппить в <prefix>-NNN.
Fallback на get_next_work_item_id (DB-инкремент) если Plane недоступен (автономность > точность).
Бонус: убрать хардкод ET- в find_issue_id.
Разведка (живой GET к Plane) — КЛЮЧЕВОЕ
- Endpoint одиночного issue:
{PLANE_BASE}/workspaces/{ws}/projects/{pid}/issues/{uuid}/— trailing slash ОБЯЗАТЕЛЕН: без него 301 redirect (не JSON). - Успешный GET (issue
64e98247-..., seq=5) → 200,sequence_id— top-level int (5), поле называется именноsequence_id. Формат helper-шаблона из ТЗ совпал 1:1. - GET по
f9009756-...(ET-010) → 404 с{"error": ...}JSON →.get("sequence_id")= None → helper вернёт None. Этот issue реально отсутствует в Plane — живая иллюстрация рассинхрона, ради которого делается M-6. - Списочный endpoint
/issues/→ 200,results[]сsequence_id(int) на каждом issue. - Вывод: шаблон helper-а из ТЗ корректен, использован как есть (trailing slash уже был).
Сделано
- Разведка живым GET — формат подтверждён
plane_sync.py:fetch_issue_sequence_id(issue_id, project_id) -> int|None(timeout=10, try/except, не кидает)webhooks/plane.pyhandle_work_item_created: seq→f"{prefix}-{seq:03d}", None→fallback DB + logger.warningplane_sync.pyfind_issue_id: убран хардкодET-, матч по sequence_id из суффикса work_item_id (rsplit("-",1)), обобщён на любой префиксtests/test_m6_sequence.py— 7 тестов- 2 коммита (Conventional Commits), push, проверка remote, PR #8
Изменённые файлы
src/plane_sync.py— +helperfetch_issue_sequence_id; find_issue_id без ET-хардкода (матч по числу из суффикса)src/webhooks/plane.py— work_item_id из Plane seq + fallback на get_next_work_item_idtests/test_m6_sequence.py— новый, 7 тестов
Результат
- Новые тесты: 7 passed (helper int/None×2/missing-field; created→ORCH-007 по seq=7; created→fallback ORCH-099 при seq=None; find_issue_id ORCH-005 по seq=5; ET-002 по seq=2).
- Полный прогон в контейнере (IMG=orchestrator-orchestrator): 158 passed, 9 failed — 9 = pre-existing 401/signature в test_webhooks.py (baseline 151 + 7 новых = 158). M-6 не трогает HMAC; 9 не починены и не сломаны (как требует ТЗ).
- Fallback-путь: при seq=None task всё равно создаётся (тест
test_created_falls_back_to_db_when_plane_downэто assert-ит) → автономность сохранена.
Git
- Ветка
feature/ORCH-M6-plane-sequenceиз свежего main (be27f50). - Коммиты:
1d978ca feat(webhook): derive work_item_id from Plane sequence_id (M-6)c431a3d fix(plane_sync): drop hardcoded ET- prefix in find_issue_id (M-6)
git log origin/main..origin/feature/ORCH-M6-plane-sequence→ оба коммита присутствуют на remote (грабля ORCH-7 проверена).- PR #8: admin/orchestrator#8 (head→base = feature→main).
- Токен: рабочий из env контейнера (
ORCH_GITEA_TOKEN=c81227...), совпал с embedded в origin URL.
Проблемы и решения
- Remote-only репо (нет локального доступа) → редактировал через Python-скрипты по SSH; heredoc с Python мангал shell → решил через
cat > file(base64-free, через stdin). - Коммит-сплит: оба изменения в plane_sync.py → разнёс
git add -p(printf "y\nn\n") — feature-хелпер в коммит 1, find_issue_id-фикс в коммит 2.
Ограничения соблюдены
Не трогал: nginx/openclaw.json/.env/deploy-хук/is_active/ORCH-1..7/stage_engine/STAGE_TRANSITIONS/HMAC/очередь.
get_next_work_item_id оставлен как fallback. НЕ деплоил, НЕ мержил.