From d47498ed3bb288b3691fc5f600d151816a73410e Mon Sep 17 00:00:00 2001 From: AmirAgassi <33383085+AmirAgassi@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:35:20 -0500 Subject: [PATCH] Refactor endpoints w/ request body validator middleware --- .sqlc/queries/company_questions_answers.sql | 7 +- internal/server/company.go | 8 ++- internal/server/company_documents.go | 15 ++-- internal/server/company_financials.go | 15 ++-- internal/server/company_questions_answers.go | 37 +++++++--- internal/server/employee.go | 15 ++-- internal/server/funding_transactions.go | 15 ++-- internal/server/index.go | 67 +++++++++--------- internal/server/meetings.go | 15 ++-- internal/server/projects.go | 72 ++++++++++++++++---- internal/server/resource_request.go | 23 ++++--- internal/server/tag.go | 8 ++- 12 files changed, 195 insertions(+), 102 deletions(-) diff --git a/.sqlc/queries/company_questions_answers.sql b/.sqlc/queries/company_questions_answers.sql index 67a675c..225aa87 100644 --- a/.sqlc/queries/company_questions_answers.sql +++ b/.sqlc/queries/company_questions_answers.sql @@ -60,4 +60,9 @@ RETURNING *; -- name: SoftDeleteCompanyAnswer :exec UPDATE company_question_answers SET deleted_at = NOW() -WHERE company_id = $1 AND question_id = $2; \ No newline at end of file +WHERE company_id = $1 AND question_id = $2; + +-- name: DeleteQuestion :exec +UPDATE questions +SET deleted_at = NOW() +WHERE id = $1 AND deleted_at IS NULL; \ No newline at end of file diff --git a/internal/server/company.go b/internal/server/company.go index 2cf9d0c..83ec881 100644 --- a/internal/server/company.go +++ b/internal/server/company.go @@ -5,13 +5,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateCompany(c echo.Context) error { - var req CreateCompanyRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateCompanyRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateCompanyRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } ownerUUID, err := validateUUID(req.OwnerUserID, "owner") diff --git a/internal/server/company_documents.go b/internal/server/company_documents.go index bd4dd1b..88960ff 100644 --- a/internal/server/company_documents.go +++ b/internal/server/company_documents.go @@ -5,13 +5,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateCompanyDocument(c echo.Context) error { - var req CreateCompanyDocumentRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateCompanyDocumentRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateCompanyDocumentRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(req.CompanyID, "company") @@ -91,9 +93,10 @@ func (s *Server) handleUpdateCompanyDocument(c echo.Context) error { return err } - var req UpdateCompanyDocumentRequest - if err := validateBody(c, &req); err != nil { - return err + var req *UpdateCompanyDocumentRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateCompanyDocumentRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) diff --git a/internal/server/company_financials.go b/internal/server/company_financials.go index 26a8cd9..b8788d5 100644 --- a/internal/server/company_financials.go +++ b/internal/server/company_financials.go @@ -6,13 +6,15 @@ import ( "strconv" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateCompanyFinancials(c echo.Context) error { - var req CreateCompanyFinancialsRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateCompanyFinancialsRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateCompanyFinancialsRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(c.Param("id"), "company") @@ -84,9 +86,10 @@ func (s *Server) handleGetCompanyFinancials(c echo.Context) error { } func (s *Server) handleUpdateCompanyFinancials(c echo.Context) error { - var req CreateCompanyFinancialsRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateCompanyFinancialsRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateCompanyFinancialsRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(c.Param("id"), "company") diff --git a/internal/server/company_questions_answers.go b/internal/server/company_questions_answers.go index 11f6c64..2dfc6c1 100644 --- a/internal/server/company_questions_answers.go +++ b/internal/server/company_questions_answers.go @@ -5,13 +5,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateQuestion(c echo.Context) error { - var req CreateQuestionRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateQuestionRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateQuestionRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) @@ -54,9 +56,10 @@ func (s *Server) handleCreateCompanyAnswer(c echo.Context) error { return err } - var req CreateCompanyAnswerRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateCompanyAnswerRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateCompanyAnswerRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } questionID, err := validateUUID(req.QuestionID, "question") @@ -143,9 +146,10 @@ func (s *Server) handleUpdateCompanyAnswer(c echo.Context) error { return err } - var req UpdateCompanyAnswerRequest - if err := validateBody(c, &req); err != nil { - return err + var req *UpdateCompanyAnswerRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateCompanyAnswerRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) @@ -205,3 +209,18 @@ func (s *Server) handleDeleteCompanyAnswer(c echo.Context) error { return c.NoContent(http.StatusNoContent) } + +func (s *Server) handleDeleteQuestion(c echo.Context) error { + questionID, err := validateUUID(c.Param("id"), "question") + if err != nil { + return err + } + + queries := db.New(s.DBPool) + err = queries.SoftDeleteQuestion(context.Background(), questionID) + if err != nil { + return handleDBError(err, "delete", "question") + } + + return c.NoContent(http.StatusNoContent) +} diff --git a/internal/server/employee.go b/internal/server/employee.go index c61b38c..a9a0bc9 100644 --- a/internal/server/employee.go +++ b/internal/server/employee.go @@ -5,13 +5,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateEmployee(c echo.Context) error { - var req CreateEmployeeRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateEmployeeRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateEmployeeRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(req.CompanyID, "company") @@ -93,9 +95,10 @@ func (s *Server) handleUpdateEmployee(c echo.Context) error { return err } - var req UpdateEmployeeRequest - if err := validateBody(c, &req); err != nil { - return err + var req *UpdateEmployeeRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateEmployeeRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) diff --git a/internal/server/funding_transactions.go b/internal/server/funding_transactions.go index d0eabf3..a61a06a 100644 --- a/internal/server/funding_transactions.go +++ b/internal/server/funding_transactions.go @@ -6,13 +6,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateFundingTransaction(c echo.Context) error { - var req CreateFundingTransactionRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateFundingTransactionRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateFundingTransactionRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } projectID, err := validateUUID(req.ProjectID, "project") @@ -102,9 +104,10 @@ func (s *Server) handleUpdateFundingTransactionStatus(c echo.Context) error { return err } - var req UpdateFundingTransactionStatusRequest - if err := validateBody(c, &req); err != nil { - return err + var req *UpdateFundingTransactionStatusRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateFundingTransactionStatusRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) diff --git a/internal/server/index.go b/internal/server/index.go index 72d7520..5cc8ae2 100644 --- a/internal/server/index.go +++ b/internal/server/index.go @@ -3,6 +3,7 @@ package server import ( "fmt" "os" + "reflect" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -113,99 +114,101 @@ func (s *Server) setupV1Routes() { } func (s *Server) setupCompanyRoutes() { - s.apiV1.POST("/companies", s.handleCreateCompany) + s.apiV1.POST("/companies", s.handleCreateCompany, middleware.ValidateRequestBody(reflect.TypeOf(CreateCompanyRequest{}))) s.apiV1.GET("/companies/:id", s.handleGetCompany) s.apiV1.GET("/companies", s.handleListCompanies) s.apiV1.DELETE("/companies/:id", s.handleDeleteCompany) } func (s *Server) setupResourceRequestRoutes() { - s.apiV1.POST("/resource-requests", s.handleCreateResourceRequest) + s.apiV1.POST("/resource-requests", s.handleCreateResourceRequest, middleware.ValidateRequestBody(reflect.TypeOf(CreateResourceRequestRequest{}))) s.apiV1.GET("/resource-requests/:id", s.handleGetResourceRequest) s.apiV1.GET("/resource-requests", s.handleListResourceRequests) - s.apiV1.PUT("/resource-requests/:id/status", s.handleUpdateResourceRequestStatus) + s.apiV1.PUT("/resource-requests/:id/status", s.handleUpdateResourceRequestStatus, middleware.ValidateRequestBody(reflect.TypeOf(UpdateResourceRequestStatusRequest{}))) s.apiV1.DELETE("/resource-requests/:id", s.handleDeleteResourceRequest) } func (s *Server) setupCompanyFinancialRoutes() { - s.apiV1.POST("/companies/:id/financials", s.handleCreateCompanyFinancials) + s.apiV1.POST("/companies/:id/financials", s.handleCreateCompanyFinancials, middleware.ValidateRequestBody(reflect.TypeOf(CreateCompanyFinancialsRequest{}))) s.apiV1.GET("/companies/:id/financials", s.handleGetCompanyFinancials) - s.apiV1.PUT("/companies/:id/financials", s.handleUpdateCompanyFinancials) + s.apiV1.PUT("/companies/:id/financials", s.handleUpdateCompanyFinancials, middleware.ValidateRequestBody(reflect.TypeOf(CreateCompanyFinancialsRequest{}))) s.apiV1.DELETE("/companies/:id/financials", s.handleDeleteCompanyFinancials) s.apiV1.GET("/companies/:id/financials/latest", s.handleGetLatestCompanyFinancials) } func (s *Server) setupEmployeeRoutes() { - s.apiV1.POST("/employees", s.handleCreateEmployee) + s.apiV1.POST("/employees", s.handleCreateEmployee, middleware.ValidateRequestBody(reflect.TypeOf(CreateEmployeeRequest{}))) s.apiV1.GET("/employees", s.handleListEmployees) s.apiV1.GET("/employees/:id", s.handleGetEmployee) - s.apiV1.PUT("/employees/:id", s.handleUpdateEmployee) + s.apiV1.PUT("/employees/:id", s.handleUpdateEmployee, middleware.ValidateRequestBody(reflect.TypeOf(UpdateEmployeeRequest{}))) s.apiV1.DELETE("/employees/:id", s.handleDeleteEmployee) } func (s *Server) setupCompanyDocumentRoutes() { - s.apiV1.POST("/companies/:id/documents", s.handleCreateCompanyDocument) + s.apiV1.POST("/companies/:id/documents", s.handleCreateCompanyDocument, middleware.ValidateRequestBody(reflect.TypeOf(CreateCompanyDocumentRequest{}))) s.apiV1.GET("/companies/:id/documents", s.handleListCompanyDocuments) s.apiV1.GET("/documents/:id", s.handleGetCompanyDocument) - s.apiV1.PUT("/documents/:id", s.handleUpdateCompanyDocument) + s.apiV1.PUT("/documents/:id", s.handleUpdateCompanyDocument, middleware.ValidateRequestBody(reflect.TypeOf(UpdateCompanyDocumentRequest{}))) s.apiV1.DELETE("/documents/:id", s.handleDeleteCompanyDocument) } func (s *Server) setupCompanyQuestionsAnswersRoutes() { - s.apiV1.POST("/questions", s.handleCreateQuestion) + s.apiV1.POST("/questions", s.handleCreateQuestion, middleware.ValidateRequestBody(reflect.TypeOf(CreateQuestionRequest{}))) s.apiV1.GET("/questions", s.handleListQuestions) s.apiV1.GET("/questions/:id", s.handleGetQuestion) + s.apiV1.DELETE("/questions/:id", s.handleDeleteQuestion) - s.apiV1.POST("/companies/:id/answers", s.handleCreateCompanyAnswer) + s.apiV1.POST("/companies/:id/answers", s.handleCreateCompanyAnswer, middleware.ValidateRequestBody(reflect.TypeOf(CreateCompanyAnswerRequest{}))) s.apiV1.GET("/companies/:id/answers", s.handleListCompanyAnswers) - s.apiV1.GET("/companies/:company_id/answers/:question_id", s.handleGetCompanyAnswer) - s.apiV1.PUT("/companies/:company_id/answers/:question_id", s.handleUpdateCompanyAnswer) - s.apiV1.DELETE("/companies/:company_id/answers/:question_id", s.handleDeleteCompanyAnswer) + s.apiV1.GET("/answers/:id", s.handleGetCompanyAnswer) + s.apiV1.PUT("/answers/:id", s.handleUpdateCompanyAnswer, middleware.ValidateRequestBody(reflect.TypeOf(UpdateCompanyAnswerRequest{}))) + s.apiV1.DELETE("/answers/:id", s.handleDeleteCompanyAnswer) } func (s *Server) setupProjectRoutes() { - s.apiV1.POST("/projects", s.handleCreateProject) + s.apiV1.POST("/projects", s.handleCreateProject, middleware.ValidateRequestBody(reflect.TypeOf(CreateProjectRequest{}))) s.apiV1.GET("/projects/:id", s.handleGetProject) s.apiV1.GET("/projects", s.handleListProjects) + s.apiV1.PUT("/projects/:id", s.handleUpdateProject, middleware.ValidateRequestBody(reflect.TypeOf(UpdateProjectRequest{}))) s.apiV1.DELETE("/projects/:id", s.handleDeleteProject) - s.apiV1.POST("/projects/:project_id/files", s.handleCreateProjectFile) - s.apiV1.GET("/projects/:project_id/files", s.handleListProjectFiles) - s.apiV1.DELETE("/projects/files/:id", s.handleDeleteProjectFile) + s.apiV1.POST("/projects/:id/files", s.handleCreateProjectFile, middleware.ValidateRequestBody(reflect.TypeOf(CreateProjectFileRequest{}))) + s.apiV1.GET("/projects/:id/files", s.handleListProjectFiles) + s.apiV1.DELETE("/files/:id", s.handleDeleteProjectFile) - s.apiV1.POST("/projects/:project_id/comments", s.handleCreateProjectComment) - s.apiV1.GET("/projects/:project_id/comments", s.handleListProjectComments) - s.apiV1.DELETE("/projects/comments/:id", s.handleDeleteProjectComment) + s.apiV1.POST("/projects/:id/comments", s.handleCreateProjectComment, middleware.ValidateRequestBody(reflect.TypeOf(CreateProjectCommentRequest{}))) + s.apiV1.GET("/projects/:id/comments", s.handleListProjectComments) + s.apiV1.DELETE("/comments/:id", s.handleDeleteProjectComment) - s.apiV1.POST("/projects/:project_id/links", s.handleCreateProjectLink) - s.apiV1.GET("/projects/:project_id/links", s.handleListProjectLinks) - s.apiV1.DELETE("/projects/links/:id", s.handleDeleteProjectLink) + s.apiV1.POST("/projects/:id/links", s.handleCreateProjectLink, middleware.ValidateRequestBody(reflect.TypeOf(CreateProjectLinkRequest{}))) + s.apiV1.GET("/projects/:id/links", s.handleListProjectLinks) + s.apiV1.DELETE("/links/:id", s.handleDeleteProjectLink) - s.apiV1.POST("/projects/:project_id/tags", s.handleAddProjectTag) - s.apiV1.GET("/projects/:project_id/tags", s.handleListProjectTags) - s.apiV1.DELETE("/projects/:project_id/tags/:tag_id", s.handleDeleteProjectTag) + s.apiV1.POST("/projects/:id/tags", s.handleAddProjectTag, middleware.ValidateRequestBody(reflect.TypeOf(AddProjectTagRequest{}))) + s.apiV1.GET("/projects/:id/tags", s.handleListProjectTags) + s.apiV1.DELETE("/projects/:id/tags/:tag_id", s.handleDeleteProjectTag) } func (s *Server) setupTagRoutes() { - s.apiV1.POST("/tags", s.handleCreateTag) + s.apiV1.POST("/tags", s.handleCreateTag, middleware.ValidateRequestBody(reflect.TypeOf(CreateTagRequest{}))) s.apiV1.GET("/tags/:id", s.handleGetTag) s.apiV1.GET("/tags", s.handleListTags) s.apiV1.DELETE("/tags/:id", s.handleDeleteTag) } func (s *Server) setupFundingTransactionRoutes() { - s.apiV1.POST("/funding-transactions", s.handleCreateFundingTransaction) + s.apiV1.POST("/funding-transactions", s.handleCreateFundingTransaction, middleware.ValidateRequestBody(reflect.TypeOf(CreateFundingTransactionRequest{}))) s.apiV1.GET("/funding-transactions/:id", s.handleGetFundingTransaction) s.apiV1.GET("/funding-transactions", s.handleListFundingTransactions) - s.apiV1.PUT("/funding-transactions/:id/status", s.handleUpdateFundingTransactionStatus) + s.apiV1.PUT("/funding-transactions/:id/status", s.handleUpdateFundingTransactionStatus, middleware.ValidateRequestBody(reflect.TypeOf(UpdateFundingTransactionStatusRequest{}))) s.apiV1.DELETE("/funding-transactions/:id", s.handleDeleteFundingTransaction) } func (s *Server) setupMeetingRoutes() { - s.apiV1.POST("/meetings", s.handleCreateMeeting) + s.apiV1.POST("/meetings", s.handleCreateMeeting, middleware.ValidateRequestBody(reflect.TypeOf(CreateMeetingRequest{}))) s.apiV1.GET("/meetings/:id", s.handleGetMeeting) s.apiV1.GET("/meetings", s.handleListMeetings) - s.apiV1.PUT("/meetings/:id", s.handleUpdateMeeting) + s.apiV1.PUT("/meetings/:id", s.handleUpdateMeeting, middleware.ValidateRequestBody(reflect.TypeOf(UpdateMeetingRequest{}))) s.apiV1.DELETE("/meetings/:id", s.handleDeleteMeeting) } diff --git a/internal/server/meetings.go b/internal/server/meetings.go index 2705f02..c6ab04b 100644 --- a/internal/server/meetings.go +++ b/internal/server/meetings.go @@ -6,13 +6,15 @@ import ( "time" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateMeeting(c echo.Context) error { - var req CreateMeetingRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateMeetingRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateMeetingRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } projectID, err := validateUUID(req.ProjectID, "project") @@ -116,9 +118,10 @@ func (s *Server) handleUpdateMeeting(c echo.Context) error { return err } - var req UpdateMeetingRequest - if err := validateBody(c, &req); err != nil { - return err + var req *UpdateMeetingRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateMeetingRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } startTime, err := time.Parse(time.RFC3339, req.StartTime) diff --git a/internal/server/projects.go b/internal/server/projects.go index 9f0d1dd..deeee8e 100644 --- a/internal/server/projects.go +++ b/internal/server/projects.go @@ -6,13 +6,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateProject(c echo.Context) error { - var req CreateProjectRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateProjectRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateProjectRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(req.CompanyID, "company") @@ -112,9 +114,10 @@ func (s *Server) handleCreateProjectFile(c echo.Context) error { return err } - var req CreateProjectFileRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateProjectFileRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateProjectFileRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) @@ -173,9 +176,10 @@ func (s *Server) handleCreateProjectComment(c echo.Context) error { return err } - var req CreateProjectCommentRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateProjectCommentRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateProjectCommentRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } userID, err := validateUUID(req.UserID, "user") @@ -239,9 +243,10 @@ func (s *Server) handleCreateProjectLink(c echo.Context) error { return err } - var req CreateProjectLinkRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateProjectLinkRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateProjectLinkRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) @@ -300,9 +305,10 @@ func (s *Server) handleAddProjectTag(c echo.Context) error { return err } - var req AddProjectTagRequest - if err := validateBody(c, &req); err != nil { - return err + var req *AddProjectTagRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*AddProjectTagRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } tagID, err := validateUUID(req.TagID, "tag") @@ -369,3 +375,39 @@ func (s *Server) handleDeleteProjectTag(c echo.Context) error { return c.NoContent(http.StatusNoContent) } + +func (s *Server) handleUpdateProject(c echo.Context) error { + projectID, err := validateUUID(c.Param("id"), "project") + if err != nil { + return err + } + + var req *UpdateProjectRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateProjectRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) + } + + queries := db.New(s.DBPool) + + // Verify project exists + _, err = queries.GetProject(context.Background(), projectID) + if err != nil { + return handleDBError(err, "verify", "project") + } + + description := req.Description + params := db.UpdateProjectParams{ + ID: projectID, + Title: req.Title, + Description: &description, + Status: req.Status, + } + + project, err := queries.UpdateProject(context.Background(), params) + if err != nil { + return handleDBError(err, "update", "project") + } + + return c.JSON(http.StatusOK, project) +} diff --git a/internal/server/resource_request.go b/internal/server/resource_request.go index 336ffc3..e129997 100644 --- a/internal/server/resource_request.go +++ b/internal/server/resource_request.go @@ -5,13 +5,19 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) +type UpdateResourceRequestStatusRequest struct { + Status string `json:"status" validate:"required"` +} + func (s *Server) handleCreateResourceRequest(c echo.Context) error { - var req CreateResourceRequestRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateResourceRequestRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateResourceRequestRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } companyID, err := validateUUID(req.CompanyID, "company") @@ -92,11 +98,10 @@ func (s *Server) handleUpdateResourceRequestStatus(c echo.Context) error { return err } - var status struct { - Status string `json:"status" validate:"required"` - } - if err := validateBody(c, &status); err != nil { - return err + var req *UpdateResourceRequestStatusRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*UpdateResourceRequestStatusRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool) @@ -107,7 +112,7 @@ func (s *Server) handleUpdateResourceRequestStatus(c echo.Context) error { request, err := queries.UpdateResourceRequestStatus(context.Background(), db.UpdateResourceRequestStatusParams{ ID: requestID, - Status: status.Status, + Status: req.Status, }) if err != nil { return handleDBError(err, "update", "resource request status") diff --git a/internal/server/tag.go b/internal/server/tag.go index 7171eb3..475a9ec 100644 --- a/internal/server/tag.go +++ b/internal/server/tag.go @@ -5,13 +5,15 @@ import ( "net/http" "github.com/KonferCA/NoKap/db" + mw "github.com/KonferCA/NoKap/internal/middleware" "github.com/labstack/echo/v4" ) func (s *Server) handleCreateTag(c echo.Context) error { - var req CreateTagRequest - if err := validateBody(c, &req); err != nil { - return err + var req *CreateTagRequest + req, ok := c.Get(mw.REQUEST_BODY_KEY).(*CreateTagRequest) + if !ok { + return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } queries := db.New(s.DBPool)