auto-sync: 2026-06-03 10:10:01

This commit is contained in:
Stream
2026-06-03 10:10:01 +03:00
parent f0aa3b9c9e
commit 90d6250690
2 changed files with 96 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
# 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 уже был).
## Сделано
- [x] Разведка живым GET — формат подтверждён
- [x] `plane_sync.py`: `fetch_issue_sequence_id(issue_id, project_id) -> int|None` (timeout=10, try/except, не кидает)
- [x] `webhooks/plane.py` `handle_work_item_created`: seq→`f"{prefix}-{seq:03d}"`, None→fallback DB + logger.warning
- [x] `plane_sync.py` `find_issue_id`: убран хардкод `ET-`, матч по sequence_id из суффикса work_item_id (rsplit("-",1)), обобщён на любой префикс
- [x] `tests/test_m6_sequence.py` — 7 тестов
- [x] 2 коммита (Conventional Commits), push, проверка remote, PR #8
## Изменённые файлы
- `src/plane_sync.py` — +helper `fetch_issue_sequence_id`; find_issue_id без ET-хардкода (матч по числу из суффикса)
- `src/webhooks/plane.py` — work_item_id из Plane seq + fallback на get_next_work_item_id
- `tests/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: https://git.mva154.duckdns.org/admin/orchestrator/pulls/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. НЕ деплоил, НЕ мержил.