Files
test_deploy/internal/http/submission.go
Alex Shevchuk d84487d238 1
2025-08-18 17:12:04 +03:00

376 lines
10 KiB
Go

package http_router
import (
"context"
"encoding/json"
"errors"
"log/slog"
"net/http"
"strings"
"time"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/integration"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/types"
"github.com/gorilla/mux"
filemanager "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/file_manager"
rmodel "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/request_model"
)
func (h *handler) getSubmissionListAgentHandler(w http.ResponseWriter, r *http.Request) {
const handlerName = "getSubmissionListAgentHandler"
var (
vars = mux.Vars(r)
agentId = vars["agent_id"]
)
request, err := new(rmodel.SubmissionListGetRequest).FromQuery(r.URL.Query())
if err != nil {
http.Error(w, constants.ErrBadRequest.Error(), http.StatusBadRequest)
h.logger.Error("error parsing request: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
return
}
request.AgentId = agentId
result, err := h.agentService.GetSubmissionList(r.Context(), request)
if err != nil {
h.handleAgentError(w, err)
h.logger.Error("error getting submission list",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(result); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error encoding response",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
}
}
func (h *handler) getSubmissionCVHandler(w http.ResponseWriter, r *http.Request) {
const handlerName = "getSubmissionCVHandler"
var (
vars = mux.Vars(r)
submissionId = vars["submission_id"]
)
params := filemanager.ParameterTable{
filemanager.SubmissionIdParam: submissionId,
}
urls, err := h.fileManager.GetFilePaths(r.Context(), filemanager.CVFileType, params)
if err != nil {
if errors.Is(err, filemanager.ErrFileNotFound) {
http.Error(w, constants.ErrNotFound.Error(), http.StatusNotFound)
h.logger.Error("CV file not found",
slog.String("error", err.Error()),
slog.String("submissionId", submissionId),
slog.String("handler", handlerName))
return
}
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error while getting file URLs: ",
slog.String("error", err.Error()),
slog.String("submissionId", submissionId),
slog.String("handler", handlerName))
return
}
if len(urls) == 0 {
http.Error(w, constants.ErrNotFound.Error(), http.StatusNotFound)
h.logger.Error("No CV URLs found",
slog.String("submissionId", submissionId),
slog.String("handler", handlerName))
return
}
response := types.CVURLResponse{
URL: urls[0],
SubmissionID: submissionId,
ExpiresAt: time.Now().Add(constants.DefaultFileTTL - time.Hour),
}
h.logger.Debug("CV URL retrieved successfully",
slog.String("submissionId", submissionId),
slog.String("handler", handlerName))
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error encoding response: ",
slog.String("error", err.Error()),
slog.String("submissionId", submissionId),
slog.String("handler", handlerName))
}
}
func (h *handler) deleteSubmissionAgentHandler(w http.ResponseWriter, r *http.Request) {
const handlerName = "deleteSubmissionHandler"
var (
vars = mux.Vars(r)
submissionId = vars["submission_id"]
)
result, err := h.agentService.DeleteSubmission(r.Context(), &rmodel.SubmissionDeleteRequest{
Id: submissionId,
})
if err != nil {
h.handleAgentError(w, err)
h.logger.Error("error deleting submission",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
return
}
go func() {
if err := h.feed.CancelEvent(r.Context(), submissionId, "Отклик был удален"); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error cancelling event: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
}
}()
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(result); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error encoding response",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
}
}
func (h *handler) getSubmissionListDistributorHandler(w http.ResponseWriter, r *http.Request) {
const handlerName = "getSubmissionsDistributorHandler"
var (
vars = mux.Vars(r)
vacancyId = vars["vacancy_id"]
)
request, err := new(rmodel.SubmissionListForVacancyGetRequest).FromQuery(r.URL.Query())
if err != nil {
http.Error(w, constants.ErrBadRequest.Error(), http.StatusBadRequest)
h.logger.Error("error parsing request: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
return
}
request.VacancyId = vacancyId
result, err := h.distributorService.GetSubmissionListForVacancy(r.Context(), request)
if err != nil {
h.handleDistributorError(w, err)
h.logger.Error("error getting submissions for vacancy",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(result); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error encoding response",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
}
}
func (h *handler) updateSubmissionStatusDistributorHandler(w http.ResponseWriter, r *http.Request) {
const handlerName = "updateSubmissionStatusDistributorHandler"
var (
vars = mux.Vars(r)
submissionId = vars["submission_id"]
)
var request rmodel.SubmissionStatusUpdateRequest
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
http.Error(w, constants.ErrBadRequest.Error(), http.StatusBadRequest)
h.logger.Error("error unmarshalling request: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
return
}
request.Id = submissionId
if _, err := h.distributorService.UpdateSubmissionStatus(r.Context(), &request); err != nil {
h.handleDistributorError(w, err)
h.logger.Error("error updating submission status",
slog.String("error", err.Error()),
slog.String("handler", handlerName),
)
return
}
// TODO:
// h.createSetSubmissionStatusFeedEvent(r.Context(), distId, submissionId, status.Status, handlerName)
w.WriteHeader(http.StatusNoContent)
}
//nolint:funlen // TODO: refactor
func (h *handler) postAnketaHandler(w http.ResponseWriter, r *http.Request) {
handlerName := "postAnketaHandler"
var (
agentID = r.FormValue("agent_id")
vacancyID = r.FormValue("vacancy_id")
cvLink = r.FormValue("cv")
name = r.FormValue("name")
phone = r.FormValue("phone_number")
email = r.FormValue("email")
birthday = r.FormValue("birthday")
info = r.FormValue("info")
firstName, lastName, middleName = splitName(name)
)
result, err := h.agentService.CreateSubmission(r.Context(), &rmodel.SubmissionCreateRequest{
AgentId: agentID,
VacancyId: vacancyID,
CandidateInfo: &rmodel.CandidateInfo{
FirstName: firstName,
LastName: lastName,
MiddleName: middleName,
PhoneNumber: phone,
Email: email,
Birthday: birthday,
CvLink: &cvLink,
Resume: &info,
},
})
if err != nil {
h.handleAgentError(w, err)
h.logger.Error("error creating submission",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
return
}
file, header, err := r.FormFile("cv_file")
if err == nil {
params := filemanager.ParameterTable{
filemanager.SubmissionIdParam: result.Id,
}
if err := h.fileManager.SaveFile(
r.Context(),
filemanager.CVFileType,
file,
header,
params,
); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error saving CV to file storage: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
return
}
} else if header != nil {
// CV is provided, but there are other errors
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error while extracting CV from request: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
}
go h.createPostAnketaEvent(
context.Background(),
agentID,
result.Id,
handlerName,
)
go func() {
if err := h.integrationClient.HandleVacancyResponse(integration.HandleVacancy{
AgentId: agentID,
VacancyId: vacancyID,
SourceLid: r.URL.RawPath,
Candidate: integration.Candidate{
Id: result.Id,
Name: name,
Email: email,
Phone: phone,
Birthday: birthday,
Info: info,
CvLink: cvLink,
},
}); err != nil {
h.logger.Error("error while handling vacancy response integration",
slog.String("error", err.Error()),
slog.String("agent_id", agentID),
slog.String("vacancy_id", vacancyID),
slog.String("submission_id", result.Id),
slog.String("handler", handlerName),
)
}
}()
w.Header().Set("Content-Type", "application/json")
if err = json.NewEncoder(w).Encode(result); err != nil {
http.Error(w, constants.ErrInternalServerError.Error(), http.StatusInternalServerError)
h.logger.Error("error encoding response: ",
slog.String("error", err.Error()),
slog.String("handler", handlerName))
}
}
func splitName(name string) (string, string, string) {
var (
parts = strings.SplitN(name, " ", 3)
lastName, firstName, middleName string
)
if len(parts) > 0 {
lastName = parts[0]
}
if len(parts) > 1 {
firstName = parts[1]
}
if len(parts) > 2 {
middleName = parts[2]
}
return lastName, firstName, middleName
}