Files
Datarush/internal/gw/handler/review_handler.go
T
2025-12-17 11:00:50 +03:00

134 lines
3.7 KiB
Go

package handler
import (
"net/http"
"datarush/internal/gw/domain"
"datarush/internal/gw/grpc_client"
"datarush/internal/gw/utils"
reviewpb "datarush/pkg/api/review"
)
type ReviewHandler struct {
reviewClient *grpc_client.ReviewClient
}
func NewReviewHandler(reviewClient *grpc_client.ReviewClient) *ReviewHandler {
return &ReviewHandler{reviewClient: reviewClient}
}
func (h *ReviewHandler) ListSubmissionsForReview(w http.ResponseWriter, r *http.Request) {
token := getPathParam(r, "token")
pageSize := getQueryParamInt32(r, "page_size", 20)
pageToken := getQueryParamInt32(r, "page_token", 0)
statusStr := getQueryParam(r, "status")
req := &reviewpb.ListSubmissionsForReviewRequest{
Token: token,
PageSize: pageSize,
PageToken: pageToken,
}
if statusStr != "" {
status := stringToReviewStatus(statusStr)
req.Status = &status
}
resp, err := h.reviewClient.ListSubmissionsForReview(r.Context(), req)
if err != nil {
utils.RespondError(w, domain.NewUnauthorizedError("invalid review token"))
return
}
submissions := make([]domain.SubmissionSummaryResponse, len(resp.Submissions))
for i, sub := range resp.Submissions {
submissions[i] = *utils.SubmissionSummaryProtoToHTTP(sub)
}
utils.RespondJSON(w, http.StatusOK, &domain.ListSubmissionsForReviewResponse{
TotalCount: resp.TotalCount,
NextPageToken: resp.NextPageToken,
Submissions: submissions,
})
}
func (h *ReviewHandler) GetSubmissionForReview(w http.ResponseWriter, r *http.Request) {
token := getPathParam(r, "token")
submissionID := getPathParam(r, "submission_id")
submission, err := h.reviewClient.GetSubmissionForReview(r.Context(), token, submissionID)
if err != nil {
utils.RespondError(w, domain.NewNotFoundError("submission not found"))
return
}
utils.RespondJSON(w, http.StatusOK, utils.SubmissionForReviewProtoToHTTP(submission))
}
func (h *ReviewHandler) EvaluateSubmission(w http.ResponseWriter, r *http.Request) {
token := getPathParam(r, "token")
submissionID := getPathParam(r, "submission_id")
var reqBody domain.EvaluateSubmissionRequest
if err := utils.DecodeJSON(r, &reqBody); err != nil {
utils.RespondError(w, err)
return
}
marks := make([]*reviewpb.CriteriaMark, len(reqBody.Marks))
for i, m := range reqBody.Marks {
marks[i] = &reviewpb.CriteriaMark{
Slug: m.Slug,
Mark: m.Mark,
}
}
req := &reviewpb.EvaluateSubmissionRequest{
Token: token,
SubmissionId: submissionID,
EarnedPoints: reqBody.EarnedPoints,
ReviewerComment: reqBody.ReviewerComment,
Marks: marks,
}
resp, err := h.reviewClient.EvaluateSubmission(r.Context(), req)
if err != nil {
utils.RespondError(w, domain.NewInternalServerError("failed to evaluate submission"))
return
}
utils.RespondJSON(w, http.StatusOK, &domain.EvaluateSubmissionResponse{
SubmissionID: resp.SubmissionId,
FinalScore: resp.FinalScore,
NewStatus: utils.ReviewStatusToString(resp.NewStatus),
})
}
func (h *ReviewHandler) ReleaseSubmission(w http.ResponseWriter, r *http.Request) {
token := getPathParam(r, "token")
submissionID := getPathParam(r, "submission_id")
if err := h.reviewClient.ReleaseSubmission(r.Context(), token, submissionID); err != nil {
utils.RespondError(w, domain.NewInternalServerError("failed to release submission"))
return
}
w.WriteHeader(http.StatusNoContent)
}
func stringToReviewStatus(s string) reviewpb.ReviewStatus {
switch s {
case "pending":
return reviewpb.ReviewStatus_REVIEW_STATUS_PENDING
case "in_review":
return reviewpb.ReviewStatus_REVIEW_STATUS_IN_REVIEW
case "completed":
return reviewpb.ReviewStatus_REVIEW_STATUS_COMPLETED
case "rejected":
return reviewpb.ReviewStatus_REVIEW_STATUS_REJECTED
default:
return reviewpb.ReviewStatus_REVIEW_STATUS_UNSPECIFIED
}
}