forked from ebhomengo/niki
				
			feat(niki): add benefactor get address
This commit is contained in:
		
							parent
							
								
									ed894c7520
								
							
						
					
					
						commit
						b0f5d5e2f4
					
				| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
package benefactoraddresshandler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	"git.gocasts.ir/ebhomengo/niki/pkg/claim"
 | 
			
		||||
	httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
 | 
			
		||||
	"github.com/labstack/echo/v4"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetAddress godoc
 | 
			
		||||
// @Summary      Get a benefactor address
 | 
			
		||||
// @Tags         Address
 | 
			
		||||
// @Accept       json
 | 
			
		||||
// @Produce      json
 | 
			
		||||
// @Param 		 id path int true "Address ID"
 | 
			
		||||
// @Success      200  {object}  param.GetAddressResponse
 | 
			
		||||
// @Failure      400  {string}  "Bad request"
 | 
			
		||||
// @Security 	 AuthBearerBenefactor
 | 
			
		||||
// @Router       /address/{id} [get]
 | 
			
		||||
func (h Handler) GetAddress(c echo.Context) error {
 | 
			
		||||
	var req param.GetAddressRequest
 | 
			
		||||
	if bErr := echo.PathParamsBinder(c).Uint("id", &req.AddressID).BindError(); bErr != nil {
 | 
			
		||||
		return echo.NewHTTPError(http.StatusBadRequest)
 | 
			
		||||
	}
 | 
			
		||||
	claims := claim.GetClaimsFromEchoContext(c)
 | 
			
		||||
	req.BenefactorID = claims.UserID
 | 
			
		||||
 | 
			
		||||
	if fieldErrors, err := h.addressVld.ValidateGetAddress(req); err != nil {
 | 
			
		||||
		msg, code := httpmsg.Error(err)
 | 
			
		||||
 | 
			
		||||
		return c.JSON(code, echo.Map{
 | 
			
		||||
			"message": msg,
 | 
			
		||||
			"errors":  fieldErrors,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	resp, sErr := h.addressSvc.Get(c.Request().Context(), req)
 | 
			
		||||
	if sErr != nil {
 | 
			
		||||
		msg, code := httpmsg.Error(sErr)
 | 
			
		||||
 | 
			
		||||
		return echo.NewHTTPError(code, msg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return c.JSON(http.StatusOK, resp)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -13,4 +13,6 @@ func (h Handler) SetRoutes(e *echo.Echo) {
 | 
			
		|||
	r.GET("/cities", h.GetAllCities)
 | 
			
		||||
	r.POST("/", h.AddAddress, middleware.Auth(h.authSvc, h.authConfig),
 | 
			
		||||
		middleware.BenefactorAuthorization(entity.UserBenefactorRole))
 | 
			
		||||
	r.GET("/:id", h.GetAddress, middleware.Auth(h.authSvc, h.authConfig),
 | 
			
		||||
		middleware.BenefactorAuthorization(entity.UserBenefactorRole))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										50
									
								
								docs/docs.go
								
								
								
								
							
							
						
						
									
										50
									
								
								docs/docs.go
								
								
								
								
							| 
						 | 
				
			
			@ -116,6 +116,48 @@ const docTemplate = `{
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "/address/{id}": {
 | 
			
		||||
            "get": {
 | 
			
		||||
                "security": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "AuthBearerBenefactor": []
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "consumes": [
 | 
			
		||||
                    "application/json"
 | 
			
		||||
                ],
 | 
			
		||||
                "produces": [
 | 
			
		||||
                    "application/json"
 | 
			
		||||
                ],
 | 
			
		||||
                "tags": [
 | 
			
		||||
                    "Address"
 | 
			
		||||
                ],
 | 
			
		||||
                "summary": "Get a benefactor address",
 | 
			
		||||
                "parameters": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "integer",
 | 
			
		||||
                        "description": "Address ID",
 | 
			
		||||
                        "name": "id",
 | 
			
		||||
                        "in": "path",
 | 
			
		||||
                        "required": true
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "responses": {
 | 
			
		||||
                    "200": {
 | 
			
		||||
                        "description": "OK",
 | 
			
		||||
                        "schema": {
 | 
			
		||||
                            "$ref": "#/definitions/addressparam.GetAddressResponse"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    "400": {
 | 
			
		||||
                        "description": "Bad request",
 | 
			
		||||
                        "schema": {
 | 
			
		||||
                            "type": "string"
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "/admin/kindboxreqs": {
 | 
			
		||||
            "get": {
 | 
			
		||||
                "security": [
 | 
			
		||||
| 
						 | 
				
			
			@ -722,6 +764,14 @@ const docTemplate = `{
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "addressparam.GetAddressResponse": {
 | 
			
		||||
            "type": "object",
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "address": {
 | 
			
		||||
                    "$ref": "#/definitions/entity.Address"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "addressparam.GetAllCitiesResponse": {
 | 
			
		||||
            "type": "object",
 | 
			
		||||
            "properties": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,6 +105,48 @@
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "/address/{id}": {
 | 
			
		||||
            "get": {
 | 
			
		||||
                "security": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "AuthBearerBenefactor": []
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "consumes": [
 | 
			
		||||
                    "application/json"
 | 
			
		||||
                ],
 | 
			
		||||
                "produces": [
 | 
			
		||||
                    "application/json"
 | 
			
		||||
                ],
 | 
			
		||||
                "tags": [
 | 
			
		||||
                    "Address"
 | 
			
		||||
                ],
 | 
			
		||||
                "summary": "Get a benefactor address",
 | 
			
		||||
                "parameters": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "integer",
 | 
			
		||||
                        "description": "Address ID",
 | 
			
		||||
                        "name": "id",
 | 
			
		||||
                        "in": "path",
 | 
			
		||||
                        "required": true
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "responses": {
 | 
			
		||||
                    "200": {
 | 
			
		||||
                        "description": "OK",
 | 
			
		||||
                        "schema": {
 | 
			
		||||
                            "$ref": "#/definitions/addressparam.GetAddressResponse"
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    "400": {
 | 
			
		||||
                        "description": "Bad request",
 | 
			
		||||
                        "schema": {
 | 
			
		||||
                            "type": "string"
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "/admin/kindboxreqs": {
 | 
			
		||||
            "get": {
 | 
			
		||||
                "security": [
 | 
			
		||||
| 
						 | 
				
			
			@ -711,6 +753,14 @@
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "addressparam.GetAddressResponse": {
 | 
			
		||||
            "type": "object",
 | 
			
		||||
            "properties": {
 | 
			
		||||
                "address": {
 | 
			
		||||
                    "$ref": "#/definitions/entity.Address"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "addressparam.GetAllCitiesResponse": {
 | 
			
		||||
            "type": "object",
 | 
			
		||||
            "properties": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,11 @@ definitions:
 | 
			
		|||
      address:
 | 
			
		||||
        $ref: '#/definitions/entity.Address'
 | 
			
		||||
    type: object
 | 
			
		||||
  addressparam.GetAddressResponse:
 | 
			
		||||
    properties:
 | 
			
		||||
      address:
 | 
			
		||||
        $ref: '#/definitions/entity.Address'
 | 
			
		||||
    type: object
 | 
			
		||||
  addressparam.GetAllCitiesResponse:
 | 
			
		||||
    properties:
 | 
			
		||||
      cities:
 | 
			
		||||
| 
						 | 
				
			
			@ -514,6 +519,32 @@ paths:
 | 
			
		|||
      summary: Add a new address for a benefactor
 | 
			
		||||
      tags:
 | 
			
		||||
      - Address
 | 
			
		||||
  /address/{id}:
 | 
			
		||||
    get:
 | 
			
		||||
      consumes:
 | 
			
		||||
      - application/json
 | 
			
		||||
      parameters:
 | 
			
		||||
      - description: Address ID
 | 
			
		||||
        in: path
 | 
			
		||||
        name: id
 | 
			
		||||
        required: true
 | 
			
		||||
        type: integer
 | 
			
		||||
      produces:
 | 
			
		||||
      - application/json
 | 
			
		||||
      responses:
 | 
			
		||||
        "200":
 | 
			
		||||
          description: OK
 | 
			
		||||
          schema:
 | 
			
		||||
            $ref: '#/definitions/addressparam.GetAddressResponse'
 | 
			
		||||
        "400":
 | 
			
		||||
          description: Bad request
 | 
			
		||||
          schema:
 | 
			
		||||
            type: string
 | 
			
		||||
      security:
 | 
			
		||||
      - AuthBearerBenefactor: []
 | 
			
		||||
      summary: Get a benefactor address
 | 
			
		||||
      tags:
 | 
			
		||||
      - Address
 | 
			
		||||
  /address/cities:
 | 
			
		||||
    get:
 | 
			
		||||
      consumes:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,3 +8,11 @@ type GetAddressByIDRequest struct {
 | 
			
		|||
type GetAddressByIDResponse struct {
 | 
			
		||||
	Address *entity.Address
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type GetAddressRequest struct {
 | 
			
		||||
	BenefactorID uint
 | 
			
		||||
	AddressID    uint
 | 
			
		||||
}
 | 
			
		||||
type GetAddressResponse struct {
 | 
			
		||||
	Address entity.Address `json:"address"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,29 @@ func (d *DB) GetAddressByID(ctx context.Context, id uint) (*entity.Address, erro
 | 
			
		|||
	return &address, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *DB) GetAddress(ctx context.Context, addressID uint, benefactorID uint) (entity.Address, error) {
 | 
			
		||||
	const op = "mysqladdress.GetAddress"
 | 
			
		||||
 | 
			
		||||
	row := d.conn.Conn().QueryRowContext(ctx, `select * from addresses where id = ? and benefactor_id = ?`, addressID, benefactorID)
 | 
			
		||||
 | 
			
		||||
	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 entity.Address{}, richerror.New(op).WithMessage(errmsg.ErrorMsgNotFound).
 | 
			
		||||
				WithKind(richerror.KindNotFound)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// TODO - log unexpected error for better observability
 | 
			
		||||
		return entity.Address{}, richerror.New(op).WithErr(err).
 | 
			
		||||
			WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return address, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func scanAddress(scanner mysql.Scanner) (entity.Address, error) {
 | 
			
		||||
	var createdAt, updatedAt time.Time
 | 
			
		||||
	var address entity.Address
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
package benefactoraddressservice
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (s Service) Get(ctx context.Context, req param.GetAddressRequest) (param.GetAddressResponse, error) {
 | 
			
		||||
	const op = "benefactoraddressservice.Get"
 | 
			
		||||
 | 
			
		||||
	address, err := s.repo.GetAddress(ctx, req.AddressID, req.BenefactorID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return param.GetAddressResponse{}, richerror.New(op).WithErr(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return param.GetAddressResponse{Address: address}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -11,6 +11,7 @@ type Repository interface {
 | 
			
		|||
	GetAddressByID(ctx context.Context, id uint) (*entity.Address, error)
 | 
			
		||||
	GetAllProvinces(ctx context.Context) ([]entity.Province, error)
 | 
			
		||||
	GetAllCities(ctx context.Context) ([]entity.City, error)
 | 
			
		||||
	GetAddress(ctx context.Context, addressID uint, benefactorID uint) (entity.Address, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Service struct {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
package benefactoraddressvalidator
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
 | 
			
		||||
	param "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
 | 
			
		||||
	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) ValidateGetAddress(req param.GetAddressRequest) (map[string]string, error) {
 | 
			
		||||
	const op = "benefactorvalidator.ValidateGetRequest"
 | 
			
		||||
	if err := validation.ValidateStruct(&req,
 | 
			
		||||
 | 
			
		||||
		validation.Field(&req.BenefactorID, validation.Required,
 | 
			
		||||
			validation.By(v.doesBenefactorExist)),
 | 
			
		||||
 | 
			
		||||
		validation.Field(&req.AddressID, validation.Required,
 | 
			
		||||
			validation.Min(uint(1))),
 | 
			
		||||
	); 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
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue