Compare commits

...

2 Commits

Author SHA1 Message Date
Amir Tavakolian cb4591e7c8 add assign role to staff feature 2026-05-24 10:38:18 +03:30
Amir Tavakolian df16e37860 fix 2026-05-24 08:47:20 +03:30
8 changed files with 108 additions and 20 deletions

View File

@ -3,7 +3,7 @@ package http
import ( import (
"fmt" "fmt"
"git.gocasts.ir/ebhomengo/niki/domain/authorization/service" "git.gocasts.ir/ebhomengo/niki/domain/authorization/service"
"github.com/gin-gonic/gin" "github.com/labstack/echo/v4"
"net/http" "net/http"
) )
@ -15,36 +15,45 @@ func NewRoleHandler(service service.Authorization) RoleHandler {
return RoleHandler{service: service} return RoleHandler{service: service}
} }
func (r RoleHandler) Store(c *gin.Context) { func (r RoleHandler) Store(c echo.Context) error {
var request service.StoreRoleRequest var request service.StoreRoleRequest
err := c.ShouldBindJSON(&request) if err := c.Bind(&request); err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": err.Error()})
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} }
role, err := r.service.Store(c, request) role, err := r.service.Store(c.Request().Context(), request)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return c.JSON(http.StatusBadRequest, echo.Map{"error": err.Error()})
return
} }
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("role %s created successfully", role.Title_fa)}) return c.JSON(http.StatusOK, echo.Map{"message": fmt.Sprintf("role %s created successfully", role.Title_fa)})
} }
func (r RoleHandler) Update(c *gin.Context) { func (r RoleHandler) Update(c echo.Context) error {
var request service.UpdateRoleRequest var request service.UpdateRoleRequest
if err := c.ShouldBindJSON(&request); err != nil { if err := c.Bind(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return c.JSON(http.StatusBadRequest, echo.Map{"error": err.Error()})
return
} }
role, err := r.service.Update(c, request) role, err := r.service.Update(c.Request().Context(), request)
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return c.JSON(http.StatusBadRequest, echo.Map{"error": err.Error()})
return
} }
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("role %s updated successfully", role.Title_fa)}) return c.JSON(http.StatusOK, echo.Map{"message": fmt.Sprintf("role %s updated successfully", role.Title_fa)})
} }
func (r RoleHandler) AssignRoleToStaff(c echo.Context) error {
var request service.AssignRoleToStaffRequest
if err := c.Bind(&request); err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": "Invalid request body", "details": err.Error()})
}
err := r.service.AssignRoleToStaff(c.Request().Context(), request)
if err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": "Failed to assign roles to staff", "details": err.Error()})
}
return c.JSON(http.StatusOK, echo.Map{"message": fmt.Sprintf("Roles assigned to staff ID %d successfully", request.StaffID)})
}

View File

@ -1,7 +1,10 @@
package http package http
import ( import (
"fmt"
"git.gocasts.ir/ebhomengo/niki/pkg/httpserver" "git.gocasts.ir/ebhomengo/niki/pkg/httpserver"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
) )
type RoleServer struct { type RoleServer struct {
@ -14,5 +17,19 @@ func NewRoleServer(cfg httpserver.Config, handler RoleHandler) RoleServer {
} }
func (s RoleServer) Start() { func (s RoleServer) Start() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
group := e.Group("/role")
group.POST("/create", s.handler.Store)
group.PUT("/update/:id", s.handler.Update)
group.POST("/assign", s.handler.AssignRoleToStaff)
address := fmt.Sprintf("%s:%s", s.cfg.Host, s.cfg.Port)
err := e.Start(address)
if err != nil {
e.Logger.Fatal(err)
}
} }

View File

@ -0,0 +1,20 @@
-- +migrate Up
CREATE TABLE IF NOT EXISTS `role_staff` (
`staff_id` BIGINT NOT NULL,
`role_id` BIGINT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`staff_id`, `role_id`),
CONSTRAINT `fk_role_staff_staff`
FOREIGN KEY (`staff_id`) REFERENCES `staffs` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_role_staff_role`
FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
INDEX `idx_role_staff_staff_id` (`staff_id`),
INDEX `idx_role_staff_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- +migrate Down
DROP TABLE IF EXISTS `role_staff`;

View File

@ -51,7 +51,6 @@ func (m RoleRepo) Update(ctx context.Context, req service.UpdateRoleRequest) (ty
return types.ID(req.ID), nil return types.ID(req.ID), nil
} }
func (m RoleRepo) IsRoleExistsByID(ctx context.Context, id types.ID) error { func (m RoleRepo) IsRoleExistsByID(ctx context.Context, id types.ID) error {
const op = "domain.authorization.repository.role.is_exists_by_id" const op = "domain.authorization.repository.role.is_exists_by_id"
@ -62,3 +61,25 @@ func (m RoleRepo) IsRoleExistsByID(ctx context.Context, id types.ID) error {
} }
return nil return nil
} }
func (m RoleRepo) AssignRoleToStaff(ctx context.Context, staffID types.ID, rolesID []types.ID) error {
const op = "domain.authorization.repository.role.assign_role_to_staff"
query := "INSERT INTO role_staff (staff_id, role_id) VALUES "
var args []interface{}
for i, roleID := range rolesID {
if i > 0 {
query += ", "
}
query += "(?, ?)"
args = append(args, staffID, roleID)
}
_, err := m.conn.Conn().ExecContext(ctx, query, args...)
if err != nil {
return richerror.New(op).WithErr(err)
}
return nil
}

View File

@ -0,0 +1,15 @@
package service
import (
"context"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
)
func (a Authorization) AssignRoleToStaff(ctx context.Context, req AssignRoleToStaffRequest) error {
const op = "service.authorization.assign_role_to_staff"
if err := a.roleRepo.AssignRoleToStaff(ctx, req.StaffID, req.RolesID); err != nil {
return richerror.New(op).WithErr(err)
}
return nil
}

View File

@ -15,3 +15,8 @@ type UpdateRoleRequest struct {
ID types.ID `json:"id"` ID types.ID `json:"id"`
RoleRequest RoleRequest
} }
type AssignRoleToStaffRequest struct {
StaffID types.ID `json:"staff_id"`
RolesID []types.ID `json:"roles_id"`
}

View File

@ -9,4 +9,5 @@ type RoleRepo interface {
Store(ctx context.Context, req StoreRoleRequest) (types.ID, error) Store(ctx context.Context, req StoreRoleRequest) (types.ID, error)
Update(ctx context.Context, req UpdateRoleRequest) (types.ID, error) Update(ctx context.Context, req UpdateRoleRequest) (types.ID, error)
IsRoleExistsByID(ctx context.Context, id types.ID) error IsRoleExistsByID(ctx context.Context, id types.ID) error
AssignRoleToStaff(ctx context.Context, staffID types.ID, rolesID []types.ID) error
} }