package meteo import ( "bytes" "crypto/sha256" "encoding/hex" "fmt" "io" "log/slog" "net/http" "servicea/internal/app" "servicea/internal/domains" "time" ) type Handler struct { domains.BaseHandler *Service } func NewHandler(service *Service) *Handler { return &Handler{ Service: service, } } func (h *Handler) IngestCSV(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(10 << 20) if err != nil { http.Error(w, ErrParsingForm.Error(), http.StatusBadRequest) return } file, header, err := r.FormFile("file") if err != nil { http.Error(w, ErrRetrievingFile.Error(), http.StatusBadRequest) return } defer file.Close() content, err := io.ReadAll(file) if err != nil { http.Error(w, ErrReadingFile.Error(), http.StatusInternalServerError) return } hash := sha256.Sum256(content) checksum := hex.EncodeToString(hash[:]) fileStats := &FileStats{ FileChecksum: checksum, } start := time.Now() err = h.Service.IngestCSV(r.Context(), bytes.NewReader(content), fileStats) if err != nil { slog.Error(ErrCannotParseFile.Error(), "filename", header.Filename, "error", err) http.Error(w, err.Error(), http.StatusBadRequest) return } fileStats.ElapsedMS = int(time.Since(start).Milliseconds()) h.UpdateElapsedMS(r.Context(), fileStats.BatchID, fileStats.ElapsedMS) slog.Info("CSV file processed", "filename", header.Filename, "rows_inserted", fileStats.RowsInserted, "rows_rejected", fileStats.RowsRejected, "elapsed_ms", fileStats.ElapsedMS, "file_checksum", fileStats.FileChecksum, ) h.ToJSON(w, http.StatusOK, app.H{"stats": fileStats}) } func (h *Handler) IngestExcel(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello from excel") } func (h *Handler) GetMeteoData(w http.ResponseWriter, r *http.Request) { queryParams := r.URL.Query() params := GetMeteoData{ Location: queryParams.Get("city"), From: queryParams.Get("from"), To: queryParams.Get("to"), Page: h.ParamToInt(queryParams.Get("page"), 1), Limit: h.ParamToInt(queryParams.Get("limit"), 10), } if err := params.Validate(); err != nil { h.ToJSON(w, http.StatusBadRequest, app.H{"error": err.Error()}) } slog.Info("params", "params", params) }