forked from ebhomengo/niki
1
0
Fork 0

feat(niki): implement get kind box req by id for admin

This commit is contained in:
Ruhollah 2024-07-21 17:46:01 +03:30
parent 4e75ebc012
commit cd18bd2e71
15 changed files with 444 additions and 10 deletions

View File

@ -0,0 +1,48 @@
package adminkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Get godoc
// @Summary Get a specific kind box req by ID
// @Tags KindBoxReq
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
// @Success 200 {object} param.GetKindBoxReqResponse
// @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
// @Router /admins/kindboxreqs/{id} [get]
func (h Handler) Get(c echo.Context) error {
var req param.GetKindBoxReqRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
if fieldErrors, err := h.adminKindBoxReqVld.ValidateGetRequest(req); err != nil {
msg, code := httpmsg.Error(err)
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: fieldErrors,
})
}
resp, err := h.adminKindBoxReqSvc.Get(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -19,4 +19,6 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission)) r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission)) r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqUpdatePermission)) r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqUpdatePermission))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetPermission))
} }

View File

@ -1242,6 +1242,72 @@ const docTemplate = `{
} }
} }
}, },
"/admins/kindboxreqs/{id}": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Get a specific kind box req by ID",
"parameters": [
{
"type": "integer",
"description": "KindBoxReq ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.GetKindBoxReqResponse"
}
},
"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": [
@ -2239,6 +2305,47 @@ const docTemplate = `{
} }
} }
}, },
"adminkindboxreqparam.GetKindBoxReqResponse": {
"type": "object",
"properties": {
"benefactorID": {
"type": "integer"
},
"countAccepted": {
"type": "integer"
},
"countRequested": {
"type": "integer"
},
"deliverAddressID": {
"type": "integer"
},
"deliverReferDate": {
"type": "string"
},
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"kindBoxType": {
"$ref": "#/definitions/entity.KindBoxType"
},
"senderAgentID": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/entity.KindBoxReqStatus"
}
}
},
"adminkindboxreqparam.KindBoxReqAcceptRequest": { "adminkindboxreqparam.KindBoxReqAcceptRequest": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -1231,6 +1231,72 @@
} }
} }
}, },
"/admins/kindboxreqs/{id}": {
"get": {
"security": [
{
"AuthBearerAdmin": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"KindBoxReq"
],
"summary": "Get a specific kind box req by ID",
"parameters": [
{
"type": "integer",
"description": "KindBoxReq ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/adminkindboxreqparam.GetKindBoxReqResponse"
}
},
"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": [
@ -2228,6 +2294,47 @@
} }
} }
}, },
"adminkindboxreqparam.GetKindBoxReqResponse": {
"type": "object",
"properties": {
"benefactorID": {
"type": "integer"
},
"countAccepted": {
"type": "integer"
},
"countRequested": {
"type": "integer"
},
"deliverAddressID": {
"type": "integer"
},
"deliverReferDate": {
"type": "string"
},
"deliverReferTimeID": {
"type": "integer"
},
"deliveredAt": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"kindBoxType": {
"$ref": "#/definitions/entity.KindBoxType"
},
"senderAgentID": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/entity.KindBoxReqStatus"
}
}
},
"adminkindboxreqparam.KindBoxReqAcceptRequest": { "adminkindboxreqparam.KindBoxReqAcceptRequest": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -179,6 +179,33 @@ definitions:
status: status:
$ref: '#/definitions/entity.KindBoxReqStatus' $ref: '#/definitions/entity.KindBoxReqStatus'
type: object type: object
adminkindboxreqparam.GetKindBoxReqResponse:
properties:
benefactorID:
type: integer
countAccepted:
type: integer
countRequested:
type: integer
deliverAddressID:
type: integer
deliverReferDate:
type: string
deliverReferTimeID:
type: integer
deliveredAt:
type: string
description:
type: string
id:
type: integer
kindBoxType:
$ref: '#/definitions/entity.KindBoxType'
senderAgentID:
type: integer
status:
$ref: '#/definitions/entity.KindBoxReqStatus'
type: object
adminkindboxreqparam.KindBoxReqAcceptRequest: adminkindboxreqparam.KindBoxReqAcceptRequest:
properties: properties:
count_accepted: count_accepted:
@ -1583,6 +1610,48 @@ paths:
summary: Admin get all kindboxreq summary: Admin get all kindboxreq
tags: tags:
- KindBoxReq - KindBoxReq
/admins/kindboxreqs/{id}:
get:
consumes:
- application/json
parameters:
- description: KindBoxReq ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/adminkindboxreqparam.GetKindBoxReqResponse'
"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: Get a specific kind box req by ID
tags:
- KindBoxReq
/admins/login-by-phone: /admins/login-by-phone:
post: post:
consumes: consumes:

View File

@ -16,4 +16,5 @@ const (
AdminKindBoxAssignReceiverAgentPermission = AdminPermission("kindbox-assign_receiver_agent") AdminKindBoxAssignReceiverAgentPermission = AdminPermission("kindbox-assign_receiver_agent")
AdminKindBoxGetAllPermission = AdminPermission("kindbox-getall") AdminKindBoxGetAllPermission = AdminPermission("kindbox-getall")
AdminKindBoxReqUpdatePermission = AdminPermission("kindboxreq-update") AdminKindBoxReqUpdatePermission = AdminPermission("kindboxreq-update")
AdminKindBoxReqGetPermission = AdminPermission("kindboxreq-get")
) )

View File

@ -39,6 +39,7 @@ func main() {
cfg := config.C() cfg := config.C()
db := initDatabase(cfg, migrate) db := initDatabase(cfg, migrate)
defer db.CloseStatements()
redisAdapter := initRedis(cfg) redisAdapter := initRedis(cfg)
dependencies := initDependencies(cfg, redisAdapter, db) dependencies := initDependencies(cfg, redisAdapter, db)

View File

@ -1,12 +1,11 @@
package adminkindboxreqparam package adminkindboxreqparam
import entity "git.gocasts.ir/ebhomengo/niki/entity" import "git.gocasts.ir/ebhomengo/niki/entity"
type KindBoxReqGetRequest struct { type GetKindBoxReqRequest struct {
BenefactorID uint KindBoxID uint `param:"id"`
KindBoxReqID uint
} }
type KindBoxReqGetResponse struct { type GetKindBoxReqResponse struct {
entity.KindBoxReq entity.KindBoxReq
} }

View File

@ -14,6 +14,7 @@ const (
ErrorMsgOtpCodeExist = "please wait a little bit" ErrorMsgOtpCodeExist = "please wait a little bit"
ErrorMsgOtpCodeIsNotValid = "verification code is not valid" ErrorMsgOtpCodeIsNotValid = "verification code is not valid"
ErrorMsgCantScanQueryResult = "can't scan query result" ErrorMsgCantScanQueryResult = "can't scan query result"
ErrorMsgCantPrepareStatement = "can't prepare statement"
ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect" ErrorMsgPhoneNumberOrPassIsIncorrect = "phone number or password is incorrect"
ErrBadRequest = "Bad request" ErrBadRequest = "Bad request"
ErrorMsgAcceptKindBoxReqStatus = "only pending requests will have the ability to be confirmed" ErrorMsgAcceptKindBoxReqStatus = "only pending requests will have the ability to be confirmed"

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"fmt" "fmt"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql" querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
"sync"
"time" "time"
) )
@ -18,6 +19,8 @@ type Config struct {
type DB struct { type DB struct {
config Config config Config
db *querier.SqlDB db *querier.SqlDB
mu sync.Mutex
statements map[string]*sql.Stmt
} }
func (db *DB) Conn() *querier.SqlDB { func (db *DB) Conn() *querier.SqlDB {
@ -48,3 +51,31 @@ func New(config Config) *DB {
return &DB{config: config, db: &querier.SqlDB{db}} return &DB{config: config, db: &querier.SqlDB{db}}
} }
func (p *DB) PrepareStatement(key string, query string) (*sql.Stmt, error) {
p.mu.Lock()
defer p.mu.Unlock()
if stmt, ok := p.statements[key]; ok {
return stmt, nil
}
stmt, err := p.db.Prepare(query)
if err != nil {
return nil, err
}
p.statements[key] = stmt
return stmt, nil
}
func (p *DB) CloseStatements() error {
for _, stmt := range p.statements {
err := stmt.Close()
if err != nil {
return err
}
}
return nil
}

View File

@ -11,8 +11,16 @@ import (
) )
func (d DB) KindBoxRequestExist(id uint) (bool, error) { func (d DB) KindBoxRequestExist(id uint) (bool, error) {
op := richerror.Op("mysqlkindboxreq.KindBoxRequestExist") const op = "mysqlkindboxreq.KindBoxRequestExist"
row := d.conn.Conn().QueryRow(`select * from kind_box_reqs where id = ?`, id)
query := `select * from kind_box_reqs where id = ?`
stmt, err := d.conn.PrepareStatement(op, query)
if err != nil {
return false, richerror.New(op).WithErr(err).
WithMessage(errmsg.ErrorMsgCantPrepareStatement).WithKind(richerror.KindUnexpected)
}
row := stmt.QueryRow(id)
_, sErr := scanKindBoxReq(row) _, sErr := scanKindBoxReq(row)
if sErr != nil { if sErr != nil {
if errors.Is(sErr, sql.ErrNoRows) { if errors.Is(sErr, sql.ErrNoRows) {

View File

@ -13,7 +13,8 @@ ALTER TABLE `admin_access_controls` MODIFY COLUMN `permission`
'kindboxreq-add', 'kindboxreq-add',
'kindbox-assign_receiver_agent', 'kindbox-assign_receiver_agent',
'kindbox-getall', 'kindbox-getall',
'kindboxreq-update' 'kindboxreq-update',
'kindboxreq-get'
) NOT NULL; ) NOT NULL;
-- +migrate Down -- +migrate Down

View File

@ -16,6 +16,8 @@ INSERT INTO `admin_access_controls` (`id`, `actor_id`, `actor_type`,`permission`
(DEFAULT, 1 , 'role','kindboxreq-deliver'), (DEFAULT, 1 , 'role','kindboxreq-deliver'),
(DEFAULT, 2 , 'role','kindboxreq-deliver'), (DEFAULT, 2 , 'role','kindboxreq-deliver'),
(DEFAULT, 3 , 'role','kindboxreq-deliver'), (DEFAULT, 3 , 'role','kindboxreq-deliver'),
(DEFAULT, 1 , 'role','kindboxreq-get'),
(DEFAULT, 2 , 'role','kindboxreq-get'),
(DEFAULT, 1 , 'role','kindboxreq-getall'), (DEFAULT, 1 , 'role','kindboxreq-getall'),
(DEFAULT, 2 , 'role','kindboxreq-getall'), (DEFAULT, 2 , 'role','kindboxreq-getall'),
(DEFAULT, 1 , 'role','kindboxreq-update'), (DEFAULT, 1 , 'role','kindboxreq-update'),

View File

@ -0,0 +1,21 @@
package adminkindboxreqservice
import (
"context"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (s Service) Get(ctx context.Context, request param.GetKindBoxReqRequest) (param.GetKindBoxReqResponse, error) {
const op = "adminkindboxreqservice.Get"
kindBoxReq, err := s.repo.GetByID(ctx, request.KindBoxID)
if err != nil {
return param.GetKindBoxReqResponse{}, richerror.New(op).WithErr(err)
}
return param.GetKindBoxReqResponse{
KindBoxReq: kindBoxReq,
}, nil
}

View File

@ -0,0 +1,36 @@
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) ValidateGetRequest(req param.GetKindBoxReqRequest) (map[string]string, error) {
const op = "adminkindboxreqvalidator.ValidateGetRequest"
if err := validation.ValidateStruct(&req,
validation.Field(&req.KindBoxID, validation.Required, validation.By(v.doesKindBoxRequestExist)),
); 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
}