add validation for accepting kind-box-req

This commit is contained in:
Abolfazl Nourzad 2024-01-22 17:37:51 +03:30
parent 12a8e0ecf5
commit 5708f0c414
Signed by: abolfazl
GPG Key ID: 183534166EB62E0B
8 changed files with 155 additions and 48 deletions

View File

@ -1,11 +1,11 @@
package adminkindboxreqhandler package adminkindboxreqhandler
import ( import (
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
"net/http" "net/http"
"strconv" "strconv"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -20,14 +20,15 @@ func (h Handler) Accept(c echo.Context) error {
return c.JSON(http.StatusBadRequest, errmsg.ErrorMsgInvalidInput) return c.JSON(http.StatusBadRequest, errmsg.ErrorMsgInvalidInput)
} }
req.ID = uint(num) req.ID = uint(num)
// if fieldErrors, err := h.adminKindBoxReqVld.ValidateGetRequest(req); err != nil { if fieldErrors, err := h.adminKindBoxReqVld.ValidateAcceptRequest(req); err != nil {
// msg, code := httpmsg.Error(err) msg, code := httpmsg.Error(err)
//
// return c.JSON(code, echo.Map{ return c.JSON(code, echo.Map{
// "message": msg, "message": msg,
// "errors": fieldErrors, "errors": fieldErrors,
// }) })
//} }
resp, sErr := h.adminKindBoxReqSvc.Accept(c.Request().Context(), req) resp, sErr := h.adminKindBoxReqSvc.Accept(c.Request().Context(), req)
if sErr != nil { if sErr != nil {
msg, code := httpmsg.Error(sErr) msg, code := httpmsg.Error(sErr)

View File

@ -14,4 +14,5 @@ const (
ErrorMsgOtpCodeIsNotValid = "verification code is not valid" ErrorMsgOtpCodeIsNotValid = "verification code is not valid"
ErrorMsgCantScanQueryResult = "can't scan query result" ErrorMsgCantScanQueryResult = "can't scan query result"
ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect" ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect"
ErrorMsgReAcceptKindBoxReq = "accepted request cannot be re-accepted"
) )

View File

@ -2,6 +2,9 @@ package mysqlkindboxreq
import ( import (
"context" "context"
"database/sql"
"errors"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
@ -29,6 +32,7 @@ func (d DB) AcceptKindBoxReq(ctx context.Context, kindBoxReqID uint, countAccept
op := richerror.Op("mysqlkindboxreq.AcceptKindBoxReq") op := richerror.Op("mysqlkindboxreq.AcceptKindBoxReq")
statement, err := d.conn.Conn(). statement, err := d.conn.Conn().
Prepare(`update kind_box_reqs set count_accepted = ? , status = ? where id = ?`) Prepare(`update kind_box_reqs set count_accepted = ? , status = ? where id = ?`)
defer statement.Close()
if err != nil { if err != nil {
return richerror.New(op).WithErr(err). return richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected) WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
@ -42,13 +46,46 @@ func (d DB) AcceptKindBoxReq(ctx context.Context, kindBoxReqID uint, countAccept
return nil return nil
} }
func (d DB) FindByID(ctx context.Context, id uint) (entity.KindBoxReq, error) { func (d DB) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error) {
op := richerror.Op("mysqlkindboxreq.findByID") op := richerror.Op("mysqlkindboxreq.GetByID")
row := d.conn.Conn().QueryRowContext(ctx, `select * from kind_box_reqs where id = ?`, id) row := d.conn.Conn().QueryRowContext(ctx, `select * from kind_box_reqs where id = ?`, id)
k, err := scanKindBoxReq(row) k, err := scanKindBoxReq(row)
if err != nil { if err != nil {
return entity.KindBoxReq{}, richerror.New(op).WithErr(err). return entity.KindBoxReq{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected) WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
} }
return k, nil return k, nil
} }
func (d DB) KindBoxRequestExist(id uint) (bool, error) {
op := richerror.Op("mysqlkindboxreq.KindBoxRequestExist")
row := d.conn.Conn().QueryRow(`select * from kind_box_reqs where id = ?`, id)
_, sErr := scanKindBoxReq(row)
if sErr != nil {
if errors.Is(sErr, sql.ErrNoRows) {
return false, nil
}
return false, richerror.New(op).WithErr(sErr).WithMessage(errmsg.ErrorMsgCantScanQueryResult).
WithKind(richerror.KindUnexpected).WithMeta(map[string]any{"id": id})
}
return true, nil
}
func (d DB) CheckKindBoxReqStatusForAccepting(id uint) error {
op := richerror.Op("mysqlkindboxreq.CheckKindBoxReqStatusForAccepting")
k, err := d.GetByID(context.Background(), id)
if err != nil {
return richerror.New(op).WithErr(err)
}
if k.Status == entity.KindBoxReqAcceptedStatus {
return richerror.New(op).WithMessage(errmsg.ErrorMsgReAcceptKindBoxReq).WithMeta(map[string]interface{}{
"id": id,
}).WithKind(richerror.KindInvalid)
}
return nil
}

View File

@ -2,6 +2,7 @@ package adminkindboxreqservice
import ( import (
"context" "context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
) )
@ -14,9 +15,9 @@ func (s Service) Accept(ctx context.Context, req param.KindBoxReqAcceptRequest)
} }
// fire new event to create a kind-box. // fire new event to create a kind-box.
//get kind box req // get kind box req
kindBoxReq, gErr := s.repo.FindByID(ctx, req.ID) kindBoxReq, gErr := s.repo.GetByID(ctx, req.ID)
if gErr != nil { if gErr != nil {
return param.KindBoxReqAcceptResponse{}, richerror.New(op).WithErr(err) return param.KindBoxReqAcceptResponse{}, richerror.New(op).WithErr(err)
} }

View File

@ -2,6 +2,7 @@ package adminkindboxreqservice
import ( import (
"context" "context"
"git.gocasts.ir/ebhomengo/niki/entity" "git.gocasts.ir/ebhomengo/niki/entity"
) )
@ -13,7 +14,7 @@ type Repository interface {
// GetAllKindBoxReq(ctx context.Context) ([]entity.KindBoxReq, error) // GetAllKindBoxReq(ctx context.Context) ([]entity.KindBoxReq, error)
// GetKindBoxReq(ctx context.Context, kindBoxReqID uint) (entity.KindBoxReq, error) // GetKindBoxReq(ctx context.Context, kindBoxReqID uint) (entity.KindBoxReq, error)
AcceptKindBoxReq(ctx context.Context, kindBoxReqID uint, countAccepted uint) error AcceptKindBoxReq(ctx context.Context, kindBoxReqID uint, countAccepted uint) error
FindByID(ctx context.Context, id uint) (entity.KindBoxReq, error) GetByID(ctx context.Context, id uint) (entity.KindBoxReq, error)
} }
// TODO: check validation. // TODO: check validation.

View File

@ -9,7 +9,7 @@ package adminkindboxreqservice
// richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
//) //)
// //
//func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) { // func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) {
// // TODO: can benefactor update its request ? // // TODO: can benefactor update its request ?
// // TODO: Is Update Mothod Service Responsible to check which kindboxreqID belongs to benefactorID ? // // TODO: Is Update Mothod Service Responsible to check which kindboxreqID belongs to benefactorID ?
// // TODO: updating data(s) may have side-effect on other entities by masood-keshvary accepted -> rejected // // TODO: updating data(s) may have side-effect on other entities by masood-keshvary accepted -> rejected

View File

@ -0,0 +1,42 @@
package adminkindboxreqvalidator
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"
validation "github.com/go-ozzo/ozzo-validation/v4"
)
func (v Validator) ValidateAcceptRequest(req param.KindBoxReqAcceptRequest) (map[string]string, error) {
const op = "adminkindboxreqvalidator.ValidateAcceptRequest"
if err := validation.ValidateStruct(&req,
validation.Field(&req.ID, validation.Required, validation.By(v.doesKindBoxRequestExist), validation.By(v.checkKindBoxReqStatus)),
validation.Field(&req.CountAccepted,
validation.Required,
validation.Min(uint(MinKindBoxReq)), validation.Max(uint(MaxKindBoxReq)),
),
); 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
}

View File

@ -1,5 +1,12 @@
package adminkindboxreqvalidator package adminkindboxreqvalidator
import (
"errors"
"fmt"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
)
const ( const (
MinKindBoxReq = 1 MinKindBoxReq = 1
MaxKindBoxReq = 100 MaxKindBoxReq = 100
@ -7,10 +14,11 @@ const (
type Repository interface { type Repository interface {
// BenefactorExist(id int) (bool, error) // BenefactorExist(id int) (bool, error)
// KindBoxRequestExist(id int) (bool, error) KindBoxRequestExist(id uint) (bool, error)
// TypeExist(id int) (bool, error) // TypeExist(id int) (bool, error)
// KindBoxBelongToBenefactor(benefactorID uint, kindboxID uint) (bool, error) // KindBoxBelongToBenefactor(benefactorID uint, kindboxID uint) (bool, error)
// PendingStatus(id uint) (bool, error) // PendingStatus(id uint) (bool, error)
CheckKindBoxReqStatusForAccepting(id uint) error
} }
type Validator struct { type Validator struct {
@ -21,47 +29,63 @@ func New(repo Repository) Validator {
return Validator{repo: repo} return Validator{repo: repo}
} }
// // func (v Validator) doesBenefactorExist(value interface{}) error {
// func (v Validator) doesBenefactorExist(value interface{}) error { // benefactorID, ok := value.(int)
// benefactorID, ok := value.(int)
// if !ok {
// return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
// }
// _, err := v.repo.BenefactorExist(benefactorID)
// if err != nil {
// return fmt.Errorf(errmsg.ErrorMsgNotFound)
// }
//
// return nil
//}
//
// func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.RuleFunc {
// return func(value interface{}) error {
// kbID, ok := value.(uint)
// if !ok { // if !ok {
// return fmt.Errorf(errmsg.ErrorMsgNotFound) // return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
// } // }
// _, err := v.repo.KindBoxBelongToBenefactor(benefactorID, kbID) // _, err := v.repo.BenefactorExist(benefactorID)
// if err != nil { // if err != nil {
// return fmt.Errorf(errmsg.ErrorMsgNotFound) // return fmt.Errorf(errmsg.ErrorMsgNotFound)
// } // }
// //
// return nil // return nil
// } // }
//}
// //
// func (v Validator) doesKindBoxRequestExist(value interface{}) error { // func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.RuleFunc {
// kindboxreqID, ok := value.(int) // return func(value interface{}) error {
// if !ok { // kbID, ok := value.(uint)
// return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) // if !ok {
// } // return fmt.Errorf(errmsg.ErrorMsgNotFound)
// _, err := v.repo.KindBoxRequestExist(kindboxreqID) // }
// if err != nil { // _, err := v.repo.KindBoxBelongToBenefactor(benefactorID, kbID)
// return fmt.Errorf(errmsg.ErrorMsgNotFound) // if err != nil {
// } // return fmt.Errorf(errmsg.ErrorMsgNotFound)
// }
// //
// return nil // return nil
//} // }
// }
func (v Validator) doesKindBoxRequestExist(value interface{}) error {
kindboxreqID, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if isExist, err := v.repo.KindBoxRequestExist(kindboxreqID); !isExist || err != nil {
if err != nil {
return err
}
if !isExist {
return errors.New("kind box request is not exist")
}
}
return nil
}
func (v Validator) checkKindBoxReqStatus(value interface{}) error {
kindboxreqID, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
err := v.repo.CheckKindBoxReqStatusForAccepting(kindboxreqID)
if err != nil {
return err
}
return nil
}
// //
// func (v Validator) doesTypeExist(value interface{}) error { // func (v Validator) doesTypeExist(value interface{}) error {
// typeID, ok := value.(int) // typeID, ok := value.(int)
@ -76,7 +100,7 @@ func New(repo Repository) Validator {
// return nil // return nil
//} //}
// //
//func (v Validator) hasPendingStatus(value interface{}) error { // func (v Validator) hasPendingStatus(value interface{}) error {
// kindboxID, ok := value.(uint) // kindboxID, ok := value.(uint)
// if !ok { // if !ok {
// return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) // return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)