refactor: rewrite ke codebase lama

This commit is contained in:
Muhammad Zhafran Ilham
2026-06-07 20:17:49 +07:00
parent ce5487dcbf
commit fe74b2213d
146 changed files with 14608 additions and 6686 deletions
@@ -0,0 +1,126 @@
const hasilResearchService = require('../services/hasilResearch.service');
const { response, error } = require('../../../helpers/utils/wrapper');
const { BadRequestError, InternalServerError } = require('../../../helpers/error');
const { SUCCESS, ERROR } = require('../../../helpers/http-status/status_code');
const { isValidPayload } = require('../../../helpers/utils/validator');
const { createHasilResearchModel, updateHasilResearchModel } = require('../models/hasilResearch.model');
const { deleteFileIfExists } = require('../../../helpers/utils/fileHelper');
class HasilResearchController {
async addHasilResearch(req, res) {
try {
const image = req.file;
const validatePayload = isValidPayload(req.body, createHasilResearchModel);
if (validatePayload.err) {
if (image?.filename) {
await deleteFileIfExists(image.filename);
}
return response(
res,
'fail',
{ err: validatePayload.err, data: null },
'Data tidak valid',
ERROR.EXPECTATION_FAILED
);
}
const result = await hasilResearchService.createHasilResearch(validatePayload.data, image);
if (result.err) {
return response(res, 'fail', result);
}
return response(res, 'success', result, 'Data hasil research berhasil ditambahkan', SUCCESS.CREATED);
} catch (err) {
if (req.file?.filename) {
await deleteFileIfExists(req.file.filename);
}
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR);
}
}
async getHasilResearch(req, res) {
try {
const result = await hasilResearchService.getAllHasilResearch();
if (result.err) {
return response(res, 'fail', result);
}
return response(res, 'success', result, 'Data research berhasil diambil', SUCCESS.OK);
} catch (err) {
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR);
}
}
async getHasilResearchById(req, res) {
try {
const { id } = req.params;
const result = await hasilResearchService.getHasilResearchById(id);
if (result.err) {
return response(res, 'fail', result);
}
return response(res, 'success', result, 'Data research berhasil diambil', SUCCESS.OK);
} catch (err) {
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR);
}
}
async updateHasilResearch(req, res) {
try {
const { id } = req.params;
const image = req.file;
const validatePayload = isValidPayload(req.body, updateHasilResearchModel);
if (validatePayload.err) {
if (image?.filename) {
await deleteFileIfExists(image.filename);
}
return response(
res,
'fail',
{ err: validatePayload.err, data: null },
'Data tidak valid',
ERROR.EXPECTATION_FAILED
);
}
const result = await hasilResearchService.updateHasilResearch(id, validatePayload.data, image);
if (result.err) {
return response(res, 'fail', result);
}
return response(res, 'success', result, 'Data hasil research berhasil diperbarui', SUCCESS.OK);
} catch (err) {
if (req.file?.filename) {
await deleteFileIfExists(req.file.filename);
}
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR);
}
}
async deleteHasilResearch(req, res) {
try {
const { id } = req.params;
const result = await hasilResearchService.deleteHasilResearch(id);
if (result.err) {
return response(res, 'fail', result);
}
return response(res, 'success', result, 'Data hasil research berhasil dihapus', SUCCESS.OK);
} catch (err) {
return response(res, 'fail', error(new InternalServerError(err.message)), 'Terjadi kesalahan yang tidak terduga', ERROR.INTERNAL_ERROR);
}
}
}
module.exports = new HasilResearchController();
+9
View File
@@ -0,0 +1,9 @@
const hasilResearchController = require('./controllers/hasilResearch.controller');
const hasilResearchService = require('./services/hasilResearch.service');
const hasilResearchRepository = require('./repositories/hasilResearch.repository');
module.exports = {
hasilResearchController,
hasilResearchService,
hasilResearchRepository
};
+52
View File
@@ -0,0 +1,52 @@
joi = require('joi');
const urlRegex = /^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/;
const createHasilResearchModel = joi.object().keys({
nama_project: joi.string().max(255).required().messages({
'string.base': 'Nama project harus berupa teks.',
'string.empty': 'Nama project tidak boleh kosong.',
'string.max': 'Nama project maksimal {#limit} karakter.',
'any.required': 'Nama project wajib diisi.',
}),
deskripsi: joi.string().required().messages({
'string.base': 'Deskripsi harus berupa teks.',
'string.empty': 'Deskripsi tidak boleh kosong.',
'any.required': 'Deskripsi wajib diisi.',
}),
link_project: joi.string().pattern(urlRegex).optional().allow('', null).messages({
'string.base': 'Link project harus berupa teks.',
'string.pattern.base': 'Format URL tidak valid.',
}),
image_path: joi.string().optional().allow('', null).messages({
'string.base': 'Path gambar harus berupa teks.',
}),
});
const updateHasilResearchModel = joi.object().keys({
nama_project: joi.string().max(255).optional().messages({
'string.base': 'Nama project harus berupa teks.',
'string.max': 'Nama project maksimal {#limit} karakter.',
}),
deskripsi: joi.string().optional().messages({
'string.base': 'Deskripsi harus berupa teks.',
}),
link_project: joi.string().pattern(urlRegex).optional().allow('', null).messages({
'string.base': 'Link project harus berupa teks.',
'string.pattern.base': 'Format URL tidak valid.',
}),
image_path: joi.string().optional().allow('', null).messages({
'string.base': 'Path gambar harus berupa teks.',
}),
});
module.exports = {
createHasilResearchModel,
updateHasilResearchModel,
};
@@ -0,0 +1,34 @@
const prisma = require('../../../helpers/db/db_connection');
class HasilResearchRepository {
async create(researchData) {
return prisma.hasilResearch.create({
data: researchData,
});
}
async findAll() {
return prisma.hasilResearch.findMany();
}
async findById(id) {
return prisma.hasilResearch.findUnique({
where: { id: parseInt(id) },
});
}
async updateById(id, researchData) {
return prisma.hasilResearch.update({
where: { id: parseInt(id) },
data: researchData,
});
}
async deleteById(id) {
return prisma.hasilResearch.delete({
where: { id: parseInt(id) },
});
}
}
module.exports = new HasilResearchRepository();
+121
View File
@@ -0,0 +1,121 @@
const hasilResearchRepository = require('../repositories/hasilResearch.repository');
const path = require('path');
const { deleteFileIfExists } = require('../../../helpers/utils/fileHelper');
const imageUploadHelper = require('../../../helpers/utils/imageUpload.helper');
const { data, error } = require('../../../helpers/utils/wrapper');
const { NotFoundError } = require('../../../helpers/error');
class HasilResearchService {
async createHasilResearch(researchData, imageFile) {
try {
const imagePath = imageUploadHelper.uploadImage(imageFile);
const newResearchData = {
...researchData,
image_path: imagePath,
};
const result = await hasilResearchRepository.create(newResearchData);
return data(result);
} catch (err) {
if (imageFile?.filename) {
try {
await deleteFileIfExists(imageFile.filename);
} catch (cleanupErr) {
console.error('Failed to cleanup file:', cleanupErr);
}
}
return error(err);
}
}
async getAllHasilResearch() {
try {
const researchList = await hasilResearchRepository.findAll();
return data(researchList);
} catch (err) {
return error(err);
}
}
async getHasilResearchById(id) {
try {
const research = await hasilResearchRepository.findById(id);
if (!research) {
return error(new NotFoundError('Hasil Research Tidak Ditemukan'));
}
return data(research);
} catch (err) {
return error(err);
}
}
async updateHasilResearch(id, researchData, imageFile) {
let oldImagePath = null;
let newImageUploaded = false;
try {
const checkResult = await this.getHasilResearchById(id);
if (checkResult.err) {
return checkResult;
}
const existingResearch = checkResult.data;
let imagePath = existingResearch.image_path;
if (imageFile) {
oldImagePath = existingResearch.image_path;
imagePath = imageUploadHelper.uploadImage(imageFile);
newImageUploaded = true;
if (oldImagePath) {
const oldFileName = path.basename(oldImagePath);
await deleteFileIfExists(oldFileName);
}
}
const updatedResearchData = {
...researchData,
image_path: imagePath,
};
const result = await hasilResearchRepository.updateById(id, updatedResearchData);
return data(result);
} catch (err) {
if (newImageUploaded && imageFile?.filename) {
try {
await deleteFileIfExists(imageFile.filename);
} catch (cleanupErr) {
console.error('Failed to cleanup new file:', cleanupErr);
}
}
return error(err);
}
}
async deleteHasilResearch(id) {
try {
const checkResult = await this.getHasilResearchById(id);
if (checkResult.err) {
return checkResult;
}
const research = checkResult.data;
if (research.image_path) {
const fileName = path.basename(research.image_path);
await deleteFileIfExists(fileName);
}
const result = await hasilResearchRepository.deleteById(id);
return data(result);
} catch (err) {
return error(err);
}
}
}
module.exports = new HasilResearchService();