From f66b631dc1ae8c47be48cac6eeb57cb5a79d8641 Mon Sep 17 00:00:00 2001 From: Sophia Nemes <186420664+asnems@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:32:40 -0400 Subject: [PATCH 1/2] store foxglove configs --- cloud_webserver_v2/docker-compose.yml | 1 - .../internal/database/database.go | 12 + .../repository/foxglove_configs_repository.go | 100 ++++++ .../usecase/foxglove_configs_usecase.go | 41 +++ .../delivery/http/foxglove_config_handler.go | 295 ++++++++++++++++++ .../internal/models/foxglove_configs_model.go | 33 ++ 6 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 cloud_webserver_v2/internal/database/repository/foxglove_configs_repository.go create mode 100644 cloud_webserver_v2/internal/database/usecase/foxglove_configs_usecase.go create mode 100644 cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go create mode 100644 cloud_webserver_v2/internal/models/foxglove_configs_model.go diff --git a/cloud_webserver_v2/docker-compose.yml b/cloud_webserver_v2/docker-compose.yml index 6b4b71e..848c09d 100644 --- a/cloud_webserver_v2/docker-compose.yml +++ b/cloud_webserver_v2/docker-compose.yml @@ -17,4 +17,3 @@ services: volumes: run_metadata: matlab_mps_data: - external: true diff --git a/cloud_webserver_v2/internal/database/database.go b/cloud_webserver_v2/internal/database/database.go index 680809b..4bb4329 100644 --- a/cloud_webserver_v2/internal/database/database.go +++ b/cloud_webserver_v2/internal/database/database.go @@ -18,6 +18,7 @@ type DatabaseClient struct { databaseClient *mongo.Client vehicleRunRepository repository.VehicleRunRepository carMetricsRepository repository.CarMetricsRepository + foxgloveConfigRepository repository.FoxgloveConfigRepository } const VehicleDataDatabase = "vehicle_data_db" @@ -55,6 +56,12 @@ func NewDatabaseClient(ctx context.Context, uri string) (*DatabaseClient, error) } databaseClient.carMetricsRepository = carMetricsRepository + foxgloveConfigRepository, err := repository.NewMongoFoxgloveConfigRepository(client, vehicleDataDatabase) + if err != nil { + return nil, fmt.Errorf("could not create foxgloveConfigRepository: %v", err) + } + databaseClient.foxgloveConfigRepository = foxgloveConfigRepository + return databaseClient, nil } @@ -66,6 +73,11 @@ func (client *DatabaseClient) CarMetricsUseCase() *usecase.CarMetricsUseCase { return usecase.NewCarMetricsUseCase(client.carMetricsRepository) } + +func (client *DatabaseClient)FoxgloveConfigUseCase() *usecase.FoxgloveConfigsUseCase { + return usecase.NewFoxgloveConfigsUseCase(client.foxgloveConfigRepository) +} + func (client *DatabaseClient) Disonnect(ctx context.Context) error { err := client.databaseClient.Disconnect(ctx) if err != nil { diff --git a/cloud_webserver_v2/internal/database/repository/foxglove_configs_repository.go b/cloud_webserver_v2/internal/database/repository/foxglove_configs_repository.go new file mode 100644 index 0000000..a79a412 --- /dev/null +++ b/cloud_webserver_v2/internal/database/repository/foxglove_configs_repository.go @@ -0,0 +1,100 @@ +package repository + +import ( + "context" + "fmt" + + "github.com/hytech-racing/cloud-webserver-v2/internal/models" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/primitive" + "go.mongodb.org/mongo-driver/mongo" +) + +const foxgloveConfigFileModel string = "foxglove_configs" + +// FoxgloveConfigRepository contains the methods any db implementation needs to implement to interact with foxglove configs +type FoxgloveConfigRepository interface { + GetAllFoxgloveConfigs(ctx context.Context) ([]models.FoxgloveConfigModel, error) + SaveFoxgloveConfig(ctx context.Context, foxgloveconfig models.FoxgloveConfigModel) (models.FoxgloveConfigModel, error) + GetFoxgloveConfigFromId(ctx context.Context, idStr string) (*models.FoxgloveConfigModel, error) + DeleteFoxgloveConfigFromID(ctx context.Context, id primitive.ObjectID) error +} + +// MongoFoxgloveConfigRepository conatins all the information needed to interact with a MongoDB implementation of the FoxgloveConfigs db +type MongoFoxgloveConfigRepository struct { + dbClient *mongo.Client + db *mongo.Database + collection *mongo.Collection +} + +// MongoFoxgloveConfigRepository creates a new NewMongoFoxgloveConfigRepository with a MongoDB client and database +func NewMongoFoxgloveConfigRepository(dbClient *mongo.Client, database *mongo.Database) (*MongoFoxgloveConfigRepository, error) { + collection := database.Collection(foxgloveConfigFileModel) + if collection == nil { + return nil, fmt.Errorf("could not get collection %s", foxgloveConfigFileModel) + } + + return &MongoFoxgloveConfigRepository{ + dbClient: dbClient, + db: database, + collection: collection, + }, nil +} + +// SaveFoxgloveConfig creates a new Foxglove Config document in the collection. +func (repo *MongoFoxgloveConfigRepository) SaveFoxgloveConfig(ctx context.Context, config models.FoxgloveConfigModel) (models.FoxgloveConfigModel, error) { + res, err := repo.collection.InsertOne(ctx, config) + if err != nil { + return models.FoxgloveConfigModel{}, fmt.Errorf("could not insert foxglove config: %v", err) + } + + config.Id = res.InsertedID.(primitive.ObjectID) + return config, nil +} + +// GetFoxgloveConfigFromId gets a document from the MongoDB document with its idStr +func (repo *MongoFoxgloveConfigRepository) GetFoxgloveConfigFromId(ctx context.Context, idStr string) (*models.FoxgloveConfigModel, error) { + objID, err := primitive.ObjectIDFromHex(idStr) + if err != nil { + return nil, fmt.Errorf("invalid id: %s", idStr) + } + filter := bson.M{"_id": objID} + result := repo.collection.FindOne(ctx, filter) + if result.Err() != nil { + return nil, result.Err() + } + + var model models.FoxgloveConfigModel + err = result.Decode(&model) + if err != nil { + return nil, fmt.Errorf("could not decode result into model: %v", err) + } + + return &model, err +} + +func (repo *MongoFoxgloveConfigRepository) GetAllFoxgloveConfigs(ctx context.Context) ([]models.FoxgloveConfigModel, error) { + filter := bson.M{} + cursor, err := repo.collection.Find(ctx, filter) + if err != nil { + return nil, err + } + + var config []models.FoxgloveConfigModel + if err = cursor.All(ctx, &config); err != nil { + return nil, err + } + + return config, nil +} + +// Delete a FoxgloveConfigModel from the MongoDB database from a VehicleRun ID +func (repo *MongoFoxgloveConfigRepository) DeleteFoxgloveConfigFromID(ctx context.Context, id primitive.ObjectID) error { + filter := bson.M{"_id": id} + _, err := repo.collection.DeleteOne(ctx, filter) + if err != nil { + return err + } + + return nil +} \ No newline at end of file diff --git a/cloud_webserver_v2/internal/database/usecase/foxglove_configs_usecase.go b/cloud_webserver_v2/internal/database/usecase/foxglove_configs_usecase.go new file mode 100644 index 0000000..45f1ba3 --- /dev/null +++ b/cloud_webserver_v2/internal/database/usecase/foxglove_configs_usecase.go @@ -0,0 +1,41 @@ +package usecase + +import ( + "context" + + "github.com/hytech-racing/cloud-webserver-v2/internal/database/repository" + "github.com/hytech-racing/cloud-webserver-v2/internal/models" + "go.mongodb.org/mongo-driver/bson/primitive" + +) + +type FoxgloveConfigsUseCase struct { + foxgloveConfigsRepo repository.FoxgloveConfigRepository +} + +func NewFoxgloveConfigsUseCase(foxgloveConfigsRepo repository.FoxgloveConfigRepository) *FoxgloveConfigsUseCase { + return &FoxgloveConfigsUseCase{ + foxgloveConfigsRepo, + } +} + +func (uc *FoxgloveConfigsUseCase) CreateFoxgloveConfigs(ctx context.Context, model models.FoxgloveConfigModel) (models.FoxgloveConfigModel, error) { + resModel, err := uc.foxgloveConfigsRepo.SaveFoxgloveConfig(ctx, model) + if err != nil { + return models.FoxgloveConfigModel{}, err + } + + return resModel, nil +} + +func (uc *FoxgloveConfigsUseCase) GetFoxgloveConfigFromId(ctx context.Context, id string) (*models.FoxgloveConfigModel, error) { + return uc.foxgloveConfigsRepo.GetFoxgloveConfigFromId(ctx, id) +} + +func (uc *FoxgloveConfigsUseCase) GetAllFoxgloveConfigs(ctx context.Context) ([]models.FoxgloveConfigModel, error) { + return uc.foxgloveConfigsRepo.GetAllFoxgloveConfigs(ctx) +} + +func (uc *FoxgloveConfigsUseCase) DeleteFoxgloveConfigFromId(ctx context.Context, id primitive.ObjectID) error { + return uc.foxgloveConfigsRepo.DeleteFoxgloveConfigFromID(ctx, id) +} diff --git a/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go b/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go new file mode 100644 index 0000000..2c2b277 --- /dev/null +++ b/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go @@ -0,0 +1,295 @@ +package http + +import ( + "fmt" + "log" + "net/http" + "strings" + "time" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/render" + "github.com/hytech-racing/cloud-webserver-v2/internal/background" + "github.com/hytech-racing/cloud-webserver-v2/internal/database" + hytech_middleware "github.com/hytech-racing/cloud-webserver-v2/internal/middleware" + "github.com/hytech-racing/cloud-webserver-v2/internal/models" + "github.com/hytech-racing/cloud-webserver-v2/internal/mps" + "github.com/hytech-racing/cloud-webserver-v2/internal/s3" + "go.mongodb.org/mongo-driver/bson/primitive" +) + +/* TODO: for FoxgloveConfig handler: + - [x] Add logic for parsing decoded FoxgloveConfig files + - [x] Be able to send those messages out to subscribers + - [x] Be able to write MATLAB files from the FoxgloveConfig inputs. + - [x] Store/organize those FoxgloveConfig and Matlab files in AWS S3 (waiting on drivebrain to write FoxgloveConfig files with dates/other info in metadata) + - [x] After debugging, make UploadFoxgloveConfig route quickly give response and perform task after responding + - [ ] The interpolation logic is a little flawed. More docs on that is in the bookstack. We need to fix it but it is low-priority for now. + - [ ] Once interpolation logic is fixed, write an interpolated FoxgloveConfig file with the data. +*/ + +// foxgloveConfigHandler handles all requests related to FoxgloveConfig data (uploads, deltions, edits, reading). +type foxgloveConfigHandler struct { + s3Repository *s3.S3Repository + dbClient *database.DatabaseClient + fileProcessor *background.FileProcessor +} + +func NewfoxgloveConfigHandler( + r *chi.Mux, + s3Repository *s3.S3Repository, + dbClient *database.DatabaseClient, + fileProcessor *background.FileProcessor, + fileUploadMiddleware *hytech_middleware.FileUploadMiddleware, + mpsClient *mps.MatlabClient, +) { + handler := &foxgloveConfigHandler{ + s3Repository: s3Repository, + dbClient: dbClient, + fileProcessor: fileProcessor, + } + + r.Route("/foxgloveconfigs", func(r chi.Router) { + // The FileUploadMiddleware is attached to all routes involved with uploading files + // It limits the amount of uploads we accept to a pre-set limit + r.With(fileUploadMiddleware.FileUploadSizeLimitMiddleware).Post("/upload", HandlerFunc(handler.UploadFoxgloveConfig).ServeHTTP) + r.Get("/", handler.GetFoxgloveConfigs) + r.Get("/{id}", HandlerFunc(handler.GetFoxgloveConfigFromID).ServeHTTP) + r.Delete("/{id}", HandlerFunc(handler.DeleteFoxgloveConfigFromID).ServeHTTP) + }) +} + +// GetFoxgloveConfigsFromFilters takes in filters through Query parameters and will respond with a +// map with a message and data field where data contains the filtered FoxgloveConfigs +func (h *foxgloveConfigHandler) GetFoxgloveConfigs(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + var resModels []models.FoxgloveConfigModel + var err error + + resModels, err = h.dbClient.FoxgloveConfigUseCase().GetAllFoxgloveConfigs(ctx) + + if err != nil { + log.Fatal(err) + } + + res := make([]models.FoxgloveConfigModelResponse, len(resModels)) + for idx, model := range resModels { + res[idx] = models.FoxgloveConfigSerialize(ctx, h.s3Repository, model) + } + + data := make(map[string]interface{}) + data["data"] = res + data["message"] = make(map[string]interface{}) + render.JSON(w, r, data) +} + +// GetFoxgloveConfigFromID takes in an ID from a URL param and responds with an FoxgloveConfig with that ID. +func (h *foxgloveConfigHandler) GetFoxgloveConfigFromID(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + + foxgloveconfigId := chi.URLParam(r, "id") + if foxgloveconfigId == "" { + return NewHandlerError("invalid request, must pass in foxgloveconfig id", http.StatusBadRequest) + } + + objectId, err := primitive.ObjectIDFromHex(foxgloveconfigId) + if err != nil { + return NewHandlerError(fmt.Sprintf("could not decode foxgloveconfig id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + foxgloveconfig, err := h.dbClient.VehicleRunUseCase().GetVehicleRunById(ctx, objectId) + if err != nil { + if err.Error() == "mongo: no documents in result" { + return NewHandlerError(fmt.Sprintf("no run with id %v found", foxgloveconfigId), http.StatusNotFound) + } + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + responseFoxgloveConfig := models.VehicleRunSerialize(ctx, h.s3Repository, *foxgloveconfig) + data := make([]models.VehicleRunModelResponse, 1) + data[0] = responseFoxgloveConfig + + response := make(map[string]interface{}) + response["message"] = "" + response["data"] = data + + render.JSON(w, r, response) + + return nil +} + +// UploadFoxgloveConfig allows for a single FoxgloveConfig file upload and enqueues the job in the FileProcessor +func (h *foxgloveConfigHandler) UploadFoxgloveConfig(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + err := r.ParseMultipartForm(32 << 20) + if err != nil { + return NewHandlerError(fmt.Sprintf("Failed to parse multipart form"), http.StatusBadRequest) + } + + file, header, err := r.FormFile("file") + if err != nil { + return NewHandlerError(fmt.Sprintf("Could not read file from request"), http.StatusBadRequest) + } + defer file.Close() + + s3FileName := fmt.Sprintf("foxgloveConfigs/%s", header.Filename) + err = h.s3Repository.WriteObjectReader(ctx, file, s3FileName) + if err != nil { + return NewHandlerError(fmt.Sprintf("Failed to upload to S3: "+err.Error()), http.StatusInternalServerError) + } + + response := make(map[string]interface{}) + response["message"] = "upload was successful" + + render.JSON(w, r, response) + return nil +} + +// DeleteFoxgloveConfigFromID takes in an ID from a URL param and deletes the FoxgloveConfig information from MongoDB and from S3. +func (h *foxgloveConfigHandler) DeleteFoxgloveConfigFromID(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + + foxgloveconfigId := chi.URLParam(r, "id") + if foxgloveconfigId == "" { + return NewHandlerError("invalid request, must pass in foxgloveconfig id", http.StatusBadRequest) + } + + objectId, err := primitive.ObjectIDFromHex(foxgloveconfigId) + if err != nil { + return NewHandlerError(fmt.Sprintf("could not decode mcap id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + foxgloveConfigModel, err := h.dbClient.FoxgloveConfigUseCase().GetFoxgloveConfigFromId(ctx, foxgloveconfigId) + if err != nil { + if err.Error() == "mongo: no documents in result" { + return NewHandlerError(fmt.Sprintf("no foxgloveConfig with id %v found", foxgloveconfigId), http.StatusNotFound) + } + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + + err = h.s3Repository.DeleteObject(ctx, foxgloveConfigModel.File.AwsBucket, foxgloveConfigModel.File.FilePath) + if err != nil { + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + + err = h.dbClient.FoxgloveConfigUseCase().DeleteFoxgloveConfigFromId(ctx, objectId) + if err != nil { + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + + return nil +} + +// UpdateMetadataRecordFromID takes in an ID from a URL param and formdata that determines which metadata to update in our VehicleRunModels. +func (h *foxgloveConfigHandler) UpdateMetadataRecordFromID(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + if err := r.ParseMultipartForm(10 << 20); err != nil { + return NewHandlerError("error parsing form data", http.StatusBadRequest) + } + defer r.MultipartForm.RemoveAll() + + foxgloveconfigId := chi.URLParam(r, "id") + if foxgloveconfigId == "" { + return NewHandlerError("invalid request, must pass in foxgloveconfig id", http.StatusBadRequest) + } + + objectId, err := primitive.ObjectIDFromHex(foxgloveconfigId) + if err != nil { + log.Println("getting foxgloveconfigID") + return NewHandlerError(fmt.Sprintf("could not decode foxgloveconfig id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + runModel, err := h.dbClient.VehicleRunUseCase().GetVehicleRunById(ctx, objectId) + if err != nil { + return NewHandlerError(fmt.Sprintf("could not get vehicle run by id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + for key, values := range r.Form { + if strings.HasPrefix(key, "mps.") { + // TODO: Figure out if updating MPS with an HTTP request is needed + + // mpsMetadata := make(map[string]interface{}) + // mpsMetadata[strings.TrimPrefix(key, "mps.")] = values[0] + + // if runModel.MpsRecord == nil { + // runModel.MpsRecord = make(map[string]models.MpsScripts) + // } + + // for function, record := range mpsMetadata { + // runModel.MpsRecord[function] = record + // } + } else { + switch key { + case "date": + layout := time.RFC3339 + parsedDate, err := time.Parse(layout, values[0]) + if err != nil { + return NewHandlerError(fmt.Sprintf("invalid date format: %v", err), http.StatusBadRequest) + } + runModel.Date = parsedDate + case "location": + runModel.Location = &values[0] + case "notes": + runModel.Notes = &values[0] + case "event_type": + runModel.EventType = &values[0] + case "car_model": + runModel.CarModel = values[0] + } + } + } + + err = h.dbClient.VehicleRunUseCase().UpdateVehicleRun(ctx, objectId, runModel) + if err != nil { + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + + return nil +} + +// ResetMetadataRecordFromID takes in an ID and metadata from a URL param that determines which metadata to reset in our VehicleRunModels. +func (h *foxgloveConfigHandler) ResetMetadataRecordFromID(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + foxgloveconfigId := chi.URLParam(r, "id") + if foxgloveconfigId == "" { + return NewHandlerError("invalid request, must pass in foxgloveconfig id", http.StatusBadRequest) + } + metadata := chi.URLParam(r, "metadata") + if metadata == "" { + return NewHandlerError("invalid request, must pass in foxgloveconfig id", http.StatusBadRequest) + } + objectId, err := primitive.ObjectIDFromHex(foxgloveconfigId) + if err != nil { + log.Println("getting foxgloveconfigID") + return NewHandlerError(fmt.Sprintf("could not decode foxgloveconfig id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + runModel, err := h.dbClient.VehicleRunUseCase().GetVehicleRunById(ctx, objectId) + if err != nil { + return NewHandlerError(fmt.Sprintf("could not get vehicle run by id %v, %v", foxgloveconfigId, err), http.StatusInternalServerError) + } + + switch metadata { + case "date": + runModel.Date = time.Now() + case "note": + runModel.Notes = nil + case "location": + runModel.Location = nil + case "event_type": + runModel.EventType = nil + // TODO: Figure out if updating MPS with an HTTP request is needed + // case "mps_record": + // runModel.MpsRecord = make(map[string]interface{}) + case "car_model": + runModel.CarModel = "" + default: + return NewHandlerError("invalid metadata key", http.StatusBadRequest) + } + + err = h.dbClient.VehicleRunUseCase().UpdateVehicleRun(ctx, objectId, runModel) + if err != nil { + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + return nil +} diff --git a/cloud_webserver_v2/internal/models/foxglove_configs_model.go b/cloud_webserver_v2/internal/models/foxglove_configs_model.go new file mode 100644 index 0000000..c20ea2b --- /dev/null +++ b/cloud_webserver_v2/internal/models/foxglove_configs_model.go @@ -0,0 +1,33 @@ +package models + +import ( + "go.mongodb.org/mongo-driver/bson/primitive" + "context" + + "github.com/hytech-racing/cloud-webserver-v2/internal/s3" + +) + +type FoxgloveConfigModel struct { + Id primitive.ObjectID `bson:"_id,omitempty"` + File FileModel `bson:"file,omitempty"` + // TODO: Add Information we want to track, empty for now as we haven't decided +} + +type FoxgloveConfigModelResponse struct { + Id string `json:"_id"` + File FileModelResponse `json:"file"` + // TODO: Add Information we want to track, empty for now as we haven't decided +} + +func FoxgloveConfigSerialize(ctx context.Context, s3Repo *s3.S3Repository, model FoxgloveConfigModel) FoxgloveConfigModelResponse { + modelOut := FoxgloveConfigModelResponse{ + Id: model.Id.Hex(), + } + + fileResponse := getFileModelResponse(ctx, s3Repo, []FileModel{model.File}) + // TODO: handle len(fileResponse) != 1 case + modelOut.File = fileResponse[0] + + return modelOut +} \ No newline at end of file From 384368e269909cdb1f7e3dfa18c1bf917df6de75 Mon Sep 17 00:00:00 2001 From: Sophia Nemes <186420664+asnems@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:56:42 -0400 Subject: [PATCH 2/2] store foxglove configs --- cloud_webserver_v2/cmd/cloud_webserver_v2/main.go | 1 + .../internal/delivery/http/foxglove_config_handler.go | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cloud_webserver_v2/cmd/cloud_webserver_v2/main.go b/cloud_webserver_v2/cmd/cloud_webserver_v2/main.go index 6f92325..2e53627 100644 --- a/cloud_webserver_v2/cmd/cloud_webserver_v2/main.go +++ b/cloud_webserver_v2/cmd/cloud_webserver_v2/main.go @@ -158,6 +158,7 @@ func main() { handler.NewUploadHandler(router, dbClient, fileProcessor) handler.NewDocumentationHandler(router, s3Repository) handler.NewCarMetricsHandler(router, s3Repository, dbClient) + handler.NewfoxgloveConfigHandler(router, s3Repository, dbClient, fileProcessor, &fileUploadMiddleware) // Graceful shutdown: listen for interrupt signals quit := make(chan os.Signal, 1) diff --git a/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go b/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go index 2c2b277..eec3f23 100644 --- a/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/foxglove_config_handler.go @@ -13,7 +13,6 @@ import ( "github.com/hytech-racing/cloud-webserver-v2/internal/database" hytech_middleware "github.com/hytech-racing/cloud-webserver-v2/internal/middleware" "github.com/hytech-racing/cloud-webserver-v2/internal/models" - "github.com/hytech-racing/cloud-webserver-v2/internal/mps" "github.com/hytech-racing/cloud-webserver-v2/internal/s3" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -41,7 +40,6 @@ func NewfoxgloveConfigHandler( dbClient *database.DatabaseClient, fileProcessor *background.FileProcessor, fileUploadMiddleware *hytech_middleware.FileUploadMiddleware, - mpsClient *mps.MatlabClient, ) { handler := &foxgloveConfigHandler{ s3Repository: s3Repository,