feat(certificate): menambahkan snapshot posisi intern di certificate

This commit is contained in:
Muhammad Zhafran Ilham
2026-08-03 23:30:37 +07:00
parent 9fa0340a09
commit 220b552f5d
5 changed files with 54 additions and 11 deletions
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE `certificate` ADD COLUMN `intern_position` VARCHAR(255) NULL;
+1
View File
@@ -364,6 +364,7 @@ model Certificate {
id_project Int id_project Int
id_user Int id_user Int
certificate_no String @unique @db.VarChar(255) certificate_no String @unique @db.VarChar(255)
intern_position String? @db.VarChar(255)
issued_at DateTime @default(now()) issued_at DateTime @default(now())
project Project @relation(fields: [id_project], references: [id], map: "certificate_id_project_foreign") project Project @relation(fields: [id_project], references: [id], map: "certificate_id_project_foreign")
@@ -89,6 +89,21 @@ class CertificateRepository {
}, },
select: { select: {
id: true, id: true,
user: {
select: {
id: true,
intern_position: true,
lamaran_magang: {
select: {
lowongan_magang: {
select: {
posisi: true
}
}
}
}
}
}
}, },
}, },
}, },
@@ -67,11 +67,13 @@ class CertificateService {
const count = await certificateRepository.maxSequenceByProject(id_project); const count = await certificateRepository.maxSequenceByProject(id_project);
const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${count + 1}`; const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${count + 1}`;
const internPosition = this.getInternPositionFromProjectInfo(projectInfo);
const certificateData = { const certificateData = {
id_project: parseInt(id_project), id_project: parseInt(id_project),
id_user: parseInt(actor.id), id_user: parseInt(actor.id),
certificate_no: certificateNo, certificate_no: certificateNo,
intern_position: internPosition,
issued_at: now, issued_at: now,
}; };
@@ -147,7 +149,10 @@ class CertificateService {
); );
} }
validatedUsers.push(userId); validatedUsers.push({
id: userId,
intern_position: this.getInternPositionFromProjectInfo(projectInfo),
});
} }
const generatedCertificates = []; const generatedCertificates = [];
@@ -160,13 +165,14 @@ class CertificateService {
let currentCount = await certificateRepository.maxSequenceByProject(id_project); let currentCount = await certificateRepository.maxSequenceByProject(id_project);
for (const userId of validatedUsers) { for (const user of validatedUsers) {
currentCount++; currentCount++;
const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${currentCount}`; const certificateNo = `No.${fullYear}/SPI3/CERT/${dateString}/${currentCount}`;
const certificateData = { const certificateData = {
id_project: parseInt(id_project), id_project: parseInt(id_project),
id_user: parseInt(userId), id_user: parseInt(user.id),
certificate_no: certificateNo, certificate_no: certificateNo,
intern_position: user.intern_position,
issued_at: now, issued_at: now,
}; };
@@ -288,10 +294,10 @@ class CertificateService {
return data({ return data({
uuid: certificate.uuid, uuid: certificate.uuid,
intern_name: certificate.user ? certificate.user.full_name : null, intern_name: certificate.user ? certificate.user.full_name : null,
intern_position: certificate.intern_position || null,
project: certificate.project ? { project: certificate.project ? {
id: certificate.project.id, id: certificate.project.id,
project_name: certificate.project.project_name, project_name: certificate.project.project_name,
intern_position: certificate.user ? certificate.user.intern_position : null,
description: certificate.project.description, description: certificate.project.description,
certificate_template: certificate.project.certificate_template, certificate_template: certificate.project.certificate_template,
start_date: certificate.project.start_date, start_date: certificate.project.start_date,
@@ -358,7 +364,7 @@ class CertificateService {
id: cert.user.id, id: cert.user.id,
full_name: cert.user.full_name, full_name: cert.user.full_name,
email: cert.user.email, email: cert.user.email,
intern_position: cert.user.intern_position, intern_position: cert.user.intern_position || null,
} : null, } : null,
project: cert.project ? { project: cert.project ? {
id: cert.project.id, id: cert.project.id,
@@ -370,6 +376,16 @@ class CertificateService {
} : null, } : null,
}; };
} }
getInternPositionFromProjectInfo(projectInfo) {
const user = projectInfo?.members?.[0]?.user;
return (
user?.intern_position ||
user?.lamaran_magang?.lowongan_magang?.posisi ||
null
);
}
} }
module.exports = new CertificateService(); module.exports = new CertificateService();
+9
View File
@@ -27,6 +27,10 @@ const router = express.Router();
* certificate_no: * certificate_no:
* type: string * type: string
* example: "CERT/20260609/PRJ2/USR5" * example: "CERT/20260609/PRJ2/USR5"
* intern_position:
* type: string
* nullable: true
* example: "Backend Developer"
* issued_at: * issued_at:
* type: string * type: string
* format: date-time * format: date-time
@@ -45,6 +49,7 @@ const router = express.Router();
* example: "rafi@student.com" * example: "rafi@student.com"
* intern_position: * intern_position:
* type: string * type: string
* nullable: true
* example: "Backend Developer" * example: "Backend Developer"
* project: * project:
* type: object * type: object
@@ -376,6 +381,10 @@ router.get('/project/:id_project', verifyJWT, isMentorOrAdmin, certificateContro
* intern_name: * intern_name:
* type: string * type: string
* example: "Rafi Athallah" * example: "Rafi Athallah"
* intern_position:
* type: string
* nullable: true
* example: "Backend Developer"
* project: * project:
* type: object * type: object
* properties: * properties: