Merge pull request #32 from internship-humic/feat/notification-system

feat: nambahin link field di Notification
This commit is contained in:
Rafi Athallah
2026-07-06 21:10:25 +07:00
committed by GitHub
7 changed files with 24 additions and 9 deletions
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `notification` ADD COLUMN `link` TEXT NULL;
+1
View File
@@ -380,6 +380,7 @@ model Notification {
id_admin Int? // For mentors/admins
title String @db.VarChar(255)
message String @db.Text
link String? @db.Text
is_read Boolean @default(false)
created_at DateTime @default(now())
@@ -5,13 +5,14 @@ const { data, error } = require('../../../helpers/utils/wrapper');
const { NotFoundError, ForbiddenError, BadRequestError } = require('../../../helpers/error');
class NotificationService {
async createNotificationForIntern(userId, title, message) {
async createNotificationForIntern(userId, title, message, link = '') {
try {
const notification = await notificationRepository.create({
id_user: parseInt(userId),
id_admin: null,
title,
message,
link,
is_read: false
});
@@ -26,13 +27,14 @@ class NotificationService {
}
}
async createNotificationForMentor(adminId, title, message) {
async createNotificationForMentor(adminId, title, message, link = '') {
try {
const notification = await notificationRepository.create({
id_user: null,
id_admin: parseInt(adminId),
title,
message,
link,
is_read: false
});
@@ -47,7 +49,7 @@ class NotificationService {
}
}
async createNotificationForProjectInterns(projectId, title, message) {
async createNotificationForProjectInterns(projectId, title, message, link = '') {
try {
const project = await taskRepository.findProjectById(projectId);
if (!project || !project.members) {
@@ -56,7 +58,7 @@ class NotificationService {
const results = [];
for (const member of project.members) {
const res = await this.createNotificationForIntern(member.id_user, title, message);
const res = await this.createNotificationForIntern(member.id_user, title, message, link);
if (res.data) {
results.push(res.data);
}
@@ -97,7 +97,8 @@ class ProjectService {
await notificationService.createNotificationForIntern(
idUser,
"Diterima ke Proyek",
`Anda telah bergabung ke proyek '${project.project_name}'.`
`Anda telah bergabung ke proyek '${project.project_name}'.`,
`/intern/projects/${project.slug}`
).catch(err => console.error("Failed to send project assignment notification:", err));
}
@@ -711,7 +712,8 @@ class ProjectService {
await notificationService.createNotificationForIntern(
id_user,
"Diterima ke Proyek",
`Anda telah bergabung ke proyek '${project.project_name}'.`
`Anda telah bergabung ke proyek '${project.project_name}'.`,
`/intern/projects/${project.slug}`
).catch(err => console.error("Failed to send project assignment notification:", err));
return data(membership);
+2 -1
View File
@@ -55,7 +55,8 @@ class TaskService {
await notificationService.createNotificationForProjectInterns(
project.id,
"Tugas Baru Ditambahkan",
`Mentor telah membuat tugas baru: '${task.title}' di proyek '${project.project_name}'.`
`Mentor telah membuat tugas baru: '${task.title}' di proyek '${project.project_name}'.`,
`/intern/projects/${project.slug}/${task.slug}`
).catch(err => console.error("Failed to send task creation notifications:", err));
return data(this.mapTask(task));
+4
View File
@@ -28,6 +28,10 @@ const router = express.Router();
* message:
* type: string
* example: "Mentor telah menambahkan tugas baru."
* link:
* type: string
* nullable: true
* example: "/intern/projects/some-project-slug/some-task-slug"
* is_read:
* type: boolean
* example: false
+5 -2
View File
@@ -7,11 +7,14 @@ const BASE_URL = 'http://localhost:9000';
async function runTests() {
console.log('=== STARTING INTEGRATION TESTS FOR NOTIFICATION SYSTEM ===\n');
// 0. Clean up existing memberships for rafi@student.com (user ID 1) to allow project assignment
console.log('0. Cleaning up existing project memberships for rafi@student.com...');
// 0. Clean up existing memberships and notifications for rafi@student.com (user ID 1)
console.log('0. Cleaning up existing project memberships and notifications for rafi@student.com...');
await prisma.projectMember.deleteMany({
where: { id_user: 1 }
});
await prisma.notification.deleteMany({
where: { id_user: 1 }
});
console.log(' Cleanup successful!\n');
let adminToken = '';