From 1811d1dcc8c30c5bf3d43adab15303c27c2bbc8c Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Tue, 15 Jul 2025 10:25:22 +0700 Subject: [PATCH] :triangular_flag_on_post: (role) create user role assignment module create module for assign to user and unassign role from user --- prisma/schema.prisma | 17 +++++++- .../UserRoleAssignment.controller.ts | 39 ------------------- src/modules/userRole/index.ts | 4 +- .../userRoleAssignment.repository.ts | 22 ----------- .../services/userRoleAssignment.service.ts | 18 --------- src/modules/userRole/userRole.types.ts | 4 -- .../controller/assignRoleToUser.controller.ts | 31 +++++++++++++++ src/modules/userRoleAssignment/index.ts | 6 +++ .../assignRoleToUser.repository.ts | 16 ++++++++ .../schemas/assignRoleToUser.schema.ts | 6 +++ .../services/assignRoleToUser.service.ts | 14 +++++++ .../userRoleAssignment.model.ts | 3 ++ .../userRoleAssignment.types.ts | 4 ++ 13 files changed, 96 insertions(+), 88 deletions(-) delete mode 100644 src/modules/userRole/controller/UserRoleAssignment.controller.ts delete mode 100644 src/modules/userRole/repositories/userRoleAssignment.repository.ts delete mode 100644 src/modules/userRole/services/userRoleAssignment.service.ts create mode 100644 src/modules/userRoleAssignment/controller/assignRoleToUser.controller.ts create mode 100644 src/modules/userRoleAssignment/index.ts create mode 100644 src/modules/userRoleAssignment/repositories/assignRoleToUser.repository.ts create mode 100644 src/modules/userRoleAssignment/schemas/assignRoleToUser.schema.ts create mode 100644 src/modules/userRoleAssignment/services/assignRoleToUser.service.ts create mode 100644 src/modules/userRoleAssignment/userRoleAssignment.model.ts create mode 100644 src/modules/userRoleAssignment/userRoleAssignment.types.ts diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1dbdea7..bfdbf50 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -201,7 +201,7 @@ model User { gender UserGender? phoneCC Int? phoneNumber Int? - roles UserRole[] @relation("UserRoles") + roles UserRoleAssignment[] bioProfile String? @db.Text avatar String? @db.Text commentBackground String? @db.Text @@ -284,10 +284,23 @@ model UserRole { createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt - users User[] @relation("UserRoles") + users UserRoleAssignment[] @@map("user_roles") } +model UserRoleAssignment { + user User @relation(fields: [userId], references: [id]) + userId String + + role UserRole @relation(fields: [roleId], references: [id]) + roleId String + + assignmentAt DateTime @default(now()) + + @@id([userId, roleId]) + @@map("user_role_assignments") +} + model UserNotification { id String @id @default(uuid()) title String @db.VarChar(255) diff --git a/src/modules/userRole/controller/UserRoleAssignment.controller.ts b/src/modules/userRole/controller/UserRoleAssignment.controller.ts deleted file mode 100644 index 3d68a79..0000000 --- a/src/modules/userRole/controller/UserRoleAssignment.controller.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Context } from "elysia"; -import { userRoleAssignmentSchema } from "../schemas/userRoleAssignment.schema"; -import { mainErrorHandler } from "../../../helpers/error/handler"; -import { userRoleAssignmentService } from "../services/userRoleAssignment.service"; -import { - returnErrorResponse, - returnWriteResponse, -} from "../../../helpers/callback/httpResponse"; - -export const userRoleAssignmentController = async (ctx: Context) => { - // Validate form input using zod schema - const validation = userRoleAssignmentSchema.safeParse(ctx.body); - if (!validation.success) - return returnErrorResponse( - ctx.set, - 400, - "Validation error", - validation.error - ); - - try { - // Store the userId and roleId from the validated data - const payload = { - userId: validation.data.userId, - roleId: validation.data.roleId, - }; - - // Call the service to assign the user role - const AssignUserRole = await userRoleAssignmentService(payload); - return returnWriteResponse( - ctx.set, - 201, - "User role assignment successfully", - AssignUserRole - ); - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/userRole/index.ts b/src/modules/userRole/index.ts index 5da84e5..753ed18 100644 --- a/src/modules/userRole/index.ts +++ b/src/modules/userRole/index.ts @@ -1,11 +1,9 @@ import Elysia from "elysia"; import { createUserRoleController } from "./controller/createUserRole.controller"; import { unautenticatedMiddleware } from "../../middleware/auth/unauthenticated.middleware"; -import { userRoleAssignmentController } from "./controller/userRoleAssignment.controller"; export const userRoleModule = new Elysia({ prefix: "/roles" }) .get("/", () => "Hello User Role Module", { beforeHandle: unautenticatedMiddleware, }) - .post("/", createUserRoleController) - .post("/assign", userRoleAssignmentController); // need fix and it just for development only! + .post("/", createUserRoleController); diff --git a/src/modules/userRole/repositories/userRoleAssignment.repository.ts b/src/modules/userRole/repositories/userRoleAssignment.repository.ts deleted file mode 100644 index 6f3203d..0000000 --- a/src/modules/userRole/repositories/userRoleAssignment.repository.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { userModel } from "../../user/user.model"; -import { UserRoleAssignment } from "../userRole.types"; - -export const userRoleAssignmentRepository = async ({ - userId, - roleId, -}: UserRoleAssignment) => { - const userAssigned = await userModel.update({ - where: { - id: userId, - }, - data: { - roles: { - connect: { - id: roleId, - }, - }, - }, - }); - - return userAssigned; -}; diff --git a/src/modules/userRole/services/userRoleAssignment.service.ts b/src/modules/userRole/services/userRoleAssignment.service.ts deleted file mode 100644 index d165611..0000000 --- a/src/modules/userRole/services/userRoleAssignment.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { userRoleAssignmentRepository } from "../repositories/userRoleAssignment.repository"; -import { UserRoleAssignment } from "../userRole.types"; - -export const userRoleAssignmentService = async ({ - userId, - roleId, -}: UserRoleAssignment) => { - try { - const assignRoleToUser = await userRoleAssignmentRepository({ - userId, - roleId, - }); - return assignRoleToUser; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/userRole/userRole.types.ts b/src/modules/userRole/userRole.types.ts index ef10ce3..e69de29 100644 --- a/src/modules/userRole/userRole.types.ts +++ b/src/modules/userRole/userRole.types.ts @@ -1,4 +0,0 @@ -export interface UserRoleAssignment { - userId: string; - roleId: string; -} diff --git a/src/modules/userRoleAssignment/controller/assignRoleToUser.controller.ts b/src/modules/userRoleAssignment/controller/assignRoleToUser.controller.ts new file mode 100644 index 0000000..892c977 --- /dev/null +++ b/src/modules/userRoleAssignment/controller/assignRoleToUser.controller.ts @@ -0,0 +1,31 @@ +import { + returnErrorResponse, + returnWriteResponse, +} from "../../../helpers/callback/httpResponse"; +import { Context } from "elysia"; +import { assignRoleToUserSchema } from "../schemas/assignRoleToUser.schema"; +import { mainErrorHandler } from "../../../helpers/error/handler"; +import { assignRoleToUserService } from "../services/assignRoleToUser.service"; + +export const assignRoleToUserController = async (ctx: Context) => { + const validation = assignRoleToUserSchema.safeParse(ctx.body); + if (!validation.success) + return returnErrorResponse( + ctx.set, + 400, + "Invalid Request", + validation.error + ); + + try { + const assignRoleToUser = await assignRoleToUserService(validation.data); + return returnWriteResponse( + ctx.set, + 201, + "User Role Assigned Successfully", + assignRoleToUser + ); + } catch (error) { + return mainErrorHandler(ctx.set, error); + } +}; diff --git a/src/modules/userRoleAssignment/index.ts b/src/modules/userRoleAssignment/index.ts new file mode 100644 index 0000000..37d06a7 --- /dev/null +++ b/src/modules/userRoleAssignment/index.ts @@ -0,0 +1,6 @@ +import Elysia from "elysia"; +import { assignRoleToUserController } from "./controller/assignRoleToUser.controller"; + +export const userRoleAssignmentModule = new Elysia({ + prefix: "/role-assignments", +}).post("/assign", assignRoleToUserController); diff --git a/src/modules/userRoleAssignment/repositories/assignRoleToUser.repository.ts b/src/modules/userRoleAssignment/repositories/assignRoleToUser.repository.ts new file mode 100644 index 0000000..107963e --- /dev/null +++ b/src/modules/userRoleAssignment/repositories/assignRoleToUser.repository.ts @@ -0,0 +1,16 @@ +import { userRoleAssignmentModel } from "../userRoleAssignment.model"; +import { InputUserRoleAssignment } from "../userRoleAssignment.types"; + +export const assignRoleToUserRepository = async ({ + userId, + roleId, +}: InputUserRoleAssignment) => { + const assignRoleToUser = await userRoleAssignmentModel.create({ + data: { + userId, + roleId, + }, + }); + + return assignRoleToUser; +}; diff --git a/src/modules/userRoleAssignment/schemas/assignRoleToUser.schema.ts b/src/modules/userRoleAssignment/schemas/assignRoleToUser.schema.ts new file mode 100644 index 0000000..1c8760b --- /dev/null +++ b/src/modules/userRoleAssignment/schemas/assignRoleToUser.schema.ts @@ -0,0 +1,6 @@ +import z from "zod"; + +export const assignRoleToUserSchema = z.object({ + userId: z.string(), + roleId: z.string(), +}); diff --git a/src/modules/userRoleAssignment/services/assignRoleToUser.service.ts b/src/modules/userRoleAssignment/services/assignRoleToUser.service.ts new file mode 100644 index 0000000..e0ca1ae --- /dev/null +++ b/src/modules/userRoleAssignment/services/assignRoleToUser.service.ts @@ -0,0 +1,14 @@ +import { assignRoleToUserRepository } from "../repositories/assignRoleToUser.repository"; +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; +import { InputUserRoleAssignment } from "../userRoleAssignment.types"; + +export const assignRoleToUserService = async ( + payload: InputUserRoleAssignment +) => { + try { + const assignRoleToUser = await assignRoleToUserRepository(payload); + return assignRoleToUser; + } catch (error) { + ErrorForwarder(error); + } +}; diff --git a/src/modules/userRoleAssignment/userRoleAssignment.model.ts b/src/modules/userRoleAssignment/userRoleAssignment.model.ts new file mode 100644 index 0000000..435f8eb --- /dev/null +++ b/src/modules/userRoleAssignment/userRoleAssignment.model.ts @@ -0,0 +1,3 @@ +import { prisma } from "../../utils/databases/prisma/connection"; + +export const userRoleAssignmentModel = prisma.userRoleAssignment; diff --git a/src/modules/userRoleAssignment/userRoleAssignment.types.ts b/src/modules/userRoleAssignment/userRoleAssignment.types.ts new file mode 100644 index 0000000..d96e328 --- /dev/null +++ b/src/modules/userRoleAssignment/userRoleAssignment.types.ts @@ -0,0 +1,4 @@ +export interface InputUserRoleAssignment { + userId: string; + roleId: string; +}