const prisma = require('../../../helpers/db/db_connection'); class TaskRepository { async findProjectById(idProject) { return prisma.project.findUnique({ where: { id: parseInt(idProject), }, include: { members: { where: { status: 'active', }, select: { id: true, id_user: true, }, }, }, }); } async createTask(taskData) { return prisma.task.create({ data: taskData, }); } async findTasksByProject(idProject) { return prisma.task.findMany({ where: { id_project: parseInt(idProject), }, orderBy: { deadline_at: 'asc', }, include: { submissions: { select: { id: true, id_task: true, id_user: true, file_path: true, url_link: true, submitted_at: true, updated_at: true, files: { select: this.submissionFileSelect(), orderBy: { id: 'asc' } } }, }, }, }); } async findTaskById(idTask) { return prisma.task.findUnique({ where: { id: parseInt(idTask), }, include: { project: { select: { id: true, id_admin: true, slug: true, project_name: true, project_icon: true, status: true, members: { where: { status: 'active', }, include: { user: { select: { id: true, full_name: true, email: true, professional_bio: true, }, }, }, }, }, }, submissions: { include: { user: { select: { id: true, full_name: true, email: true, professional_bio: true, }, }, files: { select: this.submissionFileSelect(), orderBy: { id: 'asc' } } }, }, }, }); } async updateTask(idTask, taskData) { return prisma.task.update({ where: { id: parseInt(idTask), }, data: taskData, }); } async deleteTask(idTask) { return prisma.task.delete({ where: { id: parseInt(idTask), }, }); } async countSubmissionsByTask(idTask) { return prisma.taskSubmission.count({ where: { id_task: parseInt(idTask), }, }); } async checkActiveProjectMember(idProject, idUser) { return prisma.projectMember.findFirst({ where: { id_project: parseInt(idProject), id_user: parseInt(idUser), status: 'active', }, }); } async findSubmissionByTaskAndUser(idTask, idUser) { return prisma.taskSubmission.findUnique({ where: { id_task_id_user: { id_task: parseInt(idTask), id_user: parseInt(idUser), }, }, include: { files: { select: this.submissionFileSelect(), orderBy: { id: 'asc', } } } }); } async findSubmissionById(idSubmission) { return prisma.taskSubmission.findUnique({ where: { id: parseInt(idSubmission), }, include: { task: { select: { id: true, id_project: true, title: true, submission_type: true, deadline_at: true, project: { select: { id: true, project_name: true, status: true, }, }, }, }, user: { select: { id: true, full_name: true, email: true, }, }, files: { select: this.submissionFileSelect(), orderBy: { id: 'asc', } } }, }); } async createSubmission(submissionData, filesData = []) { return prisma.taskSubmission.create({ data: { ...submissionData, files: filesData.length > 0 ? { create: filesData, } : undefined, }, include: { files: { select: this.submissionFileSelect(), orderBy: { id: 'asc', }, }, }, }); } async updateSubmission(idSubmission, submissionData, filesData = null) { return prisma.$transaction(async (tx) => { const submissionId = parseInt(idSubmission); await tx.taskSubmission.update({ where: { id: submissionId, }, data: submissionData, }); if (filesData !== null) { await tx.taskSubmissionFile.deleteMany({ where: { id_submission: submissionId, }, }); if (filesData.length > 0) { await tx.taskSubmissionFile.createMany({ data: filesData.map((file) => ({ ...file, id_submission: submissionId, })), }); } } return tx.taskSubmission.findUnique({ where: { id: submissionId, }, include: { files: { select: { id: true, file_path: true, original_name: true, mime_type: true, size_bytes: true, created_at: true, }, orderBy: { id: 'asc', }, }, }, }); }); } async deleteSubmission(idSubmission) { return prisma.taskSubmission.delete({ where: { id: parseInt(idSubmission), }, }); } async findProjectByIdOrSlug(identifier) { if (/^\d+$/.test(String(identifier))) { return this.findProjectById(identifier); } return prisma.project.findUnique({ where: { slug: identifier, }, include: { members: { where: { status: 'active', }, select: { id: true, id_user: true, }, }, }, }); } async findTaskBySlug(idProject, slug) { return prisma.task.findUnique({ where: { id_project_slug: { id_project: parseInt(idProject), slug, }, }, include: { project: { select: { id: true, id_admin: true, slug: true, project_name: true, project_icon: true, status: true, members: { where: { status: 'active', }, include: { user: { select: { id: true, full_name: true, email: true, professional_bio: true, }, }, }, }, }, }, submissions: { include: { user: { select: { id: true, full_name: true, email: true, professional_bio: true, }, }, files: { select: this.submissionFileSelect(), orderBy: { id: 'asc' } } }, }, }, }); } async findTaskSlugExists(idProject, slug, excludeTaskId = null) { const where = { id_project: parseInt(idProject), slug, }; if (excludeTaskId) { where.id = { not: parseInt(excludeTaskId), }; } const task = await prisma.task.findFirst({ where, select: { id: true, }, }); return Boolean(task); } submissionFileSelect() { return { id: true, file_path: true, original_name: true, mime_type: true, size_bytes: true, created_at: true, }; } } module.exports = new TaskRepository();