🚩 (role) create user role assignment module

create module for assign to user and unassign role from user
This commit is contained in:
Rafi Arrafif
2025-07-15 10:25:22 +07:00
parent 6decfe0c93
commit 1811d1dcc8
13 changed files with 96 additions and 88 deletions

View File

@ -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)

View File

@ -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);
}
};

View File

@ -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);

View File

@ -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;
};

View File

@ -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);
}
};

View File

@ -1,4 +0,0 @@
export interface UserRoleAssignment {
userId: string;
roleId: string;
}

View File

@ -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);
}
};

View File

@ -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);

View File

@ -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;
};

View File

@ -0,0 +1,6 @@
import z from "zod";
export const assignRoleToUserSchema = z.object({
userId: z.string(),
roleId: z.string(),
});

View File

@ -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);
}
};

View File

@ -0,0 +1,3 @@
import { prisma } from "../../utils/databases/prisma/connection";
export const userRoleAssignmentModel = prisma.userRoleAssignment;

View File

@ -0,0 +1,4 @@
export interface InputUserRoleAssignment {
userId: string;
roleId: string;
}