fix(pipeline): premature state update + reject 재생성 알림

버그1: /feedback approve가 bg task 시작 전에 state를 next_pending으로 set →
polling이 빈 video_url로 알림 발송. bg task의 run_step이 state를 set하도록
일임 — 이중 update 제거.

버그2: reject 후 같은 *_pending 상태로 재생성됐을 때 dedupe에 막혀 알림이
안 감. dedupe 키에 feedback_count_per_step[step]을 포함 — 재생성마다
count가 증가하므로 키가 달라져 재알림 동작.
This commit is contained in:
2026-05-08 23:08:24 +09:00
parent 6d416aab78
commit 97b15cb985
3 changed files with 40 additions and 6 deletions

View File

@@ -35,6 +35,7 @@ async def test_poll_notifies_once_per_state():
"state": "cover_pending",
"cover_url": "/x.jpg",
"track_title": "Test",
"feedback_count_per_step": {},
}]
with patch(
"app.agents.youtube_publisher.service_proxy.list_active_pipelines",
@@ -52,6 +53,27 @@ async def test_poll_notifies_once_per_state():
assert mock_send.call_count == 1
@pytest.mark.asyncio
async def test_poll_renotifies_on_reject_regen(monkeypatch):
from app.agents.youtube_publisher import YoutubePublisherAgent
pipelines_v1 = [{"id": 1, "state": "cover_pending", "cover_url": "/x.jpg",
"track_title": "Test", "feedback_count_per_step": {}}]
pipelines_v2 = [{"id": 1, "state": "cover_pending", "cover_url": "/x2.jpg",
"track_title": "Test", "feedback_count_per_step": {"cover": 1}}]
list_mock = AsyncMock(side_effect=[pipelines_v1, pipelines_v2])
with patch("app.agents.youtube_publisher.service_proxy.list_active_pipelines", list_mock), \
patch("app.agents.youtube_publisher.send_raw",
new=AsyncMock(return_value={"ok": True, "message_id": 99})), \
patch("app.agents.youtube_publisher.service_proxy.save_pipeline_telegram_msg",
new=AsyncMock()):
a = YoutubePublisherAgent()
await a.poll_state_changes() # 1st: notify
await a.poll_state_changes() # 2nd: feedback count differs → notify again
from app.agents.youtube_publisher import send_raw as sr
assert sr.call_count == 2
@pytest.mark.asyncio
async def test_on_telegram_reply_approve_calls_feedback():
from app.agents.youtube_publisher import YoutubePublisherAgent