From dd3ebd6a9efd66883c43a2a15b0bebe2fc6c06c8 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Thu, 20 Nov 2025 19:41:30 -0500 Subject: [PATCH 01/12] Completed Upload misc. files and associate them with MCAPS --- cloud_webserver_v2/docker-compose.yml | 2 +- .../database/usecase/vehicle_run_usecase.go | 20 +++++++++ .../internal/delivery/http/mcap_handler.go | 45 +++++++++++++++++++ .../internal/models/vehicle_run_model.go | 7 +++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/cloud_webserver_v2/docker-compose.yml b/cloud_webserver_v2/docker-compose.yml index 6b4b71e..1fc22af 100644 --- a/cloud_webserver_v2/docker-compose.yml +++ b/cloud_webserver_v2/docker-compose.yml @@ -17,4 +17,4 @@ services: volumes: run_metadata: matlab_mps_data: - external: true + diff --git a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go index 58cdf89..33581f4 100644 --- a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go +++ b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go @@ -116,3 +116,23 @@ func (uc *VehicleRunUseCase) DeleteVehicleRunById(ctx context.Context, id primit func (uc *VehicleRunUseCase) UpdateVehicleRun(ctx context.Context, id primitive.ObjectID, model *models.VehicleRunModel) error { return uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, id, model) } + +func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primitive.ObjectID, awsBucket string, fileName string, filePath string) (*models.VehicleRunModel, error) { + vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID) + if err != nil { + return nil, err + } + miscFile := models.FileModel{ + AwsBucket: awsBucket, + FilePath: filePath, + FileName: fileName, + } + vehicleRun.MiscFiles = append(vehicleRun.MiscFiles, miscFile) + err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) + if err != nil { + return nil, err + } + return vehicleRun, nil +} + + diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index cfe8184..d57fb30 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -1,6 +1,7 @@ package http import ( + "context" "fmt" "log" "net/http" @@ -62,9 +63,53 @@ func NewMcapHandler( r.Get("/{id}/process", HandlerFunc(handler.ProcessMatlabJob).ServeHTTP) r.Post("/{id}/updateMetadataRecords", HandlerFunc(handler.UpdateMetadataRecordFromID).ServeHTTP) r.Delete("/{id}/resetMetaDataRecord/{metadata}", HandlerFunc(handler.ResetMetadataRecordFromID).ServeHTTP) + r.Post("/{id}/addMiscFiles", handler.UploadNewMiscFile) }) } +// Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to +// update MongoDB +func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) { + err := r.ParseMultipartForm(32 << 20) + if err != nil { + http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) + return + } + file, header, err := r.FormFile("file") + if err != nil { + http.Error(w, "Could not read file from request", http.StatusBadRequest) + return + } + defer file.Close() + + idStr := chi.URLParam(r, "id") + vehicleRunID, err := primitive.ObjectIDFromHex(idStr) + if err != nil { + http.Error(w, "Invalid vehicle run ID", http.StatusBadRequest) + return + } + + ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + defer cancel() + s3Key := fmt.Sprintf("%s/%s", vehicleRunID.Hex(), header.Filename) + err = h.s3Repository.WriteObjectReader(ctx, file, s3Key) + if err != nil { + http.Error(w, "Failed to upload to S3: "+err.Error(), http.StatusInternalServerError) + return + } + + vehicleRun, err := h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key) + if err != nil { + http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) + return + } + response := map[string]interface{}{ + "message": "Misc file uploaded successfully", + "data": vehicleRun, + } + render.JSON(w, r, response) +} + // GetMcapsFromFilters takes in filters through Query parameters and will respond with a // map with a message and data field where data contains the filtered MCAPs func (h *mcapHandler) GetMcapsFromFilters(w http.ResponseWriter, r *http.Request) { diff --git a/cloud_webserver_v2/internal/models/vehicle_run_model.go b/cloud_webserver_v2/internal/models/vehicle_run_model.go index 878258c..a455544 100644 --- a/cloud_webserver_v2/internal/models/vehicle_run_model.go +++ b/cloud_webserver_v2/internal/models/vehicle_run_model.go @@ -59,6 +59,7 @@ type VehicleRunModel struct { Date time.Time `bson:"date"` MatFiles []FileModel `bson:"mat_files,omitempty"` MpsRecord MpsRecordModel `bson:"mps_record,omitempty"` + MiscFiles []FileModel `bson:"misc_files,omitempty"` } type VehicleRunModelResponse struct { @@ -74,6 +75,8 @@ type VehicleRunModelResponse struct { EventType *string `json:"event_type"` DynamicFields map[string]interface{} `json:"dynamic_fields"` MpsRecord MpsRecordModel `json:"mps_record"` + MiscFiles []FileModelResponse `json:"misc_files"` + } func VehicleRunSerialize(ctx context.Context, s3Repo *s3.S3Repository, model VehicleRunModel) VehicleRunModelResponse { @@ -107,6 +110,10 @@ func VehicleRunSerialize(ctx context.Context, s3Repo *s3.S3Repository, model Veh modelOut.ContentFiles[key] = fileResponses } } + if model.MiscFiles != nil && len(model.MiscFiles) > 0 { + miscResponses := getFileModelResponse(ctx, s3Repo, model.MiscFiles) + modelOut.MiscFiles = miscResponses + } return modelOut } From a1ece81d5dec65782d6ca5a52a5d0ef94972f8f4 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Thu, 20 Nov 2025 19:46:28 -0500 Subject: [PATCH 02/12] Put external back in --- cloud_webserver_v2/docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/cloud_webserver_v2/docker-compose.yml b/cloud_webserver_v2/docker-compose.yml index 1fc22af..64b2078 100644 --- a/cloud_webserver_v2/docker-compose.yml +++ b/cloud_webserver_v2/docker-compose.yml @@ -17,4 +17,5 @@ services: volumes: run_metadata: matlab_mps_data: + external: true From 3d21b1dad1ed9cbcedc68392db22e93f6953666c Mon Sep 17 00:00:00 2001 From: janista-ng Date: Thu, 20 Nov 2025 19:49:27 -0500 Subject: [PATCH 03/12] Fix --- cloud_webserver_v2/docker-compose.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cloud_webserver_v2/docker-compose.yml b/cloud_webserver_v2/docker-compose.yml index 64b2078..ea5e2bc 100644 --- a/cloud_webserver_v2/docker-compose.yml +++ b/cloud_webserver_v2/docker-compose.yml @@ -17,5 +17,4 @@ services: volumes: run_metadata: matlab_mps_data: - external: true - + external: true \ No newline at end of file From f8eb14e991353c2823c8b0726f4bcc50dbd47127 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Thu, 20 Nov 2025 19:56:52 -0500 Subject: [PATCH 04/12] format files --- .../database/usecase/vehicle_run_usecase.go | 22 ++++---- .../internal/delivery/http/mcap_handler.go | 56 +++++++++---------- .../internal/models/vehicle_run_model.go | 5 +- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go index 33581f4..6e8866d 100644 --- a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go +++ b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go @@ -118,21 +118,19 @@ func (uc *VehicleRunUseCase) UpdateVehicleRun(ctx context.Context, id primitive. } func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primitive.ObjectID, awsBucket string, fileName string, filePath string) (*models.VehicleRunModel, error) { - vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID) - if err != nil { - return nil, err - } + vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID) + if err != nil { + return nil, err + } miscFile := models.FileModel{ AwsBucket: awsBucket, FilePath: filePath, FileName: fileName, } - vehicleRun.MiscFiles = append(vehicleRun.MiscFiles, miscFile) - err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) - if err != nil { - return nil, err - } - return vehicleRun, nil + vehicleRun.MiscFiles = append(vehicleRun.MiscFiles, miscFile) + err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) + if err != nil { + return nil, err + } + return vehicleRun, nil } - - diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index d57fb30..649e0bf 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -67,31 +67,31 @@ func NewMcapHandler( }) } -// Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to +// Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to // update MongoDB func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) { - err := r.ParseMultipartForm(32 << 20) - if err != nil { - http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) - return - } + err := r.ParseMultipartForm(32 << 20) + if err != nil { + http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) + return + } file, header, err := r.FormFile("file") - if err != nil { - http.Error(w, "Could not read file from request", http.StatusBadRequest) - return - } - defer file.Close() - + if err != nil { + http.Error(w, "Could not read file from request", http.StatusBadRequest) + return + } + defer file.Close() + idStr := chi.URLParam(r, "id") - vehicleRunID, err := primitive.ObjectIDFromHex(idStr) - if err != nil { - http.Error(w, "Invalid vehicle run ID", http.StatusBadRequest) - return - } - - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + vehicleRunID, err := primitive.ObjectIDFromHex(idStr) + if err != nil { + http.Error(w, "Invalid vehicle run ID", http.StatusBadRequest) + return + } + + ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() - s3Key := fmt.Sprintf("%s/%s", vehicleRunID.Hex(), header.Filename) + s3Key := fmt.Sprintf("%s/%s", vehicleRunID.Hex(), header.Filename) err = h.s3Repository.WriteObjectReader(ctx, file, s3Key) if err != nil { http.Error(w, "Failed to upload to S3: "+err.Error(), http.StatusInternalServerError) @@ -99,15 +99,15 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) } vehicleRun, err := h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key) - if err != nil { - http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) - return - } + if err != nil { + http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) + return + } response := map[string]interface{}{ - "message": "Misc file uploaded successfully", - "data": vehicleRun, - } - render.JSON(w, r, response) + "message": "Misc file uploaded successfully", + "data": vehicleRun, + } + render.JSON(w, r, response) } // GetMcapsFromFilters takes in filters through Query parameters and will respond with a diff --git a/cloud_webserver_v2/internal/models/vehicle_run_model.go b/cloud_webserver_v2/internal/models/vehicle_run_model.go index a455544..a803529 100644 --- a/cloud_webserver_v2/internal/models/vehicle_run_model.go +++ b/cloud_webserver_v2/internal/models/vehicle_run_model.go @@ -59,7 +59,7 @@ type VehicleRunModel struct { Date time.Time `bson:"date"` MatFiles []FileModel `bson:"mat_files,omitempty"` MpsRecord MpsRecordModel `bson:"mps_record,omitempty"` - MiscFiles []FileModel `bson:"misc_files,omitempty"` + MiscFiles []FileModel `bson:"misc_files,omitempty"` } type VehicleRunModelResponse struct { @@ -75,8 +75,7 @@ type VehicleRunModelResponse struct { EventType *string `json:"event_type"` DynamicFields map[string]interface{} `json:"dynamic_fields"` MpsRecord MpsRecordModel `json:"mps_record"` - MiscFiles []FileModelResponse `json:"misc_files"` - + MiscFiles []FileModelResponse `json:"misc_files"` } func VehicleRunSerialize(ctx context.Context, s3Repo *s3.S3Repository, model VehicleRunModel) VehicleRunModelResponse { From a497879e4839c09725552df97ce197d56cc174f9 Mon Sep 17 00:00:00 2001 From: Ryan Lau <47727459+ryanlau@users.noreply.github.com> Date: Sat, 22 Nov 2025 11:35:46 -0500 Subject: [PATCH 05/12] undo docker compose changes --- cloud_webserver_v2/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_webserver_v2/docker-compose.yml b/cloud_webserver_v2/docker-compose.yml index ea5e2bc..6b4b71e 100644 --- a/cloud_webserver_v2/docker-compose.yml +++ b/cloud_webserver_v2/docker-compose.yml @@ -17,4 +17,4 @@ services: volumes: run_metadata: matlab_mps_data: - external: true \ No newline at end of file + external: true From da87e68b6e639d101a31297ebd71343d7ce19aee Mon Sep 17 00:00:00 2001 From: janista-ng Date: Sun, 18 Jan 2026 16:41:35 -0500 Subject: [PATCH 06/12] Changes MiscFiles to ContentFiles --- .../internal/database/usecase/vehicle_run_usecase.go | 5 ++++- cloud_webserver_v2/internal/models/vehicle_run_model.go | 6 ------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go index 6e8866d..7fb1a76 100644 --- a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go +++ b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go @@ -127,7 +127,10 @@ func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primi FilePath: filePath, FileName: fileName, } - vehicleRun.MiscFiles = append(vehicleRun.MiscFiles, miscFile) + if vehicleRun.ContentFiles["misc_files"] == nil { + vehicleRun.ContentFiles["misc_files"] = []models.FileModel{} + } + vehicleRun.ContentFiles["misc_files"] = append(vehicleRun.ContentFiles["misc_files"], miscFile) err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) if err != nil { return nil, err diff --git a/cloud_webserver_v2/internal/models/vehicle_run_model.go b/cloud_webserver_v2/internal/models/vehicle_run_model.go index a803529..878258c 100644 --- a/cloud_webserver_v2/internal/models/vehicle_run_model.go +++ b/cloud_webserver_v2/internal/models/vehicle_run_model.go @@ -59,7 +59,6 @@ type VehicleRunModel struct { Date time.Time `bson:"date"` MatFiles []FileModel `bson:"mat_files,omitempty"` MpsRecord MpsRecordModel `bson:"mps_record,omitempty"` - MiscFiles []FileModel `bson:"misc_files,omitempty"` } type VehicleRunModelResponse struct { @@ -75,7 +74,6 @@ type VehicleRunModelResponse struct { EventType *string `json:"event_type"` DynamicFields map[string]interface{} `json:"dynamic_fields"` MpsRecord MpsRecordModel `json:"mps_record"` - MiscFiles []FileModelResponse `json:"misc_files"` } func VehicleRunSerialize(ctx context.Context, s3Repo *s3.S3Repository, model VehicleRunModel) VehicleRunModelResponse { @@ -109,10 +107,6 @@ func VehicleRunSerialize(ctx context.Context, s3Repo *s3.S3Repository, model Veh modelOut.ContentFiles[key] = fileResponses } } - if model.MiscFiles != nil && len(model.MiscFiles) > 0 { - miscResponses := getFileModelResponse(ctx, s3Repo, model.MiscFiles) - modelOut.MiscFiles = miscResponses - } return modelOut } From 674867a7c6ad9576ef20e015ec4754dff18bfdbb Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 28 Jan 2026 19:46:28 -0500 Subject: [PATCH 07/12] resolved fixes --- .../database/usecase/vehicle_run_usecase.go | 17 ++++++++++++++++- .../internal/delivery/http/mcap_handler.go | 13 ++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go index 7fb1a76..11b06b2 100644 --- a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go +++ b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go @@ -129,7 +129,7 @@ func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primi } if vehicleRun.ContentFiles["misc_files"] == nil { vehicleRun.ContentFiles["misc_files"] = []models.FileModel{} - } + } vehicleRun.ContentFiles["misc_files"] = append(vehicleRun.ContentFiles["misc_files"], miscFile) err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) if err != nil { @@ -137,3 +137,18 @@ func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primi } return vehicleRun, nil } + +func (uc *VehicleRunUseCase) FileNameExists(ctx context.Context, vehicleRunID primitive.ObjectID, fileName string) (bool, error) { + vehicleRun, err := uc.vechicleRunRepo.GetVehicleRunFromId(ctx, vehicleRunID) + if err != nil { + return true, err + } + if vehicleRun.ContentFiles["misc_files"] != nil { + for _, f := range vehicleRun.ContentFiles["misc_files"] { + if f.FileName == fileName { + return true, nil + } + } + } + return false, nil +} diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index 649e0bf..f13d2ae 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -91,21 +91,28 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() - s3Key := fmt.Sprintf("%s/%s", vehicleRunID.Hex(), header.Filename) + s3Key := fmt.Sprintf("%s/miscFiles/%s", vehicleRunID.Hex(), header.Filename) + exists, err := h.dbClient.VehicleRunUseCase().FileNameExists(ctx, vehicleRunID, header.Filename) + if (err != nil) { + http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) + } + if (exists) { + http.Error(w, "File name already exists, duplicate file names not allowed", http.StatusNotAcceptable) + return + } err = h.s3Repository.WriteObjectReader(ctx, file, s3Key) if err != nil { http.Error(w, "Failed to upload to S3: "+err.Error(), http.StatusInternalServerError) return } - vehicleRun, err := h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key) + _, err = h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key) if err != nil { http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) return } response := map[string]interface{}{ "message": "Misc file uploaded successfully", - "data": vehicleRun, } render.JSON(w, r, response) } From f5eef1a8c17bc492bb09cc470d33b49fc2e87e0a Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 28 Jan 2026 19:53:46 -0500 Subject: [PATCH 08/12] ran go format --- .../internal/database/usecase/vehicle_run_usecase.go | 2 +- cloud_webserver_v2/internal/delivery/http/mcap_handler.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go index 11b06b2..4a42c1a 100644 --- a/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go +++ b/cloud_webserver_v2/internal/database/usecase/vehicle_run_usecase.go @@ -129,7 +129,7 @@ func (uc *VehicleRunUseCase) AddMiscFile(ctx context.Context, vehicleRunID primi } if vehicleRun.ContentFiles["misc_files"] == nil { vehicleRun.ContentFiles["misc_files"] = []models.FileModel{} - } + } vehicleRun.ContentFiles["misc_files"] = append(vehicleRun.ContentFiles["misc_files"], miscFile) err = uc.vechicleRunRepo.UpdateVehicleRunFromId(ctx, vehicleRunID, vehicleRun) if err != nil { diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index f13d2ae..e4fbef0 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -93,10 +93,10 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) defer cancel() s3Key := fmt.Sprintf("%s/miscFiles/%s", vehicleRunID.Hex(), header.Filename) exists, err := h.dbClient.VehicleRunUseCase().FileNameExists(ctx, vehicleRunID, header.Filename) - if (err != nil) { + if err != nil { http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) } - if (exists) { + if exists { http.Error(w, "File name already exists, duplicate file names not allowed", http.StatusNotAcceptable) return } From f006edd8736ce83846d9d84cd3c6253c3ee960e4 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 28 Jan 2026 19:57:51 -0500 Subject: [PATCH 09/12] removed context import --- cloud_webserver_v2/internal/delivery/http/mcap_handler.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index e4fbef0..c026a9c 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -1,7 +1,6 @@ package http import ( - "context" "fmt" "log" "net/http" @@ -70,6 +69,7 @@ func NewMcapHandler( // Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to // update MongoDB func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() err := r.ParseMultipartForm(32 << 20) if err != nil { http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) @@ -89,8 +89,6 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) - defer cancel() s3Key := fmt.Sprintf("%s/miscFiles/%s", vehicleRunID.Hex(), header.Filename) exists, err := h.dbClient.VehicleRunUseCase().FileNameExists(ctx, vehicleRunID, header.Filename) if err != nil { From f5e02c216bab072d5217a705ebc1073100d90ff6 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 4 Feb 2026 20:22:39 -0500 Subject: [PATCH 10/12] fixes 2/4 --- .../internal/delivery/http/mcap_handler.go | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index c026a9c..1ba8b63 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -62,57 +62,52 @@ func NewMcapHandler( r.Get("/{id}/process", HandlerFunc(handler.ProcessMatlabJob).ServeHTTP) r.Post("/{id}/updateMetadataRecords", HandlerFunc(handler.UpdateMetadataRecordFromID).ServeHTTP) r.Delete("/{id}/resetMetaDataRecord/{metadata}", HandlerFunc(handler.ResetMetadataRecordFromID).ServeHTTP) - r.Post("/{id}/addMiscFiles", handler.UploadNewMiscFile) + r.Post("/{id}/addMiscFile", HandlerFunc(handler.UploadNewMiscFile).ServeHTTP) }) } // Retrieves misc files uploaded from request, calls S3 usecase to update S3, & calls vehicle run usecase to // update MongoDB -func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) { +func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) *HandlerError { ctx := r.Context() err := r.ParseMultipartForm(32 << 20) if err != nil { - http.Error(w, "Failed to parse multipart form", http.StatusBadRequest) - return + return NewHandlerError(fmt.Sprintf("Failed to parse multipart form"), http.StatusBadRequest) } file, header, err := r.FormFile("file") if err != nil { - http.Error(w, "Could not read file from request", http.StatusBadRequest) - return + return NewHandlerError(fmt.Sprintf("Could not read file from request"), http.StatusBadRequest) } defer file.Close() idStr := chi.URLParam(r, "id") vehicleRunID, err := primitive.ObjectIDFromHex(idStr) if err != nil { - http.Error(w, "Invalid vehicle run ID", http.StatusBadRequest) - return + return NewHandlerError(fmt.Sprint("Invalid vehicle run ID"), http.StatusBadRequest) } s3Key := fmt.Sprintf("%s/miscFiles/%s", vehicleRunID.Hex(), header.Filename) exists, err := h.dbClient.VehicleRunUseCase().FileNameExists(ctx, vehicleRunID, header.Filename) if err != nil { - http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) + return NewHandlerError(fmt.Sprintf("Failed to save misc file to vehicle run: "+err.Error()), http.StatusInternalServerError) } if exists { - http.Error(w, "File name already exists, duplicate file names not allowed", http.StatusNotAcceptable) - return + return NewHandlerError(fmt.Sprintf("File name already exists, duplicate file names not allowed"), http.StatusNotAcceptable) } err = h.s3Repository.WriteObjectReader(ctx, file, s3Key) if err != nil { - http.Error(w, "Failed to upload to S3: "+err.Error(), http.StatusInternalServerError) - return + return NewHandlerError(fmt.Sprintf("Failed to upload to S3: "+err.Error()), http.StatusInternalServerError) } _, err = h.dbClient.VehicleRunUseCase().AddMiscFile(ctx, vehicleRunID, h.s3Repository.Bucket(), header.Filename, s3Key) if err != nil { - http.Error(w, "Failed to save misc file to vehicle run: "+err.Error(), http.StatusInternalServerError) - return + return NewHandlerError(fmt.Sprintf("Failed to save misc file to vehicle run: "+err.Error()), http.StatusInternalServerError) } response := map[string]interface{}{ "message": "Misc file uploaded successfully", } render.JSON(w, r, response) + return nil } // GetMcapsFromFilters takes in filters through Query parameters and will respond with a From f614d7858cc3f7faf5a480279cd6a9653363e469 Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 4 Feb 2026 21:17:48 -0500 Subject: [PATCH 11/12] DeleteMiscFiles --- .../internal/delivery/http/mcap_handler.go | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index 1ba8b63..d1fa579 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -63,6 +63,7 @@ func NewMcapHandler( r.Post("/{id}/updateMetadataRecords", HandlerFunc(handler.UpdateMetadataRecordFromID).ServeHTTP) r.Delete("/{id}/resetMetaDataRecord/{metadata}", HandlerFunc(handler.ResetMetadataRecordFromID).ServeHTTP) r.Post("/{id}/addMiscFile", HandlerFunc(handler.UploadNewMiscFile).ServeHTTP) + r.Delete("{id}/miscFiles/{fileName}", HandlerFunc(handler.DeleteMiscFile).ServeHTTP) }) } @@ -72,11 +73,11 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) ctx := r.Context() err := r.ParseMultipartForm(32 << 20) if err != nil { - return NewHandlerError(fmt.Sprintf("Failed to parse multipart form"), http.StatusBadRequest) + 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) + return NewHandlerError(fmt.Sprintf("Could not read file from request"), http.StatusBadRequest) } defer file.Close() @@ -110,6 +111,49 @@ func (h *mcapHandler) UploadNewMiscFile(w http.ResponseWriter, r *http.Request) return nil } +func (h *mcapHandler) DeleteMiscFile(w http.ResponseWriter, r *http.Request) *HandlerError { + ctx := r.Context() + id := chi.URLParam(r, "id") + vehicleRunID, err := primitive.ObjectIDFromHex(id) + if err != nil { + return NewHandlerError(fmt.Sprintf("Could not decode MCAP id %v, %v", id, err), http.StatusInternalServerError) + } + fileName := chi.URLParam(r, "fileName") + vehicleRun, err := h.dbClient.VehicleRunUseCase().GetVehicleRunById(ctx, vehicleRunID) + if err != nil { + if err.Error() == "mongo: no documents in result" { + return NewHandlerError(fmt.Sprintf("no run with id %v found", id), http.StatusNotFound) + } + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + var targetFile *models.FileModel + for _, f := range vehicleRun.ContentFiles["misc_files"] { + if f.FileName == fileName { + targetFile = &f + break + } + } + if targetFile == nil { + return NewHandlerError(fmt.Sprintf("File does not exist to be deleted"), http.StatusBadRequest) + } + err = h.s3Repository.DeleteObject(ctx, targetFile.AwsBucket, targetFile.FilePath) + if err != nil { + return NewHandlerError(err.Error(), http.StatusInternalServerError) + } + updatedFiles := make([]models.FileModel, 0) + for _, f := range vehicleRun.ContentFiles["misc_files"] { + if f.FileName != fileName { + updatedFiles = append(updatedFiles, f) + } + } + vehicleRun.ContentFiles["misc_files"] = updatedFiles + err = h.dbClient.VehicleRunUseCase().UpdateVehicleRun(ctx, vehicleRunID, vehicleRun) + if err != nil { + return NewHandlerError(fmt.Sprintf("Failed to update vehicle run"), http.StatusInternalServerError) + } + return nil +} + // GetMcapsFromFilters takes in filters through Query parameters and will respond with a // map with a message and data field where data contains the filtered MCAPs func (h *mcapHandler) GetMcapsFromFilters(w http.ResponseWriter, r *http.Request) { From 8fc331afadb57a000d93a7576bb3ea1e720261ab Mon Sep 17 00:00:00 2001 From: janista-ng Date: Wed, 4 Feb 2026 21:38:33 -0500 Subject: [PATCH 12/12] Fixes --- cloud_webserver_v2/internal/delivery/http/mcap_handler.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go index d1fa579..36e06ba 100644 --- a/cloud_webserver_v2/internal/delivery/http/mcap_handler.go +++ b/cloud_webserver_v2/internal/delivery/http/mcap_handler.go @@ -63,7 +63,7 @@ func NewMcapHandler( r.Post("/{id}/updateMetadataRecords", HandlerFunc(handler.UpdateMetadataRecordFromID).ServeHTTP) r.Delete("/{id}/resetMetaDataRecord/{metadata}", HandlerFunc(handler.ResetMetadataRecordFromID).ServeHTTP) r.Post("/{id}/addMiscFile", HandlerFunc(handler.UploadNewMiscFile).ServeHTTP) - r.Delete("{id}/miscFiles/{fileName}", HandlerFunc(handler.DeleteMiscFile).ServeHTTP) + r.Delete("/{id}/deleteMiscFile/{fileName}", HandlerFunc(handler.DeleteMiscFile).ServeHTTP) }) } @@ -151,6 +151,10 @@ func (h *mcapHandler) DeleteMiscFile(w http.ResponseWriter, r *http.Request) *Ha if err != nil { return NewHandlerError(fmt.Sprintf("Failed to update vehicle run"), http.StatusInternalServerError) } + response := map[string]interface{}{ + "message": "Misc file deleted successfully", + } + render.JSON(w, r, response) return nil }