feat: воркер берёт задачи только после одобрения (approved)
Some checks failed
CI / test (push) Failing after 49s
CI / build-and-package (amd64, linux) (push) Successful in 42s
CI / build-and-package (amd64, windows) (push) Successful in 45s

Исправляет баг: воркер захватывал задачу на выполнение по статусу ready
ещё до «создавай» (consent был заглушкой). Теперь:

- новый статус approved: «создавай» → ready→approved;
- воркер (pollAndDispatch + runTask) берёт ТОЛЬКО approved,
  ready = черновик готов, ждёт одобрения;
- правка/текст в approved запрещены (финальное одобрение);
- e2e-тест TestE2EWorkerDoesNotTakeUnconfirmed: в ready воркер задачу
  не трогает, запускает только после «создавай» → success;
- обновлены все затронутые тесты (models/core/worker) и retry-фикстуры.
This commit is contained in:
Hermes
2026-08-17 19:03:42 +05:00
parent f12ff04966
commit 43266ea04f
7 changed files with 152 additions and 31 deletions

View File

@@ -52,7 +52,7 @@ func (c *Core) ProcessTurn(ctx context.Context, taskID int64, text string) (Resu
return Result{}, err
}
// 2. согласие в фазе ready → создание
// 2. согласие в фазе ready → одобрение
if task.Status == storage.StatusReady {
if isConsent(text) {
return c.handleConsent(ctx, task)
@@ -61,6 +61,17 @@ func (c *Core) ProcessTurn(ctx context.Context, taskID int64, text string) (Resu
return c.handleEdit(ctx, task, text)
}
// 2b. approved — финальное одобрение, правка запрещена.
// Воркер уже взял/заберёт задачу; текст не меняет статус.
if task.Status == storage.StatusApproved {
return Result{
Reply: "Задача уже одобрена и передана на выполнение. Следите за статусом: /status " + itoa(task.ID),
Action: "send",
TaskID: task.ID,
Status: task.Status,
}, nil
}
// 3. обычный ход: накопление + аналитик
return c.handleTurn(ctx, task, text)
}
@@ -271,14 +282,15 @@ func (c *Core) notFoundReply(ctx context.Context, id int64, err error) (Result,
}, nil
}
// handleConsent создаёт задачу (статус ready → ...). Пока — подтверждение готовности.
// handleConsent одобряет задачу: ready → approved (финальное одобрение,
// после которого воркер забирает задачу на выполнение).
func (c *Core) handleConsent(ctx context.Context, task *storage.Task) (Result, error) {
task.Status = storage.StatusReady
task.Status = storage.StatusApproved
if err := c.Store.UpdateTask(ctx, task); err != nil {
return Result{}, err
}
return Result{
Reply: "✅ Задача #" + itoa(task.ID) + " готова к запуску.",
Reply: "✅ Задача #" + itoa(task.ID) + " одобрена. Запускаю выполнение.",
Action: "created:" + itoa(task.ID),
TaskID: task.ID,
Status: task.Status,

View File

@@ -160,6 +160,10 @@ func TestConsentInReady(t *testing.T) {
if res.Action != "created:"+itoa(id) {
t.Fatalf("action = %q, want created:%d", res.Action, id)
}
task, _ := store.GetTask(ctx, id)
if task.Status != storage.StatusApproved {
t.Fatalf("status после создавай = %s, want approved", task.Status)
}
}
func TestEditInReadyGoesCollecting(t *testing.T) {