Skip to content

Commit

Permalink
Merge pull request #78 from KonferCA/65-be-refactor-endpoints-to-use-…
Browse files Browse the repository at this point in the history
…request-body-validator-middleware

Refactor/65/add-request-body-validator-middleware
  • Loading branch information
juancwu authored Nov 22, 2024
2 parents 317bc72 + d47498e commit 34544c2
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 102 deletions.
7 changes: 6 additions & 1 deletion .sqlc/queries/company_questions_answers.sql
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ RETURNING *;
-- name: SoftDeleteCompanyAnswer :exec
UPDATE company_question_answers
SET deleted_at = NOW()
WHERE company_id = $1 AND question_id = $2;
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;
8 changes: 5 additions & 3 deletions internal/server/company.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
15 changes: 9 additions & 6 deletions internal/server/company_documents.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 9 additions & 6 deletions internal/server/company_financials.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down
37 changes: 28 additions & 9 deletions internal/server/company_questions_answers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
15 changes: 9 additions & 6 deletions internal/server/employee.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 9 additions & 6 deletions internal/server/funding_transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand Down
67 changes: 35 additions & 32 deletions internal/server/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package server
import (
"fmt"
"os"
"reflect"
"time"

"github.com/jackc/pgx/v5/pgxpool"
Expand Down Expand Up @@ -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)
}

Expand Down
Loading

0 comments on commit 34544c2

Please sign in to comment.