From cb4591e7c893e51256a03898021768e5b99460a0 Mon Sep 17 00:00:00 2001 From: Amir Tavakolian Date: Sun, 24 May 2026 10:38:18 +0330 Subject: [PATCH] add assign role to staff feature --- authorizationapp/delivery/http/handler.go | 15 ++++++++++++ authorizationapp/delivery/http/server.go | 1 + ....sql => 1779100307_create_roles_table.sql} | 0 .../1779100308_create_role_user_table.sql | 20 ++++++++++++++++ domain/authorization/repository/mysql_repo.go | 23 ++++++++++++++++++- domain/authorization/service/assign.go | 15 ++++++++++++ domain/authorization/service/param.go | 5 ++++ domain/authorization/service/repo_contract.go | 1 + 8 files changed, 79 insertions(+), 1 deletion(-) rename domain/authorization/repository/migrations/{1779100307_add_roles_table.sql => 1779100307_create_roles_table.sql} (100%) create mode 100644 domain/authorization/repository/migrations/1779100308_create_role_user_table.sql create mode 100644 domain/authorization/service/assign.go diff --git a/authorizationapp/delivery/http/handler.go b/authorizationapp/delivery/http/handler.go index 6aefe2ee..f0fdbaaf 100644 --- a/authorizationapp/delivery/http/handler.go +++ b/authorizationapp/delivery/http/handler.go @@ -42,3 +42,18 @@ func (r RoleHandler) Update(c echo.Context) error { 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)}) +} \ No newline at end of file diff --git a/authorizationapp/delivery/http/server.go b/authorizationapp/delivery/http/server.go index 2247614f..a9f11a6f 100644 --- a/authorizationapp/delivery/http/server.go +++ b/authorizationapp/delivery/http/server.go @@ -25,6 +25,7 @@ func (s RoleServer) Start() { 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) diff --git a/domain/authorization/repository/migrations/1779100307_add_roles_table.sql b/domain/authorization/repository/migrations/1779100307_create_roles_table.sql similarity index 100% rename from domain/authorization/repository/migrations/1779100307_add_roles_table.sql rename to domain/authorization/repository/migrations/1779100307_create_roles_table.sql diff --git a/domain/authorization/repository/migrations/1779100308_create_role_user_table.sql b/domain/authorization/repository/migrations/1779100308_create_role_user_table.sql new file mode 100644 index 00000000..9df39cdd --- /dev/null +++ b/domain/authorization/repository/migrations/1779100308_create_role_user_table.sql @@ -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`; diff --git a/domain/authorization/repository/mysql_repo.go b/domain/authorization/repository/mysql_repo.go index c1e312fd..319c0547 100644 --- a/domain/authorization/repository/mysql_repo.go +++ b/domain/authorization/repository/mysql_repo.go @@ -51,7 +51,6 @@ func (m RoleRepo) Update(ctx context.Context, req service.UpdateRoleRequest) (ty return types.ID(req.ID), nil } - func (m RoleRepo) IsRoleExistsByID(ctx context.Context, id types.ID) error { 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 } + +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 +} diff --git a/domain/authorization/service/assign.go b/domain/authorization/service/assign.go new file mode 100644 index 00000000..9826ea67 --- /dev/null +++ b/domain/authorization/service/assign.go @@ -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 +} diff --git a/domain/authorization/service/param.go b/domain/authorization/service/param.go index f5a16fe5..b1d43c88 100644 --- a/domain/authorization/service/param.go +++ b/domain/authorization/service/param.go @@ -15,3 +15,8 @@ type UpdateRoleRequest struct { ID types.ID `json:"id"` RoleRequest } + +type AssignRoleToStaffRequest struct { + StaffID types.ID `json:"staff_id"` + RolesID []types.ID `json:"roles_id"` +} diff --git a/domain/authorization/service/repo_contract.go b/domain/authorization/service/repo_contract.go index c4055fd8..d5e7455a 100644 --- a/domain/authorization/service/repo_contract.go +++ b/domain/authorization/service/repo_contract.go @@ -9,4 +9,5 @@ type RoleRepo interface { Store(ctx context.Context, req StoreRoleRequest) (types.ID, error) Update(ctx context.Context, req UpdateRoleRequest) (types.ID, error) IsRoleExistsByID(ctx context.Context, id types.ID) error + AssignRoleToStaff(ctx context.Context, staffID types.ID, rolesID []types.ID) error }