Status: Accepted
Date: 2026-04-18
Анализ потребителей endpoint'ов в экосистеме (journal phase-05) показал:
POST /api/v1/protocol/merge/byAgenda/{id}) — автотриггер из OBESRABUO_agenda state-machine (GenerateProtocolByQuestionAction). Agenda ждёт ответ блокирующе через Feign.useCreateProtocolByAgendaAsync, "ждёт до timeout'а и возвращает результат". Дублирует task-based.useCreateProtocolByAgendaTask + GET /task/{id}/status. Правильный паттерн.Критический фактор: генерация протокола занимает до 10 минут на реальных данных. Sync v1 Feign-вызов на 10 минут:
Sync v1 — структурный анти-паттерн для операции такого размера. Но одномоментно удалить нельзя — agenda-state-machine его использует, нужна согласованная миграция.
Protocol 2.0 выставляет 3 endpoint'а:
POST /api/v2/protocol/merge/byAgenda/{id}/task → {taskId} [primary async]
GET /api/v2/protocol/task/{taskId}/status → {status, result?} [polling статуса]
POST /api/v1/protocol/merge/byAgenda/{id} → Protocol (sync) [bridge, deprecated]
Удаляются:
POST /api/v2/protocol/merge/byAgenda/{id} (sync v2) — dead, без потребителей.POST /api/v2/protocol/merge/byAgenda/{id}/async (async без task) — deprecated. Frontend мигрируется на task-based (тривиальный refactor, уже использует оба).Sync v1 не выпиливаем сразу, но реализуем его поверх task-based:
ProtocolController.v1Sync делает то же что task endpoint, затем в том же HTTP-thread polls TaskStorage до готовности, отдаёт результат.@Deprecated + log.warn("Sync v1 called by {}, migrate to task-based", traceCaller).taskId в теле, чтобы caller мог продолжить polling через task-endpoint.Фаза M1 — текущая (ship protocol 2.0):
Фаза M2 — agenda migration (следующий инкремент agenda):
ObesrabuoProtocolGenerationCompleted / ...Failed через common-events API после Phase 4 / при провале.REPORT_SIGNED → PROTECTED выполняется локально в agenda.POST /task → сохранить taskId в поле вопроса/повестки → ждать event → transition.Фаза M3 — cleanup:
Если common-events инфраструктура окажется не готова или бюрократически сложной, fallback — agenda делает polling task-status по расписанию:
taskId в поле сущности с ожидающим состоянием.GET /task/{id}/status → если COMPLETED/FAILED — делает state-transition.Менее изящно, но работает без изменений в common. Решение между event-driven и polling для M2 — в questions-to-business.md.
Positive:
Negative:
ConfirmLoadProtocol.ProtocolController (bridge v1), ProtocolTaskController (task-based), ProtocolEventsProvider.notifyGenerationCompleted (M2, event emission)