forked from ebhomengo/niki
1
0
Fork 0

feat(niki): add kindboxreq benefactor

This commit is contained in:
mohammad mahdi rezaei 2024-01-16 19:43:06 +03:30
parent f622b6edd0
commit 91409f0275
53 changed files with 791 additions and 377 deletions

View File

@ -1,32 +1,32 @@
package adminkindboxreqhandler package adminkindboxreqhandler
import ( // import (
"net/http" // "net/http"
//
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"
echo "github.com/labstack/echo/v4" // echo "github.com/labstack/echo/v4"
) //)
//
func (h Handler) Add(c echo.Context) error { // func (h Handler) Add(c echo.Context) error {
var req param.KindBoxReqAddRequest // var req param.KindBoxReqAddRequest
if bErr := c.Bind(&req); bErr != nil { // if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest) // return echo.NewHTTPError(http.StatusBadRequest)
} // }
if fieldErrors, err := h.adminKindBoxReqVld.ValidateAddRequest(req); err != nil { // if fieldErrors, err := h.adminKindBoxReqVld.ValidateAddRequest(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.Add(c.Request().Context(), req) // resp, sErr := h.adminKindBoxReqSvc.Add(c.Request().Context(), req)
if sErr != nil { // if sErr != nil {
msg, code := httpmsg.Error(sErr) // msg, code := httpmsg.Error(sErr)
//
return echo.NewHTTPError(code, msg) // return echo.NewHTTPError(code, msg)
} // }
//
return c.JSON(http.StatusCreated, resp) // return c.JSON(http.StatusCreated, resp)
} //}

View File

@ -7,8 +7,10 @@ import (
func (h Handler) SetRoutes(e *echo.Echo) { func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admin/kindboxreqs") r := e.Group("/admin/kindboxreqs")
r.POST("/", h.Add).Name = "admin-addkindboxreq" //nolint:gocritic
//r.POST("/", h.Add).Name = "admin-addkindboxreq"
r.GET("/:id", h.Get).Name = "admin-getkindboxreqbyid" r.GET("/:id", h.Get).Name = "admin-getkindboxreqbyid"
r.GET("/", h.GetAll).Name = "admin-getallkindboxreq" r.GET("/", h.GetAll).Name = "admin-getallkindboxreq"
r.PATCH("/:id", h.Update).Name = "admin-updatekindboxreq" //nolint:gocritic
//r.PATCH("/:id", h.Update).Name = "admin-updatekindboxreq"
} }

View File

@ -1,32 +1,32 @@
package adminkindboxreqhandler package adminkindboxreqhandler
import ( // import (
"net/http" // "net/http"
//
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"
echo "github.com/labstack/echo/v4" // echo "github.com/labstack/echo/v4"
) //)
//
func (h Handler) Update(c echo.Context) error { // func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest // var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil { // if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest) // return echo.NewHTTPError(http.StatusBadRequest)
} // }
if fieldErrors, err := h.adminKindBoxReqVld.ValidateUpdateRequest(req); err != nil { // if fieldErrors, err := h.adminKindBoxReqVld.ValidateUpdateRequest(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.Update(c.Request().Context(), req) // resp, sErr := h.adminKindBoxReqSvc.Update(c.Request().Context(), req)
if sErr != nil { // if sErr != nil {
msg, code := httpmsg.Error(sErr) // msg, code := httpmsg.Error(sErr)
//
return echo.NewHTTPError(code, msg) // return echo.NewHTTPError(code, msg)
} // }
//
return c.JSON(http.StatusCreated, resp) // return c.JSON(http.StatusCreated, resp)
} //}

View File

@ -4,15 +4,18 @@ import (
"net/http" "net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4" echo "github.com/labstack/echo/v4"
) )
func (h Handler) Add(c echo.Context) error { func (h Handler) Add(c echo.Context) error {
var req param.KindBoxReqAddRequest claims := claim.GetClaimsFromEchoContext(c)
req := param.KindBoxReqAddRequest{BenefactorID: claims.UserID}
if bErr := c.Bind(&req); bErr != nil { if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest) return echo.NewHTTPError(http.StatusBadRequest)
} }
if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateAddRequest(req); err != nil { if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateAddRequest(req); err != nil {
msg, code := httpmsg.Error(err) msg, code := httpmsg.Error(err)

View File

@ -1,32 +1,24 @@
package benefactorkindboxreqhandler package benefactorkindboxreqhandler
import ( // func (h Handler) Get(c echo.Context) error {
"net/http" // var req param.KindBoxReqGetRequest
// if bErr := c.Bind(&req); bErr != nil {
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" // return echo.NewHTTPError(http.StatusBadRequest)
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" // }
echo "github.com/labstack/echo/v4" // if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateGetRequest(req); err != nil {
) // msg, code := httpmsg.Error(err)
//
func (h Handler) Get(c echo.Context) error { // return c.JSON(code, echo.Map{
var req param.KindBoxReqGetRequest // "message": msg,
if bErr := c.Bind(&req); bErr != nil { // "errors": fieldErrors,
return echo.NewHTTPError(http.StatusBadRequest) // })
} // }
if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateGetRequest(req); err != nil { // resp, sErr := h.benefactorKindBoxReqSvc.Get(c.Request().Context(), req)
msg, code := httpmsg.Error(err) // if sErr != nil {
// msg, code := httpmsg.Error(sErr)
return c.JSON(code, echo.Map{ //
"message": msg, // return echo.NewHTTPError(code, msg)
"errors": fieldErrors, // }
}) //
} // return c.JSON(http.StatusCreated, resp)
resp, sErr := h.benefactorKindBoxReqSvc.Get(c.Request().Context(), req) //}
if sErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusCreated, resp)
}

View File

@ -1,25 +1,17 @@
package benefactorkindboxreqhandler package benefactorkindboxreqhandler
import ( // func (h Handler) GetAll(c echo.Context) error {
"net/http" // var req param.KindBoxReqGetAllRequest
// if bErr := c.Bind(&req); bErr != nil {
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" // return echo.NewHTTPError(http.StatusBadRequest)
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" // }
echo "github.com/labstack/echo/v4" //
) // resp, sErr := h.benefactorKindBoxReqSvc.GetAll(c.Request().Context(), req)
// if sErr != nil {
func (h Handler) GetAll(c echo.Context) error { // msg, code := httpmsg.Error(sErr)
var req param.KindBoxReqGetAllRequest //
if bErr := c.Bind(&req); bErr != nil { // return echo.NewHTTPError(code, msg)
return echo.NewHTTPError(http.StatusBadRequest) // }
} //
// return c.JSON(http.StatusCreated, resp)
resp, sErr := h.benefactorKindBoxReqSvc.GetAll(c.Request().Context(), req) //}
if sErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusCreated, resp)
}

View File

@ -1,14 +1,16 @@
package benefactorkindboxreqhandler package benefactorkindboxreqhandler
import ( import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
echo "github.com/labstack/echo/v4" echo "github.com/labstack/echo/v4"
) )
func (h Handler) SetRoutes(e *echo.Echo) { func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactor/kindboxreqs") r := e.Group("/benefactor/kindboxreqs")
r.POST("/", h.Add).Name = "benefactor-addkindboxreq" r.POST("/", h.Add, middleware.Auth(h.authSvc, h.authConfig))
r.GET("/:id", h.Get).Name = "benefactor-get-kindboxreqbyid" //nolint:gocritic
r.GET("/", h.GetAll).Name = "benefactor-getallkindboxreq" // r.GET("/:id", h.Get)
r.PATCH("/:id", h.Update).Name = "benefactor-updatekindboxreq" // r.GET("/", h.GetAll)
// r.PATCH("/:id", h.Update)
} }

View File

@ -1,32 +1,24 @@
package benefactorkindboxreqhandler package benefactorkindboxreqhandler
import ( // func (h Handler) Update(c echo.Context) error {
"net/http" // var req param.KindBoxReqUpdateRequest
// if bErr := c.Bind(&req); bErr != nil {
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" // return echo.NewHTTPError(http.StatusBadRequest)
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg" // }
echo "github.com/labstack/echo/v4" // if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateUpdateRequest(req); err != nil {
) // msg, code := httpmsg.Error(err)
//
func (h Handler) Update(c echo.Context) error { // return c.JSON(code, echo.Map{
var req param.KindBoxReqUpdateRequest // "message": msg,
if bErr := c.Bind(&req); bErr != nil { // "errors": fieldErrors,
return echo.NewHTTPError(http.StatusBadRequest) // })
} // }
if fieldErrors, err := h.benefactorKindBoxReqVld.ValidateUpdateRequest(req); err != nil { // resp, sErr := h.benefactorKindBoxReqSvc.Update(c.Request().Context(), req)
msg, code := httpmsg.Error(err) // if sErr != nil {
// msg, code := httpmsg.Error(sErr)
return c.JSON(code, echo.Map{ //
"message": msg, // return echo.NewHTTPError(code, msg)
"errors": fieldErrors, // }
}) //
} // return c.JSON(http.StatusCreated, resp)
resp, sErr := h.benefactorKindBoxReqSvc.Update(c.Request().Context(), req) //}
if sErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusCreated, resp)
}

View File

@ -0,0 +1,25 @@
package middleware
import (
"git.gocasts.ir/ebhomengo/niki/config"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor"
mw "github.com/labstack/echo-jwt/v4"
"github.com/labstack/echo/v4"
)
func Auth(service authservice.Service, cfg authservice.Config) echo.MiddlewareFunc {
return mw.WithConfig(mw.Config{
ContextKey: config.AuthMiddlewareContextKey,
SigningKey: []byte(cfg.SignKey),
// TODO - as sign method string to config
SigningMethod: "HS256",
ParseTokenFunc: func(c echo.Context, auth string) (interface{}, error) {
claims, err := service.ParseToken(auth)
if err != nil {
return nil, err
}
return claims, nil
},
})
}

View File

@ -5,23 +5,36 @@ import (
config "git.gocasts.ir/ebhomengo/niki/config" config "git.gocasts.ir/ebhomengo/niki/config"
benefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/benefactor" benefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/benefactor"
benefactorkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor" benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor" benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
echo "github.com/labstack/echo/v4" echo "github.com/labstack/echo/v4"
middleware "github.com/labstack/echo/v4/middleware" middleware "github.com/labstack/echo/v4/middleware"
) )
type Server struct { type Server struct {
config config.Config config config.Config
Router *echo.Echo Router *echo.Echo
benefactorHandler benefactorhandler.Handler benefactorHandler benefactorhandler.Handler
benefactorkindboxreqhandler benefactorkindboxreqhandler.Handler
} }
func New(cfg config.Config, benefactorSvc benefactorservice.Service, benefactorVld benefactorvalidator.Validator) Server { func New(
cfg config.Config,
benefactorSvc benefactorservice.Service,
benefactorVld benefactorvalidator.Validator,
authSvc authservice.Service,
benefactorKindBoxReqSvc benefactorkindboxreqservice.Service,
benefactorKindBoxReqVld benefactorkindboxreqvalidator.Validator,
) Server {
return Server{ return Server{
Router: echo.New(), Router: echo.New(),
config: cfg, config: cfg,
benefactorHandler: benefactorhandler.New(cfg.Auth, benefactorSvc, benefactorVld), benefactorHandler: benefactorhandler.New(cfg.Auth, benefactorSvc, benefactorVld),
benefactorkindboxreqhandler: benefactorkindboxreqhandler.New(cfg.Auth, authSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld),
} }
} }
@ -33,6 +46,7 @@ func (s Server) Serve() {
// Routes // Routes
s.Router.GET("/health-check", s.healthCheck) s.Router.GET("/health-check", s.healthCheck)
s.benefactorHandler.SetRoutes(s.Router) s.benefactorHandler.SetRoutes(s.Router)
s.benefactorkindboxreqhandler.SetRoutes(s.Router)
// Start server // Start server
address := fmt.Sprintf(":%d", s.config.HTTPServer.Port) address := fmt.Sprintf(":%d", s.config.HTTPServer.Port)

6
entity/Province.go Normal file
View File

@ -0,0 +1,6 @@
package entity
type Province struct {
ID uint
Name string
}

12
entity/address.go Normal file
View File

@ -0,0 +1,12 @@
package entity
type Address struct {
ID uint
PostalCode string
Address string
Lat float32
Lon float32
CityID uint
ProvinceID uint
BenefactorID uint
}

7
entity/city.go Normal file
View File

@ -0,0 +1,7 @@
package entity
type City struct {
ID uint
Name string
ProvinceID uint
}

View File

@ -3,12 +3,13 @@ package entity
import "time" import "time"
type KindBoxReq struct { type KindBoxReq struct {
ID uint ID uint
TypeID uint KindBoxType KindBoxType
CountRequested uint CountRequested uint
CountAccepted uint CountAccepted uint
BenefactorID uint BenefactorID uint
Status KindBoxReqStatus Status KindBoxReqStatus
Description string Description string
StatusChangedAt time.Time ReferDate time.Time
AddressID uint
} }

View File

@ -1,27 +1,28 @@
package entity package entity
// TODO - use config file instead of const.
type KindBoxType uint type KindBoxType uint
// const ( const (
// KindBoxPendingSendStatus KindBoxType = iota + 1 KindBoxOnTable KindBoxType = iota + 1
// KindBoxSentStatus KindBoxCylindrical
// KindBoxPendingReceivedStatus KindBoxStandUp
// KindBoxReceivedStatus )
// KindBoxEnumeratedStatus
// )
var KindBoxTypeStrings = map[KindBoxType]string{ var KindBoxTypeStrings = map[KindBoxType]string{
// KindBoxPendingSendStatus: "pending-send", KindBoxOnTable: "on-table",
// KindBoxSentStatus: "sent", KindBoxCylindrical: "cylindrical",
// KindBoxPendingReceivedStatus: "pending-received", KindBoxStandUp: "stand-up",
// KindBoxReceivedStatus: "received",
// KindBoxEnumeratedStatus: "enumerated",
} }
func (s KindBoxType) String() string { func (s KindBoxType) String() string {
return KindBoxTypeStrings[s] return KindBoxTypeStrings[s]
} }
func (s KindBoxType) IsValid() bool {
return s > 0 && int(s) <= len(KindBoxTypeStrings)
}
// AllKindBoxType returns a slice containing all string values of KindBoxType. // AllKindBoxType returns a slice containing all string values of KindBoxType.
func AllKindBoxType() []string { func AllKindBoxType() []string {
statusStrings := make([]string, len(KindBoxTypeStrings)) statusStrings := make([]string, len(KindBoxTypeStrings))

2
go.mod
View File

@ -8,6 +8,7 @@ require (
github.com/go-sql-driver/mysql v1.6.0 github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang-jwt/jwt/v4 v4.5.0
github.com/knadh/koanf v1.5.0 github.com/knadh/koanf v1.5.0
github.com/labstack/echo-jwt/v4 v4.2.0
github.com/labstack/echo/v4 v4.11.4 github.com/labstack/echo/v4 v4.11.4
github.com/redis/go-redis/v9 v9.4.0 github.com/redis/go-redis/v9 v9.4.0
github.com/rubenv/sql-migrate v1.6.0 github.com/rubenv/sql-migrate v1.6.0
@ -22,6 +23,7 @@ require (
github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect

4
go.sum
View File

@ -82,6 +82,8 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -174,6 +176,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c=
github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU=
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=

26
main.go
View File

@ -5,12 +5,18 @@ import (
smsprovider "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider" smsprovider "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider"
"git.gocasts.ir/ebhomengo/niki/config" "git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server" httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
"git.gocasts.ir/ebhomengo/niki/repository/migrator"
"git.gocasts.ir/ebhomengo/niki/repository/mysql" "git.gocasts.ir/ebhomengo/niki/repository/mysql"
mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor" mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor"
mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/redis_otp" redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/redis_otp"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor" authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor"
benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor" benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor" benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
) )
@ -18,16 +24,18 @@ func main() {
cfg := config.C() cfg := config.C()
// TODO - add command for migrations // TODO - add command for migrations
// mgr := migrator.New(cfg.Mysql) mgr := migrator.New(cfg.Mysql)
// mgr.Up() mgr.Up()
_, benefactorSvc, benefactorVld := setupServices(cfg) authSvc, benefactorSvc, benefactorVld, benefactorKindBoxReqSvc, benefactorKindBoxReqVld := setupServices(cfg)
server := httpserver.New(cfg, benefactorSvc, benefactorVld) server := httpserver.New(cfg, benefactorSvc, benefactorVld, authSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld)
server.Serve() server.Serve()
} }
//nolint:nakedret // we are sure of this
func setupServices(cfg config.Config) ( func setupServices(cfg config.Config) (
authSvc authservice.Service, benefactorSvc benefactorservice.Service, benefactorVld benefactorvalidator.Validator, authSvc authservice.Service, benefactorSvc benefactorservice.Service, benefactorVld benefactorvalidator.Validator,
benefactorKindBoxReqSvc benefactorkindboxreqservice.Service, benefactorKindBoxReqVld benefactorkindboxreqvalidator.Validator,
) { ) {
authSvc = authservice.New(cfg.Auth) authSvc = authservice.New(cfg.Auth)
@ -43,5 +51,13 @@ func setupServices(cfg config.Config) (
benefactorVld = benefactorvalidator.New() benefactorVld = benefactorvalidator.New()
return authSvc, benefactorSvc, benefactorVld benefactorkindBoxReqMysql := mysqlkindboxreq.New(MysqlRepo)
benefactorKindBoxReqSvc = benefactorkindboxreqservice.New(benefactorkindBoxReqMysql)
benefactorAddressMysql := mysqladdress.New(MysqlRepo)
benefactorAddressSvc := benefactoraddressservice.New(benefactorAddressMysql)
benefactorKindBoxReqVld = benefactorkindboxreqvalidator.New(benefactorkindBoxReqMysql, benefactorSvc, benefactorAddressSvc)
return
} }

View File

@ -0,0 +1,17 @@
package addressparam
import "git.gocasts.ir/ebhomengo/niki/entity"
type BenefactorAddAddressRequest struct {
PostalCode string `json:"postal_code"`
Address string `json:"address"`
Lat float32 `json:"lat"`
Lon float32 `json:"lon"`
CityID uint `json:"city_id"`
ProvinceID uint `json:"province_id"`
BenefactorID uint `json:"benefactor_id"`
}
type BenefactorAddAddressResponse struct {
Address entity.Address `json:"address"`
}

View File

@ -0,0 +1,10 @@
package addressparam
import "git.gocasts.ir/ebhomengo/niki/entity"
type GetAddressByIDRequest struct {
ID uint
}
type GetAddressByIDResponse struct {
Address *entity.Address
}

View File

@ -0,0 +1,8 @@
package benefactoreparam
type BenefactorExistByIDRequest struct {
ID uint
}
type BenefactorExistByIDResponse struct {
Existed bool
}

View File

@ -1,13 +1,17 @@
package benefactorkindboxreqparam package benefactorkindboxreqparam
import entity "git.gocasts.ir/ebhomengo/niki/entity" import (
entity "git.gocasts.ir/ebhomengo/niki/entity"
)
type KindBoxReqAddRequest struct { type KindBoxReqAddRequest struct {
BenefactorID uint BenefactorID uint `json:"benefactor_id"`
TypeID uint TypeID entity.KindBoxType `json:"type_id"`
CountRequested uint AddressID uint `json:"address_id"`
ReferDate string `json:"refer_date"`
CountRequested uint `json:"count_requested"`
} }
type KindBoxReqAddResponse struct { type KindBoxReqAddResponse struct {
KindBoxReq entity.KindBoxReq KindBoxReq entity.KindBoxReq `json:"kind_box_req"`
} }

View File

@ -5,7 +5,7 @@ import entity "git.gocasts.ir/ebhomengo/niki/entity"
type KindBoxReqUpdateRequest struct { type KindBoxReqUpdateRequest struct {
BenefactorID uint BenefactorID uint
KindBoxReqID uint KindBoxReqID uint
TypeID uint TypeID entity.KindBoxType
CountRequested uint CountRequested uint
} }

12
pkg/claim/echo.go Normal file
View File

@ -0,0 +1,12 @@
package claim
import (
"git.gocasts.ir/ebhomengo/niki/config"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth/benefactor"
"github.com/labstack/echo/v4"
)
func GetClaimsFromEchoContext(c echo.Context) *authservice.Claims {
//nolint:forcetypeassert //defensive programming vs let it crash - log-metric-recover ,...
return c.Get(config.AuthMiddlewareContextKey).(*authservice.Claims)
}

View File

@ -0,0 +1,27 @@
package mysqladdress
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d DB) CreateBenefactorAddress(ctx context.Context, address entity.Address) (entity.Address, error) {
const op = "mysqlbenefactor.createBenefactorAddress"
res, err := d.conn.Conn().ExecContext(ctx, `insert into addresses(postal_code, address, lat, lon,province_id,city_id,benefactor_id) values(?, ?, ?,?,?,?,?)`,
address.PostalCode, address.Address, address.Lat, address.Lon, address.ProvinceID, address.CityID, address.BenefactorID)
if err != nil {
return entity.Address{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindUnexpected)
}
//nolint
// error is always nil
id, _ := res.LastInsertId()
address.ID = uint(id)
return address, nil
}

View File

@ -0,0 +1,13 @@
package mysqladdress
import "git.gocasts.ir/ebhomengo/niki/repository/mysql"
type DB struct {
conn *mysql.DB
}
func New(conn *mysql.DB) *DB {
return &DB{
conn: conn,
}
}

View File

@ -0,0 +1,47 @@
package mysqladdress
import (
"context"
"database/sql"
"errors"
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
)
// TODO - use this approach or return (bool,entity.Address,error).
func (d DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, error) {
const op = "mysqladdress.IsExistAddressByID"
row := d.conn.Conn().QueryRowContext(ctx, `select * from addresses where id = ?`, id)
address, err := scanAddress(row)
if err != nil {
sErr := sql.ErrNoRows
//TODO-errorsas: second argument to errors.As should not be *error
//nolint
if errors.As(err, &sErr) {
return nil, nil
}
// TODO - log unexpected error for better observability
return nil, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}
return &address, nil
}
func scanAddress(scanner mysql.Scanner) (entity.Address, error) {
var createdAt time.Time
var address entity.Address
err := scanner.Scan(&address.ID, &address.PostalCode, &address.Address, &address.Lat, &address.Lon,
&address.ProvinceID, &address.CityID, &address.BenefactorID,
&createdAt)
return address, err
}

View File

@ -34,6 +34,28 @@ func (d DB) IsExistBenefactorByPhoneNumber(ctx context.Context, phoneNumber stri
return true, Benefactor, nil return true, Benefactor, nil
} }
func (d *DB) IsExistBenefactorByID(ctx context.Context, id uint) (bool, error) {
const op = "mysqlbenefactor.IsExistBenefactorByID"
row := d.conn.Conn().QueryRowContext(ctx, `select * from benefactors where id = ?`, id)
_, err := scanBenefactor(row)
if err != nil {
sErr := sql.ErrNoRows
//TODO-errorsas: second argument to errors.As should not be *error
//nolint
if errors.As(err, &sErr) {
return false, nil
}
// TODO - log unexpected error for better observability
return false, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
}
return true, nil
}
func scanBenefactor(scanner mysql.Scanner) (entity.Benefactor, error) { func scanBenefactor(scanner mysql.Scanner) (entity.Benefactor, error) {
var createdAt time.Time var createdAt time.Time
var benefactor entity.Benefactor var benefactor entity.Benefactor

View File

@ -0,0 +1,13 @@
package mysqlkindboxreq
import "git.gocasts.ir/ebhomengo/niki/repository/mysql"
type DB struct {
conn *mysql.DB
}
func New(conn *mysql.DB) *DB {
return &DB{
conn: conn,
}
}

View File

@ -0,0 +1,27 @@
package mysqlkindboxreq
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (d DB) AddKindBoxReq(ctx context.Context, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error) {
const op = "mysqlkindboxreq.AddKindBoxReq"
res, err := d.conn.Conn().ExecContext(ctx, `insert into kind_box_reqs(benefactor_id,kind_box_type,address_id,count_requested,refer_date,status) values (?,?,?,?,?,?)`,
kindBoxReq.BenefactorID, kindBoxReq.KindBoxType.String(), kindBoxReq.AddressID, kindBoxReq.CountRequested, kindBoxReq.ReferDate, kindBoxReq.Status.String())
if err != nil {
return entity.KindBoxReq{}, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindUnexpected)
}
//nolint
// err is always nil
id, _ := res.LastInsertId()
kindBoxReq.ID = uint(id)
return kindBoxReq, nil
}

View File

@ -0,0 +1,9 @@
-- +migrate Up
CREATE TABLE `provinces` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL ,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- +migrate Down
DROP TABLE `provinces`;

View File

@ -0,0 +1,11 @@
-- +migrate Up
CREATE TABLE `cities` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(191) NOT NULL,
`province_id` INT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`province_id`) REFERENCES `provinces`(`id`)
);
-- +migrate Down
DROP TABLE `cities`;

View File

@ -0,0 +1,19 @@
-- +migrate Up
CREATE TABLE `addresses`
(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`postal_code` VARCHAR(191) NOT NULL,
`address` TEXT NOT NULL,
`lat` FLOAT NOT NULL,
`lon` FLOAT NOT NULL,
`province_id` INT NOT NULL,
`city_id` INT NOT NULL,
`benefactor_id` INT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`province_id`) REFERENCES `provinces` (`id`),
FOREIGN KEY (`city_id`) REFERENCES `cities` (`id`),
FOREIGN KEY (`benefactor_id`) REFERENCES `benefactors` (`id`)
);
-- +migrate Down
DROP TABLE `addresses`;

View File

@ -0,0 +1,19 @@
-- +migrate Up
CREATE TABLE `kind_box_reqs`
(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`benefactor_id` INT NOT NULL,
`kind_box_type` ENUM('on-table','cylindrical','stand-up') NOT NULL,
`address_id` INT NOT NULL,
`count_requested` INT UNSIGNED NOT NULL,
`count_accepted` INT,
`description` TEXT,
`refer_date` DATETIME NOT NULL,
`status` varchar(191),
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`address_id`) REFERENCES `addresses` (`id`),
FOREIGN KEY (`benefactor_id`) REFERENCES `benefactors` (`id`)
);
-- +migrate Down
DROP TABLE `kind_box_reqs`;

0
rtx.log Normal file
View File

View File

@ -1,25 +1,17 @@
package adminkindboxreqservice package adminkindboxreqservice
import ( // func (s Service) Add(ctx context.Context, req param.KindBoxReqAddRequest) (param.KindBoxReqAddResponse, error) {
"context" // const op = "adminkindboxreqservice.Add"
//
entity "git.gocasts.ir/ebhomengo/niki/entity" // kindBoxReq, err := s.repo.AddKindBoxReq(ctx, entity.KindBoxReq{
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" // BenefactorID: req.BenefactorID,
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // KindBoxType: req.TypeID,
) // CountRequested: req.CountRequested,
// Status: entity.KindBoxReqPendingStatus,
func (s Service) Add(ctx context.Context, req param.KindBoxReqAddRequest) (param.KindBoxReqAddResponse, error) { // })
const op = "adminkindboxreqservice.Add" // if err != nil {
// return param.KindBoxReqAddResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
kindBoxReq, err := s.repo.AddKindBoxReq(ctx, entity.KindBoxReq{ // }
BenefactorID: req.BenefactorID, //
TypeID: req.TypeID, // return param.KindBoxReqAddResponse{KindBoxReq: kindBoxReq}, nil
CountRequested: req.CountRequested, //}
Status: entity.KindBoxReqPendingStatus,
})
if err != nil {
return param.KindBoxReqAddResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqAddResponse{KindBoxReq: kindBoxReq}, nil
}

View File

@ -1,28 +1,29 @@
package adminkindboxreqservice package adminkindboxreqservice
import ( //
"context" // import (
// "context"
entity "git.gocasts.ir/ebhomengo/niki/entity" //
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req" // entity "git.gocasts.ir/ebhomengo/niki/entity"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
) // richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
//)
func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) { //
// TODO: can benefactor update its request ? // func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) {
// TODO: Is Update Mothod Service Responsible to check which kindboxreqID belongs to benefactorID ? // // TODO: can benefactor update its request ?
// TODO: updating data(s) may have side-effect on other entities by masood-keshvary accepted -> rejected // // 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
const op = "adminkindboxreqservice.Update" //
// const op = "adminkindboxreqservice.Update"
kindBoxReq, uErr := s.repo.UpdateKindBoxReq(ctx, req.KindBoxReqID, entity.KindBoxReq{ //
BenefactorID: req.BenefactorID, // kindBoxReq, uErr := s.repo.UpdateKindBoxReq(ctx, req.KindBoxReqID, entity.KindBoxReq{
TypeID: req.TypeID, // BenefactorID: req.BenefactorID,
CountRequested: req.CountRequested, // TypeID: req.TypeID,
}) // CountRequested: req.CountRequested,
if uErr != nil { // })
return param.KindBoxReqUpdateResponse{}, richerror.New(op).WithErr(uErr).WithKind(richerror.KindUnexpected) // if uErr != nil {
} // return param.KindBoxReqUpdateResponse{}, richerror.New(op).WithErr(uErr).WithKind(richerror.KindUnexpected)
// }
return param.KindBoxReqUpdateResponse{KindBoxReq: kindBoxReq}, nil //
} // return param.KindBoxReqUpdateResponse{KindBoxReq: kindBoxReq}, nil
//}

View File

@ -0,0 +1,52 @@
package benefactoraddressservice
import (
"context"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
type Repository interface {
CreateBenefactorAddress(ctx context.Context, address entity.Address) (entity.Address, error)
GetAddressByID(ctx context.Context, id uint) (*entity.Address, error)
}
type Service struct {
repo Repository
}
func New(repo Repository) Service {
return Service{repo: repo}
}
func (s Service) Add(ctx context.Context, req param.BenefactorAddAddressRequest) (param.BenefactorAddAddressResponse, error) {
const op = "benefactoraddressservice.Add"
address, err := s.repo.CreateBenefactorAddress(ctx, entity.Address{
PostalCode: req.PostalCode,
Address: req.Address,
Lat: req.Lat,
Lon: req.Lon,
CityID: req.CityID,
ProvinceID: req.ProvinceID,
BenefactorID: req.BenefactorID,
})
if err != nil {
return param.BenefactorAddAddressResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.BenefactorAddAddressResponse{Address: address}, nil
}
func (s Service) AddressExistByID(ctx context.Context, req param.GetAddressByIDRequest) (param.GetAddressByIDResponse, error) {
const op = "benefactorservice.BenefactorExistByID"
address, err := s.repo.GetAddressByID(ctx, req.ID)
if err != nil {
return param.GetAddressByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.GetAddressByIDResponse{Address: address}, nil
}

View File

@ -0,0 +1,19 @@
package benefactorservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) BenefactorExistByID(ctx context.Context, req param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error) {
const op = "benefactorservice.BenefactorExistByID"
isExisted, err := s.repo.IsExistBenefactorByID(ctx, req.ID)
if err != nil {
return param.BenefactorExistByIDResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.BenefactorExistByIDResponse{Existed: isExisted}, nil
}

View File

@ -16,6 +16,7 @@ type Config struct {
type Repository interface { type Repository interface {
IsExistBenefactorByPhoneNumber(ctx context.Context, phoneNumber string) (bool, entity.Benefactor, error) IsExistBenefactorByPhoneNumber(ctx context.Context, phoneNumber string) (bool, entity.Benefactor, error)
CreateBenefactor(ctx context.Context, benefactor entity.Benefactor) (entity.Benefactor, error) CreateBenefactor(ctx context.Context, benefactor entity.Benefactor) (entity.Benefactor, error)
IsExistBenefactorByID(ctx context.Context, id uint) (bool, error)
} }
type AuthGenerator interface { type AuthGenerator interface {

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqservice
import ( import (
"context" "context"
"time"
entity "git.gocasts.ir/ebhomengo/niki/entity" entity "git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
@ -10,10 +11,15 @@ import (
func (s Service) Add(ctx context.Context, req param.KindBoxReqAddRequest) (param.KindBoxReqAddResponse, error) { func (s Service) Add(ctx context.Context, req param.KindBoxReqAddRequest) (param.KindBoxReqAddResponse, error) {
const op = "userkindboxreqservice.Add" const op = "userkindboxreqservice.Add"
t, tErr := time.Parse(time.DateTime, req.ReferDate)
if tErr != nil {
return param.KindBoxReqAddResponse{}, richerror.New(op).WithErr(tErr).WithKind(richerror.KindInvalid)
}
kindBoxReq, err := s.repo.AddKindBoxReq(ctx, entity.KindBoxReq{ kindBoxReq, err := s.repo.AddKindBoxReq(ctx, entity.KindBoxReq{
BenefactorID: req.BenefactorID, BenefactorID: req.BenefactorID,
TypeID: req.TypeID, KindBoxType: req.TypeID,
AddressID: req.AddressID,
ReferDate: t,
CountRequested: req.CountRequested, CountRequested: req.CountRequested,
Status: entity.KindBoxReqPendingStatus, Status: entity.KindBoxReqPendingStatus,
}) })

View File

@ -1,20 +1,13 @@
package benefactorkindboxreqservice package benefactorkindboxreqservice
import ( // func (s Service) Delete(ctx context.Context, req param.KindBoxReqDeleteRequest) (param.KindBoxReqDeleteResponse, error) {
"context" // // TODO: Does business domain need to delete an kindboxreq ?
// const op = "userkindboxreqservice.Delete"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" //
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // dErr := s.repo.DeleteKindBoxReq(ctx, req.KindBoxReqID)
) // if dErr != nil {
// return param.KindBoxReqDeleteResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected)
func (s Service) Delete(ctx context.Context, req param.KindBoxReqDeleteRequest) (param.KindBoxReqDeleteResponse, error) { // }
// TODO: Does business domain need to delete an kindboxreq ? //
const op = "userkindboxreqservice.Delete" // return param.KindBoxReqDeleteResponse{}, nil
//}
dErr := s.repo.DeleteKindBoxReq(ctx, req.KindBoxReqID)
if dErr != nil {
return param.KindBoxReqDeleteResponse{}, richerror.New(op).WithErr(dErr).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqDeleteResponse{}, nil
}

View File

@ -1,19 +1,12 @@
package benefactorkindboxreqservice package benefactorkindboxreqservice
import ( // func (s Service) Get(ctx context.Context, req param.KindBoxReqGetRequest) (param.KindBoxReqGetResponse, error) {
"context" // const op = "userkindboxreqservice.Get"
//
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" // kindBoxReq, err := s.repo.GetKindBoxReq(ctx, req.KindBoxReqID)
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // if err != nil {
) // return param.KindBoxReqGetResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
// }
func (s Service) Get(ctx context.Context, req param.KindBoxReqGetRequest) (param.KindBoxReqGetResponse, error) { //
const op = "userkindboxreqservice.Get" // return param.KindBoxReqGetResponse{KindBoxReq: kindBoxReq}, nil
//}
kindBoxReq, err := s.repo.GetKindBoxReq(ctx, req.KindBoxReqID)
if err != nil {
return param.KindBoxReqGetResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqGetResponse{KindBoxReq: kindBoxReq}, nil
}

View File

@ -1,20 +1,13 @@
package benefactorkindboxreqservice package benefactorkindboxreqservice
import ( //// TODO: Pagination, Filters, Sort.
"context" // func (s Service) GetAll(ctx context.Context, req param.KindBoxReqGetAllRequest) (param.KindBoxReqGetAllResponse, error) {
// const op = "userkindboxreqservice.GetAll"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" //
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // allKindBoxReq, err := s.repo.GetAllKindBoxReq(ctx, req.BenefactorID)
) // if err != nil {
// return param.KindBoxReqGetAllResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
// TODO: Pagination, Filters, Sort. // }
func (s Service) GetAll(ctx context.Context, req param.KindBoxReqGetAllRequest) (param.KindBoxReqGetAllResponse, error) { //
const op = "userkindboxreqservice.GetAll" // return param.KindBoxReqGetAllResponse{AllKindBoxReq: allKindBoxReq}, nil
//}
allKindBoxReq, err := s.repo.GetAllKindBoxReq(ctx, req.BenefactorID)
if err != nil {
return param.KindBoxReqGetAllResponse{}, richerror.New(op).WithErr(err).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqGetAllResponse{AllKindBoxReq: allKindBoxReq}, nil
}

View File

@ -8,11 +8,11 @@ import (
type Repository interface { type Repository interface {
AddKindBoxReq(ctx context.Context, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error) AddKindBoxReq(ctx context.Context, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error)
UpdateKindBoxReq(ctx context.Context, kindBoxReqID uint, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error) // UpdateKindBoxReq(ctx context.Context, kindBoxReqID uint, kindBoxReq entity.KindBoxReq) (entity.KindBoxReq, error)
// TODO: can benefactor cancel its request ? // TODO: can benefactor cancel its request ?
DeleteKindBoxReq(ctx context.Context, kindBoxReqID uint) error // DeleteKindBoxReq(ctx context.Context, kindBoxReqID uint) error
GetAllKindBoxReq(ctx context.Context, benefactorID uint) ([]entity.KindBoxReq, error) // GetAllKindBoxReq(ctx context.Context, benefactorID uint) ([]entity.KindBoxReq, error)
GetKindBoxReq(ctx context.Context, kindBoxReqID uint) (entity.KindBoxReq, error) // GetKindBoxReq(ctx context.Context, kindBoxReqID uint) (entity.KindBoxReq, error)
} }
type Service struct { type Service struct {

View File

@ -1,26 +1,18 @@
package benefactorkindboxreqservice package benefactorkindboxreqservice
import ( // func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) {
"context" // // TODO: can benefactor update its request ?
// // TODO: Is Update Mothod Service Responsible to check which kindboxreqID belongs to benefactorID ?
entity "git.gocasts.ir/ebhomengo/niki/entity" // const op = "userkindboxreqservice.Update"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" //
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error" // kindBoxReq, uErr := s.repo.UpdateKindBoxReq(ctx, req.KindBoxReqID, entity.KindBoxReq{
) // BenefactorID: req.BenefactorID,
// KindBoxType: req.TypeID,
func (s Service) Update(ctx context.Context, req param.KindBoxReqUpdateRequest) (param.KindBoxReqUpdateResponse, error) { // CountRequested: req.CountRequested,
// TODO: can benefactor update its request ? // })
// TODO: Is Update Mothod Service Responsible to check which kindboxreqID belongs to benefactorID ? // if uErr != nil {
const op = "userkindboxreqservice.Update" // return param.KindBoxReqUpdateResponse{}, richerror.New(op).WithErr(uErr).WithKind(richerror.KindUnexpected)
// }
kindBoxReq, uErr := s.repo.UpdateKindBoxReq(ctx, req.KindBoxReqID, entity.KindBoxReq{ //
BenefactorID: req.BenefactorID, // return param.KindBoxReqUpdateResponse{KindBoxReq: kindBoxReq}, nil
TypeID: req.TypeID, //}
CountRequested: req.CountRequested,
})
if uErr != nil {
return param.KindBoxReqUpdateResponse{}, richerror.New(op).WithErr(uErr).WithKind(richerror.KindUnexpected)
}
return param.KindBoxReqUpdateResponse{KindBoxReq: kindBoxReq}, nil
}

View File

@ -2,6 +2,7 @@ package benefactorkindboxreqvalidator
import ( import (
"errors" "errors"
"time"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req" param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
@ -23,7 +24,17 @@ func (v Validator) ValidateAddRequest(req param.KindBoxReqAddRequest) (map[strin
validation.Field(&req.TypeID, validation.Field(&req.TypeID,
validation.Required, validation.Required,
validation.By(v.doesTypeExist)), validation.By(v.doesTypeExist)),
validation.Field(&req.AddressID,
validation.Required,
validation.By(v.doesAddressExist(req.BenefactorID))),
validation.Field(&req.ReferDate,
validation.Required,
validation.Date(time.DateTime),
),
); err != nil { ); err != nil {
fieldErrors := make(map[string]string) fieldErrors := make(map[string]string)
var errV validation.Errors var errV validation.Errors

View File

@ -17,11 +17,11 @@ func (v Validator) ValidateDeleteRequest(req param.KindBoxReqDeleteRequest) (map
validation.Required, validation.Required,
validation.By(v.doesBenefactorExist)), validation.By(v.doesBenefactorExist)),
validation.Field(&req.KindBoxReqID, // validation.Field(&req.KindBoxReqID,
validation.Required, // validation.Required,
validation.By(v.doesKindBoxRequestExist), // validation.By(v.doesKindBoxRequestExist),
validation.By(v.hasPendingStatus), // validation.By(v.hasPendingStatus),
validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))), // validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))),
); err != nil { ); err != nil {
fieldErrors := make(map[string]string) fieldErrors := make(map[string]string)

View File

@ -17,10 +17,10 @@ func (v Validator) ValidateGetRequest(req param.KindBoxReqGetRequest) (map[strin
validation.Required, validation.Required,
validation.By(v.doesBenefactorExist)), validation.By(v.doesBenefactorExist)),
validation.Field(&req.KindBoxReqID, // validation.Field(&req.KindBoxReqID,
validation.Required, // validation.Required,
validation.By(v.doesKindBoxRequestExist), // validation.By(v.doesKindBoxRequestExist),
validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))), // validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))),
); err != nil { ); err != nil {
fieldErrors := make(map[string]string) fieldErrors := make(map[string]string)

View File

@ -19,11 +19,11 @@ func (v Validator) ValidateUpdateRequest(req param.KindBoxReqUpdateRequest) (map
validation.Required, validation.Required,
validation.By(v.doesBenefactorExist)), validation.By(v.doesBenefactorExist)),
validation.Field(&req.KindBoxReqID, // validation.Field(&req.KindBoxReqID,
validation.Required, // validation.Required,
validation.By(v.doesKindBoxRequestExist), // validation.By(v.doesKindBoxRequestExist),
validation.By(v.hasPendingStatus), // validation.By(v.hasPendingStatus),
validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))), // validation.By(v.doesKindBoxBelongToBenefactor(req.BenefactorID))),
validation.Field(&req.TypeID, validation.Field(&req.TypeID,
validation.Required, validation.Required,

View File

@ -1,31 +1,43 @@
package benefactorkindboxreqvalidator package benefactorkindboxreqvalidator
import ( import (
"context"
"fmt" "fmt"
"git.gocasts.ir/ebhomengo/niki/entity"
addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactore"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg" errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
validation "github.com/go-ozzo/ozzo-validation/v4" validation "github.com/go-ozzo/ozzo-validation/v4"
) )
const ( const (
MinKindBoxReq = 1 MinKindBoxReq uint = 1
MaxKindBoxReq = 100 MaxKindBoxReq uint = 100
) )
type Repository interface { type Repository interface {
BenefactorExist(id uint) (bool, error) // KindBoxReqExist(id uint) (bool, error)
KindBoxReqExist(id uint) (bool, error) // KindBoxBelongToBenefactor(bID uint, kbID uint) (bool, error)
TypeExist(id uint) (bool, error) // PendingStatus(id uint) (bool, error)
KindBoxBelongToBenefactor(bID uint, kbID uint) (bool, error) }
PendingStatus(id uint) (bool, error)
type BenefactorSvc interface {
BenefactorExistByID(ctx context.Context, request param.BenefactorExistByIDRequest) (param.BenefactorExistByIDResponse, error)
}
type AddressSvc interface {
AddressExistByID(ctx context.Context, request addressparam.GetAddressByIDRequest) (addressparam.GetAddressByIDResponse, error)
} }
type Validator struct { type Validator struct {
repo Repository repo Repository
benefactorSvc BenefactorSvc
addressSvc AddressSvc
} }
func New(repo Repository) Validator { func New(repo Repository, benefactorSvc BenefactorSvc, addressSvc AddressSvc) Validator {
return Validator{repo: repo} return Validator{repo: repo, benefactorSvc: benefactorSvc, addressSvc: addressSvc}
} }
func (v Validator) doesBenefactorExist(value interface{}) error { func (v Validator) doesBenefactorExist(value interface{}) error {
@ -33,7 +45,7 @@ func (v Validator) doesBenefactorExist(value interface{}) error {
if !ok { if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
} }
_, err := v.repo.BenefactorExist(benefactorID) _, err := v.benefactorSvc.BenefactorExistByID(context.Background(), param.BenefactorExistByIDRequest{ID: benefactorID})
if err != nil { if err != nil {
return fmt.Errorf(errmsg.ErrorMsgNotFound) return fmt.Errorf(errmsg.ErrorMsgNotFound)
} }
@ -42,39 +54,31 @@ func (v Validator) doesBenefactorExist(value interface{}) error {
} }
func (v Validator) doesTypeExist(value interface{}) error { func (v Validator) doesTypeExist(value interface{}) error {
typeID, ok := value.(uint) typeID, ok := value.(entity.KindBoxType)
if !ok { if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
} }
_, err := v.repo.TypeExist(typeID) if !typeID.IsValid() {
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) doesAddressExist(benefactorID uint) validation.RuleFunc {
kindBoxReqID, ok := value.(uint)
if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
_, err := v.repo.KindBoxReqExist(kindBoxReqID)
if err != nil {
return fmt.Errorf(errmsg.ErrorMsgNotFound)
}
return nil
}
func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.RuleFunc {
return func(value interface{}) error { return func(value interface{}) error {
kbID, ok := value.(uint) addressID, ok := value.(uint)
if !ok { if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
address, err := v.addressSvc.AddressExistByID(context.Background(), addressparam.GetAddressByIDRequest{ID: addressID})
if err != nil {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
}
if address.Address == nil {
return fmt.Errorf(errmsg.ErrorMsgNotFound) return fmt.Errorf(errmsg.ErrorMsgNotFound)
} }
_, err := v.repo.KindBoxBelongToBenefactor(benefactorID, kbID) if address.Address.BenefactorID != benefactorID {
if err != nil {
return fmt.Errorf(errmsg.ErrorMsgNotFound) return fmt.Errorf(errmsg.ErrorMsgNotFound)
} }
@ -82,15 +86,43 @@ func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.R
} }
} }
func (v Validator) hasPendingStatus(value interface{}) error { // func (v Validator) doesKindBoxRequestExist(value interface{}) error {
kindboxID, ok := value.(uint) // kindBoxReqID, ok := value.(uint)
if !ok { // if !ok {
return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong) // return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
} // }
_, err := v.repo.PendingStatus(kindboxID) // _, err := v.repo.KindBoxReqExist(kindBoxReqID)
if err != nil { // if err != nil {
return fmt.Errorf(errmsg.ErrorMsgNotFound) // return fmt.Errorf(errmsg.ErrorMsgNotFound)
} // }
//
return nil // return nil
} //}
//
// func (v Validator) doesKindBoxBelongToBenefactor(benefactorID uint) validation.RuleFunc {
// return func(value interface{}) error {
// kbID, ok := value.(uint)
// if !ok {
// return fmt.Errorf(errmsg.ErrorMsgNotFound)
// }
// _, err := v.repo.KindBoxBelongToBenefactor(benefactorID, kbID)
// if err != nil {
// return fmt.Errorf(errmsg.ErrorMsgNotFound)
// }
//
// return nil
// }
//}
//
// func (v Validator) hasPendingStatus(value interface{}) error {
// kindboxID, ok := value.(uint)
// if !ok {
// return fmt.Errorf(errmsg.ErrorMsgSomethingWentWrong)
// }
// _, err := v.repo.PendingStatus(kindboxID)
// if err != nil {
// return fmt.Errorf(errmsg.ErrorMsgNotFound)
// }
//
// return nil
//}