package meteo import ( "bytes" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "io" "log/slog" "net/http" "time" ) type Handler struct { *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, ) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(H{ "stats": fileStats, }) } func (h *Handler) IngestExcel(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello from excel") }