Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/controllers/task.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,34 @@ class TaskController {
next(error);
}
}

// 세부 TASK 담당자 설정 API
async setSubTaskAssignee(req, res, next) {
try {
const { subTaskId } = req.params;
const { assigneeId } = req.body;

console.log('Request - subTaskId:', subTaskId, 'assigneeId:', assigneeId);

const result = await taskService.setSubTaskAssignee(parseInt(subTaskId), assigneeId);

console.log('Service result:', result);

const responseData = {
resultType: 'SUCCESS',
message: '담당자가 지정되었습니다.',
data: {
sub_task_id: result.subTaskId,
assignee_id: result.assigneeId
}
};

return res.status(200).json(responseData);
} catch (error) {
console.error('Error in setSubTaskAssignee:', error);
next(error);
}
}
}

export default new TaskController();
6 changes: 6 additions & 0 deletions src/routes/task.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ router.patch(
taskController.updateSubTaskDeadline
);

// 세부 TASK 담당자 설정 API
router.patch(
'/subtask/:subTaskId/assignee',
taskController.setSubTaskAssignee
);

export default router;
110 changes: 110 additions & 0 deletions src/services/task.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,116 @@ class TaskService {
throw error;
}
}

// 세부 TASK 담당자 설정 API
async setSubTaskAssignee(subTaskId, assigneeId) {
console.log('Service - subTaskId:', subTaskId, 'assigneeId:', assigneeId);

try {
// ID 유효성 검사
const parsedSubTaskId = parseInt(subTaskId);
if (isNaN(parsedSubTaskId)) {
const error = new Error('유효하지 않은 세부 태스크 ID입니다.');
error.status = 400;
throw error;
}

// 서브태스크와 관련된 Task, Member 정보 조회
const existingTask = await prisma.subTask.findUnique({
where: { id: parsedSubTaskId },
include: {
task: {
include: {
members: {
include: {
user: true
}
},
folder: true
}
},
assignee: true
}
});

console.log('Existing task with members:', JSON.stringify(existingTask, null, 2));

if (!existingTask) {
const error = new Error('해당하는 세부 태스크를 찾을 수 없습니다.');
error.status = 404;
throw error;
}

const task = existingTask.task;
const isTeamTask = task.type === 'TEAM';

// assigneeId가 있는 경우에만 멤버 확인
if (assigneeId) {
const parsedAssigneeId = parseInt(assigneeId);
if (isNaN(parsedAssigneeId)) {
const error = new Error('유효하지 않은 담당자 ID입니다.');
error.status = 400;
throw error;
}

if (isTeamTask) {
// 팀 과제인 경우: 팀 멤버인지 확인
const isTeamMember = task.members.some(
member => member.userId === parsedAssigneeId
);

console.log('Is team member:', isTeamMember, 'Team members:', task.members);

if (!isTeamMember) {
const error = new Error('팀원만 담당자로 지정할 수 있습니다.');
error.status = 400;
throw error;
}
} else {
// 개인 과제인 경우: 본인만 담당자로 지정 가능
const taskOwner = task.members.find(member => member.role === false)?.user;
if (taskOwner && taskOwner.id !== parsedAssigneeId) {
const error = new Error('개인 과제는 본인만 담당자로 지정할 수 있습니다.');
error.status = 400;
throw error;
}
}
}

// 담당자 업데이트 (assigneeId가 null이면 담당자 해제)
const updatedTask = await prisma.subTask.update({
where: { id: parsedSubTaskId },
data: {
assigneeId: assigneeId ? parseInt(assigneeId) : null,
updatedAt: new Date()
},
select: {
id: true,
assigneeId: true
}
});

console.log('Updated task:', updatedTask);

return {
subTaskId: updatedTask.id,
assigneeId: updatedTask.assigneeId
};
} catch (error) {
console.error('Error in setSubTaskAssignee service:', {
message: error.message,
stack: error.stack,
status: error.status
});

if (error.status) {
throw error;
}
error.status = 500;
error.message = '서버 내부 오류가 발생했습니다.';
throw error;
}
}
}

export default new TaskService();