diff --git a/backend/internal/handler/admin/scheduled_test_handler.go b/backend/internal/handler/admin/scheduled_test_handler.go index f400f1fc..f26e1fb1 100644 --- a/backend/internal/handler/admin/scheduled_test_handler.go +++ b/backend/internal/handler/admin/scheduled_test_handler.go @@ -47,9 +47,6 @@ func (h *ScheduledTestHandler) ListByAccount(c *gin.Context) { response.InternalError(c, err.Error()) return } - if plans == nil { - plans = []*service.ScheduledTestPlan{} - } c.JSON(http.StatusOK, plans) } @@ -154,8 +151,5 @@ func (h *ScheduledTestHandler) ListResults(c *gin.Context) { response.InternalError(c, err.Error()) return } - if results == nil { - results = []*service.ScheduledTestResult{} - } c.JSON(http.StatusOK, results) } diff --git a/backend/internal/service/account_test_service.go b/backend/internal/service/account_test_service.go index 5891770d..e2351805 100644 --- a/backend/internal/service/account_test_service.go +++ b/backend/internal/service/account_test_service.go @@ -1564,7 +1564,7 @@ func (s *AccountTestService) sendErrorAndEnd(c *gin.Context, errorMsg string) er // RunTestBackground executes an account test in-memory (no real HTTP client), // capturing SSE output via httptest.NewRecorder, then parses the result. -func (s *AccountTestService) RunTestBackground(ctx context.Context, accountID int64, modelID string) (*ScheduledTestOutcome, error) { +func (s *AccountTestService) RunTestBackground(ctx context.Context, accountID int64, modelID string) (*ScheduledTestResult, error) { startedAt := time.Now() w := httptest.NewRecorder() @@ -1574,28 +1574,25 @@ func (s *AccountTestService) RunTestBackground(ctx context.Context, accountID in testErr := s.TestAccountConnection(ginCtx, accountID, modelID) finishedAt := time.Now() - latencyMs := finishedAt.Sub(startedAt).Milliseconds() - body := w.Body.String() responseText, errMsg := parseTestSSEOutput(body) - outcome := &ScheduledTestOutcome{ - Status: "success", - ResponseText: responseText, - ErrorMessage: errMsg, - LatencyMs: latencyMs, - StartedAt: startedAt, - FinishedAt: finishedAt, - } - + status := "success" if testErr != nil || errMsg != "" { - outcome.Status = "failed" + status = "failed" if errMsg == "" && testErr != nil { - outcome.ErrorMessage = testErr.Error() + errMsg = testErr.Error() } } - return outcome, nil + return &ScheduledTestResult{ + Status: status, + ResponseText: responseText, + ErrorMessage: errMsg, + LatencyMs: finishedAt.Sub(startedAt).Milliseconds(), + StartedAt: startedAt, + FinishedAt: finishedAt, + }, nil } // parseTestSSEOutput extracts response text and error message from captured SSE output. diff --git a/backend/internal/service/scheduled_test_port.go b/backend/internal/service/scheduled_test_port.go index f795ba00..c02a6b43 100644 --- a/backend/internal/service/scheduled_test_port.go +++ b/backend/internal/service/scheduled_test_port.go @@ -32,16 +32,6 @@ type ScheduledTestResult struct { CreatedAt time.Time `json:"created_at"` } -// ScheduledTestOutcome is returned by RunTestBackground. -type ScheduledTestOutcome struct { - Status string - ResponseText string - ErrorMessage string - LatencyMs int64 - StartedAt time.Time - FinishedAt time.Time -} - // ScheduledTestPlanRepository defines the data access interface for test plans. type ScheduledTestPlanRepository interface { Create(ctx context.Context, plan *ScheduledTestPlan) (*ScheduledTestPlan, error) diff --git a/backend/internal/service/scheduled_test_runner_service.go b/backend/internal/service/scheduled_test_runner_service.go index 45d85624..477695da 100644 --- a/backend/internal/service/scheduled_test_runner_service.go +++ b/backend/internal/service/scheduled_test_runner_service.go @@ -117,13 +117,13 @@ func (s *ScheduledTestRunnerService) runScheduled() { } func (s *ScheduledTestRunnerService) runOnePlan(ctx context.Context, plan *ScheduledTestPlan) { - outcome, err := s.accountTestSvc.RunTestBackground(ctx, plan.AccountID, plan.ModelID) + result, err := s.accountTestSvc.RunTestBackground(ctx, plan.AccountID, plan.ModelID) if err != nil { logger.LegacyPrintf("service.scheduled_test_runner", "[ScheduledTestRunner] plan=%d RunTestBackground error: %v", plan.ID, err) return } - if err := s.scheduledSvc.SaveResult(ctx, plan.ID, plan.MaxResults, outcome); err != nil { + if err := s.scheduledSvc.SaveResult(ctx, plan.ID, plan.MaxResults, result); err != nil { logger.LegacyPrintf("service.scheduled_test_runner", "[ScheduledTestRunner] plan=%d SaveResult error: %v", plan.ID, err) } diff --git a/backend/internal/service/scheduled_test_service.go b/backend/internal/service/scheduled_test_service.go index 8f850c54..c9bb3b6a 100644 --- a/backend/internal/service/scheduled_test_service.go +++ b/backend/internal/service/scheduled_test_service.go @@ -77,16 +77,8 @@ func (s *ScheduledTestService) ListResults(ctx context.Context, planID int64, li } // SaveResult inserts a result and prunes old entries beyond maxResults. -func (s *ScheduledTestService) SaveResult(ctx context.Context, planID int64, maxResults int, outcome *ScheduledTestOutcome) error { - result := &ScheduledTestResult{ - PlanID: planID, - Status: outcome.Status, - ResponseText: outcome.ResponseText, - ErrorMessage: outcome.ErrorMessage, - LatencyMs: outcome.LatencyMs, - StartedAt: outcome.StartedAt, - FinishedAt: outcome.FinishedAt, - } +func (s *ScheduledTestService) SaveResult(ctx context.Context, planID int64, maxResults int, result *ScheduledTestResult) error { + result.PlanID = planID if _, err := s.resultRepo.Create(ctx, result); err != nil { return err } diff --git a/frontend/src/components/admin/account/ScheduledTestsPanel.vue b/frontend/src/components/admin/account/ScheduledTestsPanel.vue index 5e7d43ea..423ad3ba 100644 --- a/frontend/src/components/admin/account/ScheduledTestsPanel.vue +++ b/frontend/src/components/admin/account/ScheduledTestsPanel.vue @@ -469,8 +469,8 @@ const handleCreate = async () => { const maxResults = Number(newPlan.max_results) || 100 await adminAPI.scheduledTests.create({ account_id: props.accountId, - model_id: String(newPlan.model_id), - cron_expression: String(newPlan.cron_expression), + model_id: newPlan.model_id, + cron_expression: newPlan.cron_expression, enabled: newPlan.enabled, max_results: maxResults }) @@ -515,8 +515,8 @@ const handleEdit = async () => { updating.value = true try { const updated = await adminAPI.scheduledTests.update(editingPlanId.value, { - model_id: String(editForm.model_id), - cron_expression: String(editForm.cron_expression), + model_id: editForm.model_id, + cron_expression: editForm.cron_expression, max_results: Number(editForm.max_results) || 100, enabled: editForm.enabled })