package handler import ( "net/http" "datarush/internal/gw/domain" "datarush/internal/gw/grpc_client" "datarush/internal/gw/storage" "datarush/internal/gw/utils" ) type SubmissionHandler struct { submissionClient *grpc_client.SubmissionClient s3Storage *storage.S3Storage } func NewSubmissionHandler( submissionClient *grpc_client.SubmissionClient, s3Storage *storage.S3Storage, ) *SubmissionHandler { return &SubmissionHandler{ submissionClient: submissionClient, s3Storage: s3Storage, } } func (h *SubmissionHandler) SubmitTask(w http.ResponseWriter, r *http.Request) { userID, err := getUserIDFromContext(r.Context()) if err != nil { utils.RespondError(w, domain.NewUnauthorizedError("unauthorized")) return } competitionID := getPathParam(r, "competition_id") taskID := getPathParam(r, "task_id") if err := r.ParseMultipartForm(32 << 20); err != nil { // 32 MB max utils.RespondError(w, domain.NewBadRequestError("failed to parse form")) return } file, header, err := r.FormFile("content") if err != nil { utils.RespondError(w, domain.NewBadRequestError("missing or invalid file")) return } defer file.Close() fileURL, err := h.s3Storage.UploadFile(r.Context(), file, header) if err != nil { utils.RespondError(w, domain.NewInternalServerError("failed to upload file")) return } submission, err := h.submissionClient.SubmitTask(r.Context(), userID, competitionID, taskID, fileURL) if err != nil { utils.RespondError(w, domain.NewInternalServerError("failed to submit task")) return } utils.RespondJSON(w, http.StatusCreated, &domain.SubmitTaskResponse{ SubmissionID: submission.Id, }) } func (h *SubmissionHandler) GetSubmissionHistory(w http.ResponseWriter, r *http.Request) { userID, err := getUserIDFromContext(r.Context()) if err != nil { utils.RespondError(w, domain.NewUnauthorizedError("unauthorized")) return } competitionID := getPathParam(r, "competition_id") taskID := getPathParam(r, "task_id") submissions, err := h.submissionClient.GetSubmissionsHistory(r.Context(), userID, competitionID, taskID) if err != nil { utils.RespondError(w, domain.NewInternalServerError("failed to get submission history")) return } response := make([]domain.SubmissionResponse, len(submissions)) for i, sub := range submissions { response[i] = *utils.SubmissionProtoToHTTP(sub) } utils.RespondJSON(w, http.StatusOK, &domain.SubmissionHistoryResponse{ Submissions: response, }) }