Files
ai-service/internal/httpapi/dashboard.go
2026-06-09 14:59:08 +03:00

95 lines
2.7 KiB
Go

package httpapi
import (
"net/http"
"time"
"ai-service/internal/model"
)
type dashboardResponse struct {
At time.Time `json:"at"`
Summary dashboardSummary `json:"summary"`
Stats *model.Stats `json:"stats"`
Providers providersStatusResponse `json:"providers"`
Infra infraStatusResponse `json:"infra"`
TranscriptionComparison []model.TranscriptionComparisonStat `json:"transcription_comparison"`
Jobs []*model.JobSummary `json:"jobs"`
}
type dashboardSummary struct {
Pending int64 `json:"pending"`
Running int64 `json:"running"`
Done int64 `json:"done"`
Failed int64 `json:"failed"`
Cancelled int64 `json:"cancelled"`
Total int64 `json:"total"`
}
func (s *Server) handleDashboard(w http.ResponseWriter, r *http.Request) {
now := time.Now().UTC()
ctx, cancel := contextWithTimeout(r, 12*time.Second)
defer cancel()
stats, err := s.store.Stats(ctx)
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
jobs, err := s.store.ListJobSummaries(ctx, model.JobFilter{
Statuses: []string{model.StatusFailed, model.StatusRunning},
Limit: 40,
})
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
comparison, err := s.store.TranscriptionComparison(ctx)
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
resp := dashboardResponse{
At: now,
Summary: summarizeQueues(stats),
Stats: stats,
Providers: providersStatusResponse{
At: now,
Providers: []providerStatus{
s.checkLLM(ctx),
s.checkWhisperX(ctx),
s.checkAudioLLM(ctx, "qwen2-audio", s.cfg.QwenAudioBaseURL, s.cfg.QwenAudioAPIKey, s.cfg.QwenAudioModel, s.cfg.QwenAudioTimeout),
s.checkAudioLLM(ctx, "voxtral-small", s.cfg.VoxtralBaseURL, s.cfg.VoxtralAPIKey, s.cfg.VoxtralModel, s.cfg.VoxtralTimeout),
},
},
Infra: loadInfraSnapshot(r, s.cfg),
TranscriptionComparison: comparison,
Jobs: jobs,
}
writeJSON(w, http.StatusOK, resp)
}
func summarizeQueues(stats *model.Stats) dashboardSummary {
var out dashboardSummary
if stats == nil {
return out
}
for _, row := range stats.Queues {
switch row.Status {
case model.StatusPending:
out.Pending += row.Total
case model.StatusRunning:
out.Running += row.Total
case model.StatusDone:
out.Done += row.Total
case model.StatusFailed:
out.Failed += row.Total
case model.StatusCancelled:
out.Cancelled += row.Total
}
out.Total += row.Total
}
return out
}