From 220b552f5d69f2c3d17d73bf1cee49101820cab8 Mon Sep 17 00:00:00 2001 From: Muhammad Zhafran Ilham Date: Mon, 3 Aug 2026 23:30:37 +0700 Subject: [PATCH] feat(certificate): menambahkan snapshot posisi intern di certificate --- .../migration.sql | 2 ++ prisma/schema.prisma | 13 +++++----- .../repositories/certificate.repository.js | 15 +++++++++++ .../services/certificate.service.js | 26 +++++++++++++++---- src/routes/certificate.routes.js | 9 +++++++ 5 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 prisma/migrations/20260803161554_add_intern_position_to_certificate/migration.sql diff --git a/prisma/migrations/20260803161554_add_intern_position_to_certificate/migration.sql b/prisma/migrations/20260803161554_add_intern_position_to_certificate/migration.sql new file mode 100644 index 0000000..45fb744 --- /dev/null +++ b/prisma/migrations/20260803161554_add_intern_position_to_certificate/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE `certificate` ADD COLUMN `intern_position` VARCHAR(255) NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 379715d..7773980 100755 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -359,12 +359,13 @@ enum SubmissionType { } model Certificate { - id Int @id @default(autoincrement()) - uuid String @unique @default(uuid()) @db.VarChar(36) - id_project Int - id_user Int - certificate_no String @unique @db.VarChar(255) - issued_at DateTime @default(now()) + id Int @id @default(autoincrement()) + uuid String @unique @default(uuid()) @db.VarChar(36) + id_project Int + id_user Int + certificate_no String @unique @db.VarChar(255) + intern_position String? @db.VarChar(255) + issued_at DateTime @default(now()) project Project @relation(fields: [id_project], references: [id], map: "certificate_id_project_foreign") user User @relation(fields: [id_user], references: [id], map: "certificate_id_user_foreign") diff --git a/src/modules/certificate/repositories/certificate.repository.js b/src/modules/certificate/repositories/certificate.repository.js index 1bd3d3d..cc2b46b 100644 --- a/src/modules/certificate/repositories/certificate.repository.js +++ b/src/modules/certificate/repositories/certificate.repository.js @@ -89,6 +89,21 @@ class CertificateRepository { }, select: { id: true, + user: { + select: { + id: true, + intern_position: true, + lamaran_magang: { + select: { + lowongan_magang: { + select: { + posisi: true + } + } + } + } + } + } }, }, }, diff --git a/src/modules/certificate/services/certificate.service.js b/src/modules/certificate/services/certificate.service.js index 2a64bb0..88c876c 100644 --- a/src/modules/certificate/services/certificate.service.js +++ b/src/modules/certificate/services/certificate.service.js @@ -67,11 +67,13 @@ class CertificateService { const count = await certificateRepository.maxSequenceByProject(id_project); const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${count + 1}`; + const internPosition = this.getInternPositionFromProjectInfo(projectInfo); const certificateData = { id_project: parseInt(id_project), id_user: parseInt(actor.id), certificate_no: certificateNo, + intern_position: internPosition, issued_at: now, }; @@ -147,7 +149,10 @@ class CertificateService { ); } - validatedUsers.push(userId); + validatedUsers.push({ + id: userId, + intern_position: this.getInternPositionFromProjectInfo(projectInfo), + }); } const generatedCertificates = []; @@ -160,13 +165,14 @@ class CertificateService { let currentCount = await certificateRepository.maxSequenceByProject(id_project); - for (const userId of validatedUsers) { + for (const user of validatedUsers) { currentCount++; const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${currentCount}`; const certificateData = { id_project: parseInt(id_project), - id_user: parseInt(userId), + id_user: parseInt(user.id), certificate_no: certificateNo, + intern_position: user.intern_position, issued_at: now, }; @@ -288,10 +294,10 @@ class CertificateService { return data({ uuid: certificate.uuid, intern_name: certificate.user ? certificate.user.full_name : null, + intern_position: certificate.intern_position || null, project: certificate.project ? { id: certificate.project.id, project_name: certificate.project.project_name, - intern_position: certificate.user ? certificate.user.intern_position : null, description: certificate.project.description, certificate_template: certificate.project.certificate_template, start_date: certificate.project.start_date, @@ -358,7 +364,7 @@ class CertificateService { id: cert.user.id, full_name: cert.user.full_name, email: cert.user.email, - intern_position: cert.user.intern_position, + intern_position: cert.user.intern_position || null, } : null, project: cert.project ? { id: cert.project.id, @@ -370,6 +376,16 @@ class CertificateService { } : null, }; } + + getInternPositionFromProjectInfo(projectInfo) { + const user = projectInfo?.members?.[0]?.user; + + return ( + user?.intern_position || + user?.lamaran_magang?.lowongan_magang?.posisi || + null + ); + } } module.exports = new CertificateService(); diff --git a/src/routes/certificate.routes.js b/src/routes/certificate.routes.js index d3f8d73..da36702 100644 --- a/src/routes/certificate.routes.js +++ b/src/routes/certificate.routes.js @@ -27,6 +27,10 @@ const router = express.Router(); * certificate_no: * type: string * example: "CERT/20260609/PRJ2/USR5" + * intern_position: + * type: string + * nullable: true + * example: "Backend Developer" * issued_at: * type: string * format: date-time @@ -45,6 +49,7 @@ const router = express.Router(); * example: "rafi@student.com" * intern_position: * type: string + * nullable: true * example: "Backend Developer" * project: * type: object @@ -376,6 +381,10 @@ router.get('/project/:id_project', verifyJWT, isMentorOrAdmin, certificateContro * intern_name: * type: string * example: "Rafi Athallah" + * intern_position: + * type: string + * nullable: true + * example: "Backend Developer" * project: * type: object * properties: