ops_repo_window_stats.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package repository
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "github.com/Wei-Shaw/sub2api/internal/service"
  7. )
  8. func (r *opsRepository) GetWindowStats(ctx context.Context, filter *service.OpsDashboardFilter) (*service.OpsWindowStats, error) {
  9. if r == nil || r.db == nil {
  10. return nil, fmt.Errorf("nil ops repository")
  11. }
  12. if filter == nil {
  13. return nil, fmt.Errorf("nil filter")
  14. }
  15. if filter.StartTime.IsZero() || filter.EndTime.IsZero() {
  16. return nil, fmt.Errorf("start_time/end_time required")
  17. }
  18. start := filter.StartTime.UTC()
  19. end := filter.EndTime.UTC()
  20. if start.After(end) {
  21. return nil, fmt.Errorf("start_time must be <= end_time")
  22. }
  23. // Bound excessively large windows to prevent accidental heavy queries.
  24. if end.Sub(start) > 24*time.Hour {
  25. return nil, fmt.Errorf("window too large")
  26. }
  27. successCount, tokenConsumed, err := r.queryUsageCounts(ctx, filter, start, end)
  28. if err != nil {
  29. return nil, err
  30. }
  31. errorTotal, _, _, _, _, _, err := r.queryErrorCounts(ctx, filter, start, end)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return &service.OpsWindowStats{
  36. StartTime: start,
  37. EndTime: end,
  38. SuccessCount: successCount,
  39. ErrorCountTotal: errorTotal,
  40. TokenConsumed: tokenConsumed,
  41. }, nil
  42. }