feat: Invite intern ke project ketika creare project hanya bisa jika intern tidak sedang memiliki active project lain
This commit is contained in:
@@ -390,6 +390,32 @@ class ProjectRepository {
|
|||||||
data: { status },
|
data: { status },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findActiveMembershipsByUserIds(userIds) {
|
||||||
|
return prisma.projectMember.findMany({
|
||||||
|
where: {
|
||||||
|
id_user: {
|
||||||
|
in: userIds.map((id) => parseInt(id)),
|
||||||
|
},
|
||||||
|
status: "active",
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
full_name: true,
|
||||||
|
email: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
project_name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = new ProjectRepository();
|
module.exports = new ProjectRepository();
|
||||||
|
|||||||
@@ -58,6 +58,27 @@ class ProjectService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userIds = users.map((user) => user.id);
|
||||||
|
|
||||||
|
if (userIds.length > 0) {
|
||||||
|
const activeMemberships = await projectRepository.findActiveMembershipsByUserIds(userIds);
|
||||||
|
|
||||||
|
if (activeMemberships.length > 0) {
|
||||||
|
const assignedInterns = activeMemberships.map((membership) => {
|
||||||
|
const email = membership.user?.email || "unknown email";
|
||||||
|
const projectName = membership.project?.project_name || "Unknown Project";
|
||||||
|
|
||||||
|
return `${email} already assigned to ${projectName}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return error(
|
||||||
|
new ConflictError(
|
||||||
|
`One or more interns already have an active project: ${assignedInterns.join(", ")}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const newProjectData = {
|
const newProjectData = {
|
||||||
id_admin: parseInt(actor.id),
|
id_admin: parseInt(actor.id),
|
||||||
project_icon: projectData.project_icon,
|
project_icon: projectData.project_icon,
|
||||||
@@ -69,7 +90,6 @@ class ProjectService {
|
|||||||
status: "active",
|
status: "active",
|
||||||
};
|
};
|
||||||
|
|
||||||
const userIds = users.map((user) => user.id);
|
|
||||||
const project = await projectRepository.createWithMembers(
|
const project = await projectRepository.createWithMembers(
|
||||||
newProjectData,
|
newProjectData,
|
||||||
userIds,
|
userIds,
|
||||||
@@ -441,7 +461,7 @@ class ProjectService {
|
|||||||
const activeMembership = intern.project_members?.[0] || null;
|
const activeMembership = intern.project_members?.[0] || null;
|
||||||
const projectName = activeMembership?.project?.project_name || "Unassigned";
|
const projectName = activeMembership?.project?.project_name || "Unassigned";
|
||||||
const role = intern.lamaran_magang?.lowongan_magang?.posisi || "-";
|
const role = intern.lamaran_magang?.lowongan_magang?.posisi || "-";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: intern.id,
|
id: intern.id,
|
||||||
name: intern.full_name,
|
name: intern.full_name,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ const router = express.Router();
|
|||||||
* example: 2026-08-10
|
* example: 2026-08-10
|
||||||
* member_emails:
|
* member_emails:
|
||||||
* type: array
|
* type: array
|
||||||
|
* description: Optional intern emails to invite. Each intern must already have an active user account and must not be assigned to another active project.
|
||||||
* items:
|
* items:
|
||||||
* type: string
|
* type: string
|
||||||
* format: email
|
* format: email
|
||||||
@@ -459,7 +460,7 @@ const router = express.Router();
|
|||||||
* /project-api/add:
|
* /project-api/add:
|
||||||
* post:
|
* post:
|
||||||
* summary: Create a new project
|
* summary: Create a new project
|
||||||
* description: Create a new Internify LMS project. Admin can optionally invite interns by email.
|
* description: Create a new Internify LMS project. Admin can optionally invite interns by email. Invited interns must not be active members of another project.
|
||||||
* tags: [Project]
|
* tags: [Project]
|
||||||
* security:
|
* security:
|
||||||
* - bearerAuth: []
|
* - bearerAuth: []
|
||||||
|
|||||||
Reference in New Issue
Block a user