package app import ( "encoding/json" "errors" "net/http" "strconv" "task_manager/internal/domain/tasks" "task_manager/internal/domain/users" "task_manager/internal/persistance" gorilla "github.com/gorilla/mux" ) const ( api_version string = "/api/v1" ) type ErrorResponse struct { Code int `json:"code"` // Http code Message string `json:"message"` // Обычный текст ошибки Error string `json:"error"` // Машинный текст ошибки } func (rm *TaskManager) RegisterRoutes(router *gorilla.Router) { router.HandleFunc(api_version+"/user/login", rm.handleLogin).Methods(http.MethodPost) router.HandleFunc(api_version+"/user/register", rm.handleRegistrateUser).Methods(http.MethodPost) router.HandleFunc(api_version+"/user/tasks", rm.handleUserTasks).Methods(http.MethodGet) router.HandleFunc(api_version+"/user/projects", rm.handleUserProjects).Methods(http.MethodGet) router.HandleFunc(api_version+"/user/projects", rm.handleAssignUserToProject).Methods(http.MethodPost) router.HandleFunc(api_version+"/projects", rm.handleCreateProject).Methods(http.MethodPost) router.HandleFunc(api_version+"/projects", rm.handleGetProjects).Methods(http.MethodGet) router.HandleFunc(api_version+"/projects/tasks", rm.handleCreateTask).Methods(http.MethodPost) router.HandleFunc(api_version+"/projects/tasks/{task_id}", rm.handleUpdateTask).Methods(http.MethodPatch) router.HandleFunc(api_version+"/projects/sprints", rm.handleCreateSprint).Methods(http.MethodPost) router.HandleFunc(api_version+"/projects/users", rm.handleGetProjectUsers).Methods(http.MethodGet) } func (rm *TaskManager) handleLogin(w http.ResponseWriter, r *http.Request) { var input struct { Name string `json:"name"` Password string `json:"password"` } err := json.NewDecoder(r.Body).Decode(&input) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload", err) return } user, err := rm.repo.GetUser(input.Name) if err != nil || user.Password != persistance.GetMD5Hash(input.Password) { respondWithError(w, http.StatusUnauthorized, "Invalid username or password", errors.New("authentication failed")) return } respondWithJSON(w, http.StatusOK, user) } func (rm *TaskManager) handleRegistrateUser(w http.ResponseWriter, r *http.Request) { var user users.User err := json.NewDecoder(r.Body).Decode(&user) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload", err) return } err = rm.repo.AddUser(&user) if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to create user", err) return } respondWithJSON(w, http.StatusCreated, user) } func (rm *TaskManager) handleUserTasks(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("id_user") if userID == "" { respondWithError(w, http.StatusBadRequest, "Missing user ID", errors.New("id_user parameter required")) return } id, err := strconv.Atoi(userID) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid user ID", err) return } tasks, err := rm.repo.GetUserTasks(id) if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to fetch user tasks", err) return } respondWithJSON(w, http.StatusOK, tasks) } func (rm *TaskManager) handleUserProjects(w http.ResponseWriter, r *http.Request) { userID := r.URL.Query().Get("id_user") if userID == "" { respondWithError(w, http.StatusBadRequest, "Missing user ID", errors.New("id_user parameter required")) return } _, err := strconv.Atoi(userID) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid user ID", err) return } // Заглушка: здесь предполагается метод получения проектов пользователя // Для реализации необходимо будет добавить соответствующий метод в репозиторий projects := []string{"Project 1", "Project 2"} // Пример данных respondWithJSON(w, http.StatusOK, projects) } func (rm *TaskManager) handleAssignUserToProject(w http.ResponseWriter, r *http.Request) { var input struct { IdUser int `json:"id_user"` IdProject int `json:"id_project"` } err := json.NewDecoder(r.Body).Decode(&input) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload", err) return } // Заглушка: реализация привязки пользователя к проекту // Для добавления необходимо доработать метод в репозитории respondWithJSON(w, http.StatusOK, map[string]string{ "message": "User assigned to project successfully", }) } func (rm *TaskManager) handleCreateProject(w http.ResponseWriter, r *http.Request) { respondWithJSON(w, http.StatusNotImplemented, map[string]string{ "message": "Create project not implemented yet", }) } func (rm *TaskManager) handleCreateTask(w http.ResponseWriter, r *http.Request) { var task tasks.Task err := json.NewDecoder(r.Body).Decode(&task) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload", err) return } err = rm.repo.AddTask(&task) if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to create task", err) return } respondWithJSON(w, http.StatusCreated, task) } func (rm *TaskManager) handleCreateSprint(w http.ResponseWriter, r *http.Request) { taskID := gorilla.Vars(r)["task_id"] id, err := strconv.Atoi(taskID) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid task ID", err) return } var task tasks.Task err = json.NewDecoder(r.Body).Decode(&task) if err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload", err) return } task.Id = id err = rm.repo.UpdateTask(task) if err != nil { respondWithError(w, http.StatusInternalServerError, "Failed to update task", err) return } respondWithJSON(w, http.StatusOK, task) } func (rm *TaskManager) handleGetProjectUsers(w http.ResponseWriter, r *http.Request) { respondWithJSON(w, http.StatusNotImplemented, map[string]string{ "message": "Get projects not implemented yet", }) } func (rm *TaskManager) handleUpdateTask(w http.ResponseWriter, r *http.Request) { respondWithJSON(w, http.StatusNotImplemented, map[string]string{ "message": "Create sprint not implemented yet", }) } func (rm *TaskManager) handleGetProjects(w http.ResponseWriter, r *http.Request) { respondWithJSON(w, http.StatusNotImplemented, map[string]string{ "message": "Get project users not implemented yet", }) } func respondWithError(w http.ResponseWriter, code int, message string, err error) { w.WriteHeader(code) json.NewEncoder(w).Encode(ErrorResponse{ Code: code, Message: message, Error: err.Error(), }) } func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { w.WriteHeader(code) json.NewEncoder(w).Encode(payload) }