forked from ebhomengo/niki
1
0
Fork 0

feat(niki): implement validation and generate swagger docs

This commit is contained in:
Ruhollah 2024-07-21 16:40:22 +03:30 committed by imirazimi
parent 4c52cd18c1
commit 4e75ebc012
10 changed files with 670 additions and 134 deletions

View File

@ -3,29 +3,60 @@ package adminkindboxreqhandler
import ( import (
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4" echo "github.com/labstack/echo/v4"
"net/http" "net/http"
) )
// GetAll godoc // GetAll godoc
// @Summary Admin get all kindboxreq // @Summary Admin get all kindboxreq
// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options
// @Tags KindBoxReq // @Tags KindBoxReq
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param page_number query int false "page_number" // @Param filter_id query int false "Filter by ID"
// @Param page_size query int false "page_size" // @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_sender_agent_id query int false "Filter by sender agent ID"
// @Param filter_kind_box_type query entity.KindBoxType false "Filter by KindBox type" Format(enum)
// @Param filter_status query entity.KindBoxReqStatus false "Filter by KindBoxReq status" Format(enum)
// @Param filter_count_requested query int false "Filter by count requested"
// @Param filter_count_accepted query int false "Filter by count accepted"
// @Param filter_deliver_refer_time_id query int false "Filter by deliver refer time ID"
// @Param filter_deliver_refer_date query string false "Filter by deliver refer date" Format(date)
// @Param filter_deliver_address_id query int false "Filter by deliver address ID"
// @Param filter_delivered_at query string false "Filter by delivered at" Format(date)
// @Param page_number query int false "Page number"
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,benefactor_id,sender_agent_id,kind_box_type,status,count_requested,count_accepted,deliver_refer_time_id,deliver_refer_date,deliver_address_id,delivered_at)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} param.KindBoxReqGetAllResponse // @Success 200 {object} param.KindBoxReqGetAllResponse
// @Failure 400 {string} "Bad request" // @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin // @Security AuthBearerAdmin
// @Router /admin/kindboxreqs [get]. // @Router /admins/kindboxreqs [get].
func (h Handler) GetAll(c echo.Context) error { func (h Handler) GetAll(c echo.Context) error {
var req param.KindBoxReqGetAllRequest var req param.KindBoxReqGetAllRequest
if bErr := c.Bind(&req); bErr != nil {
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest) return echo.NewHTTPError(http.StatusBadRequest)
} }
resp, sErr := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
if sErr != nil { req.Filter = queryparam.GetFilterParams(c)
msg, code := httpmsg.Error(sErr) if fieldErrors, err := h.adminKindBoxReqVld.ValidateGetAll(req); err != nil {
msg, code := httpmsg.Error(err)
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: fieldErrors,
})
}
resp, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg) return echo.NewHTTPError(code, msg)
} }

View File

@ -7,7 +7,7 @@ import (
) )
func (h Handler) SetRoutes(e *echo.Echo) { func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admin/kindboxreqs") r := e.Group("/admins/kindboxreqs")
r.Use(middleware.Auth(h.authSvc, h.authConfig)) r.Use(middleware.Auth(h.authSvc, h.authConfig))
r.POST("", h.AddKindBoxReq, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAddPermission)) r.POST("", h.AddKindBoxReq, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAddPermission))

View File

@ -19,15 +19,11 @@ func AdminAuthorization(service adminauthorizationservice.Service,
isAllowed, err := service.CheckAccess(claims.UserID, entity.MapToAdminRole(claims.Role), permissions...) isAllowed, err := service.CheckAccess(claims.UserID, entity.MapToAdminRole(claims.Role), permissions...)
if err != nil { if err != nil {
return c.JSON(http.StatusInternalServerError, echo.Map{ return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
"message": errmsg.ErrorMsgSomethingWentWrong,
})
} }
if !isAllowed { if !isAllowed {
return c.JSON(http.StatusForbidden, echo.Map{ return echo.NewHTTPError(http.StatusForbidden, errmsg.ErrorMsgUserNotAllowed)
"message": errmsg.ErrorMsgUserNotAllowed,
})
} }
return next(c) return next(c)

View File

@ -560,51 +560,6 @@ const docTemplate = `{
} }
}, },
"/admin/kindboxreqs": { "/admin/kindboxreqs": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Admin get all kindboxreq",
"parameters": [
{
"type": "integer",
"description": "page_number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"description": "page_size",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse"
}
},
"400": {
"description": "Bad request",
"schema": {
"type": "string"
}
}
}
},
"post": { "post": {
"security": [ "security": [
{ {
@ -1104,6 +1059,189 @@ const docTemplate = `{
} }
} }
}, },
"/admins/kindboxreqs": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "Retrieves a list of all KindBox requests with filtering, sorting, and pagination options",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Admin get all kindboxreq",
"parameters": [
{
"type": "integer",
"description": "Filter by ID",
"name": "filter_id",
"in": "query"
},
{
"type": "integer",
"description": "Filter by benefactor ID",
"name": "filter_benefactor_id",
"in": "query"
},
{
"type": "integer",
"description": "Filter by sender agent ID",
"name": "filter_sender_agent_id",
"in": "query"
},
{
"enum": [
1,
2,
3
],
"type": "integer",
"format": "enum",
"description": "Filter by KindBox type",
"name": "filter_kind_box_type",
"in": "query"
},
{
"enum": [
1,
2,
3,
4,
5
],
"type": "integer",
"format": "enum",
"description": "Filter by KindBoxReq status",
"name": "filter_status",
"in": "query"
},
{
"type": "integer",
"description": "Filter by count requested",
"name": "filter_count_requested",
"in": "query"
},
{
"type": "integer",
"description": "Filter by count accepted",
"name": "filter_count_accepted",
"in": "query"
},
{
"type": "integer",
"description": "Filter by deliver refer time ID",
"name": "filter_deliver_refer_time_id",
"in": "query"
},
{
"type": "string",
"format": "date",
"description": "Filter by deliver refer date",
"name": "filter_deliver_refer_date",
"in": "query"
},
{
"type": "integer",
"description": "Filter by deliver address ID",
"name": "filter_deliver_address_id",
"in": "query"
},
{
"type": "string",
"format": "date",
"description": "Filter by delivered at",
"name": "filter_delivered_at",
"in": "query"
},
{
"type": "integer",
"description": "Page number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"description": "Page size",
"name": "page_size",
"in": "query"
},
{
"enum": [
"id",
"benefactor_id",
"sender_agent_id",
"kind_box_type",
"status",
"count_requested",
"count_accepted",
"deliver_refer_time_id",
"deliver_refer_date",
"deliver_address_id",
"delivered_at"
],
"type": "string",
"description": "Sort by field",
"name": "sort_field",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"description": "Sort order",
"name": "sort_direction",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"401": {
"description": "invalid or expired jwt",
"schema": {
"type": "string"
}
},
"403": {
"description": "user not allowed",
"schema": {
"type": "string"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/httpmsg.ErrorResponse"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/login-by-phone": { "/admins/login-by-phone": {
"post": { "post": {
"consumes": [ "consumes": [
@ -2961,6 +3099,20 @@ const docTemplate = `{
} }
} }
}, },
"httpmsg.ErrorResponse": {
"type": "object",
"properties": {
"errors": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"message": {
"type": "string"
}
}
},
"param.PaginationResponse": { "param.PaginationResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -549,51 +549,6 @@
} }
}, },
"/admin/kindboxreqs": { "/admin/kindboxreqs": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Admin get all kindboxreq",
"parameters": [
{
"type": "integer",
"description": "page_number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"description": "page_size",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse"
}
},
"400": {
"description": "Bad request",
"schema": {
"type": "string"
}
}
}
},
"post": { "post": {
"security": [ "security": [
{ {
@ -1093,6 +1048,189 @@
} }
} }
}, },
"/admins/kindboxreqs": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"description": "Retrieves a list of all KindBox requests with filtering, sorting, and pagination options",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Admin get all kindboxreq",
"parameters": [
{
"type": "integer",
"description": "Filter by ID",
"name": "filter_id",
"in": "query"
},
{
"type": "integer",
"description": "Filter by benefactor ID",
"name": "filter_benefactor_id",
"in": "query"
},
{
"type": "integer",
"description": "Filter by sender agent ID",
"name": "filter_sender_agent_id",
"in": "query"
},
{
"enum": [
1,
2,
3
],
"type": "integer",
"format": "enum",
"description": "Filter by KindBox type",
"name": "filter_kind_box_type",
"in": "query"
},
{
"enum": [
1,
2,
3,
4,
5
],
"type": "integer",
"format": "enum",
"description": "Filter by KindBoxReq status",
"name": "filter_status",
"in": "query"
},
{
"type": "integer",
"description": "Filter by count requested",
"name": "filter_count_requested",
"in": "query"
},
{
"type": "integer",
"description": "Filter by count accepted",
"name": "filter_count_accepted",
"in": "query"
},
{
"type": "integer",
"description": "Filter by deliver refer time ID",
"name": "filter_deliver_refer_time_id",
"in": "query"
},
{
"type": "string",
"format": "date",
"description": "Filter by deliver refer date",
"name": "filter_deliver_refer_date",
"in": "query"
},
{
"type": "integer",
"description": "Filter by deliver address ID",
"name": "filter_deliver_address_id",
"in": "query"
},
{
"type": "string",
"format": "date",
"description": "Filter by delivered at",
"name": "filter_delivered_at",
"in": "query"
},
{
"type": "integer",
"description": "Page number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"description": "Page size",
"name": "page_size",
"in": "query"
},
{
"enum": [
"id",
"benefactor_id",
"sender_agent_id",
"kind_box_type",
"status",
"count_requested",
"count_accepted",
"deliver_refer_time_id",
"deliver_refer_date",
"deliver_address_id",
"delivered_at"
],
"type": "string",
"description": "Sort by field",
"name": "sort_field",
"in": "query"
},
{
"enum": [
"asc",
"desc"
],
"type": "string",
"description": "Sort order",
"name": "sort_direction",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "string"
}
},
"401": {
"description": "invalid or expired jwt",
"schema": {
"type": "string"
}
},
"403": {
"description": "user not allowed",
"schema": {
"type": "string"
}
},
"422": {
"description": "Unprocessable Entity",
"schema": {
"$ref": "#/definitions/httpmsg.ErrorResponse"
}
},
"500": {
"description": "something went wrong",
"schema": {
"type": "string"
}
}
}
}
},
"/admins/login-by-phone": { "/admins/login-by-phone": {
"post": { "post": {
"consumes": [ "consumes": [
@ -2950,6 +3088,20 @@
} }
} }
}, },
"httpmsg.ErrorResponse": {
"type": "object",
"properties": {
"errors": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"message": {
"type": "string"
}
}
},
"param.PaginationResponse": { "param.PaginationResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -753,6 +753,15 @@ definitions:
name: name:
type: string type: string
type: object type: object
httpmsg.ErrorResponse:
properties:
errors:
additionalProperties:
type: string
type: object
message:
type: string
type: object
param.PaginationResponse: param.PaginationResponse:
properties: properties:
page_number: page_number:
@ -1127,34 +1136,6 @@ paths:
tags: tags:
- KindBox - KindBox
/admin/kindboxreqs: /admin/kindboxreqs:
get:
consumes:
- application/json
parameters:
- description: page_number
in: query
name: page_number
type: integer
- description: page_size
in: query
name: page_size
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse'
"400":
description: Bad request
schema:
type: string
security:
- AuthBearerAdmin: []
summary: Admin get all kindboxreq
tags:
- KindBoxReq
post: post:
consumes: consumes:
- application/json - application/json
@ -1474,6 +1455,134 @@ paths:
summary: Get all agents by admin summary: Get all agents by admin
tags: tags:
- Admin - Admin
/admins/kindboxreqs:
get:
consumes:
- application/json
description: Retrieves a list of all KindBox requests with filtering, sorting,
and pagination options
parameters:
- description: Filter by ID
in: query
name: filter_id
type: integer
- description: Filter by benefactor ID
in: query
name: filter_benefactor_id
type: integer
- description: Filter by sender agent ID
in: query
name: filter_sender_agent_id
type: integer
- description: Filter by KindBox type
enum:
- 1
- 2
- 3
format: enum
in: query
name: filter_kind_box_type
type: integer
- description: Filter by KindBoxReq status
enum:
- 1
- 2
- 3
- 4
- 5
format: enum
in: query
name: filter_status
type: integer
- description: Filter by count requested
in: query
name: filter_count_requested
type: integer
- description: Filter by count accepted
in: query
name: filter_count_accepted
type: integer
- description: Filter by deliver refer time ID
in: query
name: filter_deliver_refer_time_id
type: integer
- description: Filter by deliver refer date
format: date
in: query
name: filter_deliver_refer_date
type: string
- description: Filter by deliver address ID
in: query
name: filter_deliver_address_id
type: integer
- description: Filter by delivered at
format: date
in: query
name: filter_delivered_at
type: string
- description: Page number
in: query
name: page_number
type: integer
- description: Page size
in: query
name: page_size
type: integer
- description: Sort by field
enum:
- id
- benefactor_id
- sender_agent_id
- kind_box_type
- status
- count_requested
- count_accepted
- deliver_refer_time_id
- deliver_refer_date
- deliver_address_id
- delivered_at
in: query
name: sort_field
type: string
- description: Sort order
enum:
- asc
- desc
in: query
name: sort_direction
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/adminkindboxreqparam.KindBoxReqGetAllResponse'
"400":
description: Bad Request
schema:
type: string
"401":
description: invalid or expired jwt
schema:
type: string
"403":
description: user not allowed
schema:
type: string
"422":
description: Unprocessable Entity
schema:
$ref: '#/definitions/httpmsg.ErrorResponse'
"500":
description: something went wrong
schema:
type: string
security:
- AuthBearerAdmin: []
summary: Admin get all kindboxreq
tags:
- KindBoxReq
/admins/login-by-phone: /admins/login-by-phone:
post: post:
consumes: consumes:

View File

@ -0,0 +1,6 @@
package httpmsg
type ErrorResponse struct {
Message string `json:"message"`
Errors map[string]string `json:"errors"`
}

View File

@ -1,5 +1,43 @@
package adminkindboxreqvalidator package adminkindboxreqvalidator
func (v Validator) ValidateGetAllRequest() (map[string]string, error) { import (
"errors"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/validator"
validation "github.com/go-ozzo/ozzo-validation/v4"
)
func (v Validator) ValidateGetAll(req param.KindBoxReqGetAllRequest) (map[string]string, error) {
const op = "adminkindboxreqvalidator.ValidateGetAll"
validFields := []string{
"id", "benefactor_id", "sender_agent_id",
"kind_box_type", "status", "count_requested", "count_accepted",
"deliver_refer_time_id", "deliver_refer_date",
"deliver_address_id", "delivered_at",
}
if err := validation.ValidateStruct(&req,
validation.Field(&req.Filter, validation.By(validator.AreFilterFieldsValid(validFields))),
validation.Field(&req.Sort, validation.By(validator.AreSortFieldsValid(validFields))),
); err != nil {
fieldErrors := make(map[string]string)
var errV validation.Errors
if errors.As(err, &errV) {
for key, value := range errV {
if value != nil {
fieldErrors[key] = value.Error()
}
}
}
return fieldErrors, richerror.New(op).
WithMessage(errmsg.ErrorMsgInvalidInput).
WithKind(richerror.KindInvalid).
WithMeta(map[string]interface{}{"req": req}).
WithErr(err)
}
return map[string]string{}, nil return map[string]string{}, nil
} }

24
validator/filter.go Normal file
View File

@ -0,0 +1,24 @@
package validator
import (
"fmt"
params "git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4"
"slices"
)
func AreFilterFieldsValid(validFilters []string) validation.RuleFunc {
return func(value interface{}) error {
filters, ok := value.(params.FilterRequest)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
for filter := range filters {
if !slices.Contains(validFilters, filter) {
return fmt.Errorf(errmsg.ErrorMsgFiltersAreNotValid)
}
}
return nil
}
}

28
validator/sort.go Normal file
View File

@ -0,0 +1,28 @@
package validator
import (
"fmt"
params "git.gocasts.ir/ebhomengo/niki/param"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4"
"slices"
)
func AreSortFieldsValid(validSortFields []string) validation.RuleFunc {
return func(value interface{}) error {
sort, ok := value.(params.SortRequest)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if sort.Field == "" && sort.Direction != "" {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsRequired)
}
if sort.Direction != "" && sort.Direction != params.AscSortDirection && sort.Direction != params.DescSortDirection {
return fmt.Errorf(errmsg.ErrorMsgSortDirectionShouldBeAscOrDesc)
}
if sort.Field != "" && !slices.Contains(validSortFields, sort.Field) {
return fmt.Errorf(errmsg.ErrorMsgSortFieldIsNotValid)
}
return nil
}
}