package app import ( "context" "encoding/json" "errors" "net" "net/http" "strconv" "strings" "time" mysqlstorage "hyapp/services/statistics-service/internal/storage/mysql" ) type queryHTTPServer struct { repo *mysqlstorage.Repository server *http.Server listener net.Listener } func newQueryHTTPServer(addr string, repo *mysqlstorage.Repository) (*queryHTTPServer, error) { addr = strings.TrimSpace(addr) if addr == "" { return nil, nil } listener, err := net.Listen("tcp", addr) if err != nil { return nil, err } s := &queryHTTPServer{repo: repo, listener: listener} mux := http.NewServeMux() mux.HandleFunc("/internal/v1/statistics/overview", s.overview) s.server = &http.Server{Handler: mux, ReadHeaderTimeout: 2 * time.Second} return s, nil } func (s *queryHTTPServer) Run() error { if s == nil { return nil } err := s.server.Serve(s.listener) if errors.Is(err, http.ErrServerClosed) { return nil } return err } func (s *queryHTTPServer) Close(ctx context.Context) error { if s == nil { return nil } return s.server.Shutdown(ctx) } func (s *queryHTTPServer) overview(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() startMS := parseInt64(query.Get("start_ms")) endMS := parseInt64(query.Get("end_ms")) if startMS <= 0 { now := time.Now().UTC() startMS = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC).UnixMilli() } if endMS <= startMS { endMS = startMS + 24*time.Hour.Milliseconds() } overview, err := s.repo.QueryOverview(r.Context(), mysqlstorage.OverviewQuery{ AppCode: query.Get("app_code"), StartMS: startMS, EndMS: endMS, SeriesStartMS: parseInt64(query.Get("series_start_ms")), SeriesEndMS: parseInt64(query.Get("series_end_ms")), CountryID: parseInt64(query.Get("country_id")), RegionID: parseInt64(query.Get("region_id")), }) if err != nil { writeJSON(w, http.StatusInternalServerError, map[string]any{"error": err.Error()}) return } writeJSON(w, http.StatusOK, overview) } func parseInt64(value string) int64 { parsed, _ := strconv.ParseInt(strings.TrimSpace(value), 10, 64) return parsed } func writeJSON(w http.ResponseWriter, status int, payload any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(payload) }