diff --git a/internal/core/core.go b/internal/core/core.go index 4da4306..0e75d03 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -228,6 +228,11 @@ func (c *Core) handleRetry(ctx context.Context, rest string) (Result, error) { if err := c.Store.ClearHistory(ctx, id); err != nil { return Result{}, err } + // Чистый перезапуск: сбрасываем маркер постмортем-анализа от прошлого + // прогона, чтобы на новом failed/timeout постмортем запустился заново. + if err := c.Store.DeleteTracesByAgent(ctx, id, "postmortem"); err != nil { + return Result{}, err + } return Result{ Reply: "Задача перезапущена. Опишите, что меняем:", TaskID: id, diff --git a/internal/storage/storage_test.go b/internal/storage/storage_test.go index ab03614..5ab0936 100644 --- a/internal/storage/storage_test.go +++ b/internal/storage/storage_test.go @@ -264,6 +264,26 @@ func TestUpdateTraceOutput(t *testing.T) { } } +// TestDeleteTracesByAgent — удаление трасс по агенту (сброс маркера при /retry). +func TestDeleteTracesByAgent(t *testing.T) { + s, ctx := setupTestDB(t) + task := &Task{ChatID: "tg://del", TaskTag: "delete-by-agent"} + id, _ := s.CreateTask(ctx, task) + + _, _ = s.AppendTrace(ctx, &Trace{TaskID: id, Agent: "dev"}) + _, _ = s.AppendTrace(ctx, &Trace{TaskID: id, Agent: "postmortem"}) + _, _ = s.AppendTrace(ctx, &Trace{TaskID: id, Agent: "postmortem"}) + + if err := s.DeleteTracesByAgent(ctx, id, "postmortem"); err != nil { + t.Fatalf("DeleteTracesByAgent: %v", err) + } + + traces, _ := s.GetTraces(ctx, id) + if len(traces) != 1 || traces[0].Agent != "dev" { + t.Fatalf("traces = %d (agent %q), want только dev", len(traces), traces[0].Agent) + } +} + // хелперы для проверки классов ошибок func IsNotFound(err error) bool { return errors.Is(err, ErrNotFound) diff --git a/internal/storage/traces.go b/internal/storage/traces.go index 549fe91..8bb776a 100644 --- a/internal/storage/traces.go +++ b/internal/storage/traces.go @@ -107,6 +107,17 @@ func (s *Storage) GetLatestTrace(ctx context.Context, taskID int64, agent string return tr, nil } +// DeleteTracesByAgent удаляет все трассы задачи с заданным агентом +// (сброс маркера при /retry N: чистый перезапуск без наследия анализа). +func (s *Storage) DeleteTracesByAgent(ctx context.Context, taskID int64, agent string) error { + _, err := s.db.ExecContext(ctx, + `DELETE FROM traces WHERE task_id=? AND agent=?`, taskID, agent) + if err != nil { + return fmt.Errorf("%w: delete traces agent %s for task %d: %w", ErrDB, agent, taskID, err) + } + return nil +} + // DeleteTrace удаляет трассу. Только для тестов/админки. func (s *Storage) DeleteTrace(ctx context.Context, id int64) error { res, err := s.db.ExecContext(ctx, `DELETE FROM traces WHERE id = ?`, id)