diff --git a/internal/migrate/sql/006_ai_jobs_owner_error_stats.up.sql b/internal/migrate/sql/006_ai_jobs_owner_error_stats.up.sql new file mode 100644 index 0000000..ce944da --- /dev/null +++ b/internal/migrate/sql/006_ai_jobs_owner_error_stats.up.sql @@ -0,0 +1,3 @@ +CREATE INDEX IF NOT EXISTS ai_jobs_owner_error_stats_idx + ON ai_jobs (owner_service, task_type, model_profile, error_code, updated_at DESC) + WHERE status = 'failed'; diff --git a/internal/model/job.go b/internal/model/job.go index 3cc9b32..efe25ae 100644 --- a/internal/model/job.go +++ b/internal/model/job.go @@ -111,6 +111,7 @@ type QueueStat struct { } type ErrorStat struct { + OwnerService string `json:"owner_service,omitempty"` TaskType string `json:"task_type"` ModelProfile string `json:"model_profile"` ErrorCode string `json:"error_code"` diff --git a/internal/store/store.go b/internal/store/store.go index 9d18855..8311a7e 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -599,13 +599,13 @@ ORDER BY owner_service, task_type, model_profile, status } errorRows, err := s.pool.Query(ctx, ` -SELECT task_type, model_profile, COALESCE(NULLIF(error_code, ''), 'unknown') AS error_code, +SELECT owner_service, task_type, model_profile, COALESCE(NULLIF(error_code, ''), 'unknown') AS error_code, count(*) AS total, count(*) FILTER (WHERE updated_at > NOW() - INTERVAL '24 hours') AS last_24h FROM ai_jobs WHERE status = 'failed' -GROUP BY task_type, model_profile, COALESCE(NULLIF(error_code, ''), 'unknown') -ORDER BY last_24h DESC, total DESC +GROUP BY owner_service, task_type, model_profile, COALESCE(NULLIF(error_code, ''), 'unknown') +ORDER BY owner_service, last_24h DESC, total DESC `) if err != nil { return nil, err @@ -613,7 +613,7 @@ ORDER BY last_24h DESC, total DESC defer errorRows.Close() for errorRows.Next() { var stat model.ErrorStat - if err := errorRows.Scan(&stat.TaskType, &stat.ModelProfile, &stat.ErrorCode, &stat.Total, &stat.Last24h); err != nil { + if err := errorRows.Scan(&stat.OwnerService, &stat.TaskType, &stat.ModelProfile, &stat.ErrorCode, &stat.Total, &stat.Last24h); err != nil { return nil, err } out.Errors = append(out.Errors, stat) diff --git a/migrations/006_ai_jobs_owner_error_stats.down.sql b/migrations/006_ai_jobs_owner_error_stats.down.sql new file mode 100644 index 0000000..2031bac --- /dev/null +++ b/migrations/006_ai_jobs_owner_error_stats.down.sql @@ -0,0 +1 @@ +DROP INDEX IF EXISTS ai_jobs_owner_error_stats_idx; diff --git a/migrations/006_ai_jobs_owner_error_stats.up.sql b/migrations/006_ai_jobs_owner_error_stats.up.sql new file mode 100644 index 0000000..ce944da --- /dev/null +++ b/migrations/006_ai_jobs_owner_error_stats.up.sql @@ -0,0 +1,3 @@ +CREATE INDEX IF NOT EXISTS ai_jobs_owner_error_stats_idx + ON ai_jobs (owner_service, task_type, model_profile, error_code, updated_at DESC) + WHERE status = 'failed';