add controller and service for create user

This commit is contained in:
rafiarrafif
2025-05-07 03:46:22 +07:00
parent c6367c3689
commit 32dc3dae4a
9 changed files with 118 additions and 10 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -8,7 +8,9 @@
}, },
"dependencies": { "dependencies": {
"@prisma/client": "^6.7.0", "@prisma/client": "^6.7.0",
"@types/bcrypt": "^5.0.2",
"@types/jsonwebtoken": "^9.0.9", "@types/jsonwebtoken": "^9.0.9",
"bcrypt": "^5.1.1",
"cookie": "^1.0.2", "cookie": "^1.0.2",
"elysia": "latest", "elysia": "latest",
"joi": "^17.13.3", "joi": "^17.13.3",

View File

@ -0,0 +1,6 @@
import bcrypt from "bcrypt";
export const hashPassword = async (password: string): Promise<string> => {
const saltRounds = Number(process.env.SALT_ROUNDS);
return await bcrypt.hash(password, saltRounds);
};

View File

@ -0,0 +1,56 @@
import { Prisma } from "@prisma/client";
import { Context } from "elysia";
import { createUserSchema } from "../user.schema";
import { createUserService } from "../services/createUser.service";
import { PrismaErrorTypes } from "../../../utils/databases/prisma/error/types";
import {
returnErrorResponse,
returnWriteResponse,
} from "../../../helpers/callback/httpResponse";
/**
* @function createUser
* @description Creates a new user in the database.
*
* @param {Context & { body: Prisma.UserCreateInput }} ctx - The context object containing the request body.
* @param {Prisma.UserCreateInput} ctx.body - The user data to be created.
*
* @returns {Promise<Object>} A response object indicating success or failure.
* @throws {Object} An error response object if validation fails or an error occurs during user creation.
*
* @example
* Request route: POST /users
* Request body:
* {
* "username": "john_doe",
* "email": "john@example.com",
* "password": "password123"
* }
*/
export const createUser = async (
ctx: Context & { body: Prisma.UserCreateInput }
) => {
// Validate the user input using a validation schema
const { error } = createUserSchema.validate(ctx.body);
if (error)
return returnErrorResponse(ctx.set, 400, "Invalid user input", error);
// Create the user in the database using the service
createUserService(ctx.body)
.then((result) => {
return returnWriteResponse(
ctx.set,
201,
"User created successfully",
result
);
})
.catch((error: PrismaErrorTypes) => {
return returnErrorResponse(
ctx.set,
error.status,
error.message,
error.details
);
});
};

View File

@ -1,6 +1,7 @@
import Elysia from "elysia"; import Elysia from "elysia";
import { getAllUser } from "./controller/getAllUser.controller"; import { getAllUser } from "./controller/getAllUser.controller";
import { createUser } from "./controller/createUser.controller";
export const userModule = new Elysia({ prefix: "/users" }) export const userModule = new Elysia({ prefix: "/users" })
.get("/", () => "Hello User Module") .get("/", () => getAllUser)
.post("/", () => getAllUser); .post("/", () => createUser);

View File

@ -0,0 +1,22 @@
import { Prisma } from "@prisma/client";
import { hashPassword } from "../../../helpers/security/password/hash";
import { userModel } from "../user.model";
import { handlePrismaError } from "../../../utils/databases/prisma/error/handler";
export const createUserService = async (userData: Prisma.UserCreateInput) => {
const { password, ...rest } = userData; // Destructure the password and the rest of the user data
const hashedPassword = await hashPassword(password); // Hash the password before saving to the database
// Create the user in the database using Prisma
try {
const newUser = await userModel.create({
data: {
...rest,
password: hashedPassword,
},
});
return newUser;
} catch (error) {
return handlePrismaError(error);
}
};

View File

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

View File

@ -0,0 +1,15 @@
import Joi from "joi";
export const createUserSchema = Joi.object({
name: Joi.string().min(4).max(255).required(),
username: Joi.string().min(4).max(255).required(),
email: Joi.string().email().required(),
password: Joi.string().min(8).max(255).required(),
birthdate: Joi.date(),
gender: Joi.string().valid("male", "female"),
phoneCC: Joi.string().min(2).max(2),
phoneNumber: Joi.string().min(7).max(15),
bioProfile: Joi.string().max(300),
profilePicture: Joi.string().uri(),
commentPicture: Joi.string().uri(),
});

View File

@ -4,10 +4,8 @@ import {
returnErrorResponse, returnErrorResponse,
returnWriteResponse, returnWriteResponse,
} from "../../../helpers/callback/httpResponse"; } from "../../../helpers/callback/httpResponse";
import { handlePrismaError } from "../../../utils/databases/prisma/error/handler";
import { createUserRoleSchema } from "../userRole.schema"; import { createUserRoleSchema } from "../userRole.schema";
import { JWTDecodeToken } from "../../../helpers/jwt/decodeToken"; import { JWTDecodeToken } from "../../../helpers/jwt/decodeToken";
import { prisma } from "../../../utils/databases/prisma/connection";
import { createUserRoleService } from "../services/createUserRole.service"; import { createUserRoleService } from "../services/createUserRole.service";
import { PrismaErrorTypes } from "../../../utils/databases/prisma/error/types"; import { PrismaErrorTypes } from "../../../utils/databases/prisma/error/types";
@ -72,10 +70,15 @@ export const createUserRole = async (
}; };
createUserRoleService(dataPayload) createUserRoleService(dataPayload)
.then((result) => .then((result) => {
returnWriteResponse(ctx.set, 201, "User role created", result) return returnWriteResponse(ctx.set, 201, "User role created", result);
) })
.catch((error: PrismaErrorTypes) => .catch((error: PrismaErrorTypes) => {
returnErrorResponse(ctx.set, error.status, error.message, error.details) return returnErrorResponse(
ctx.set,
error.status,
error.message,
error.details
); );
});
}; };