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
7 changes: 4 additions & 3 deletions prisma/generated/prisma-client-js/edge.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions prisma/generated/prisma-client-js/index-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ exports.ActionType = exports.$Enums.ActionType = {
CREATED: 'CREATED',
UPDATED: 'UPDATED',
DELETED: 'DELETED',
RESTORED: 'RESTORED',
COMMENTED: 'COMMENTED',
STATUS_CHANGED: 'STATUS_CHANGED',
ASSIGNED: 'ASSIGNED',
Expand Down
1 change: 1 addition & 0 deletions prisma/generated/prisma-client-js/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export const ActionType: {
CREATED: 'CREATED',
UPDATED: 'UPDATED',
DELETED: 'DELETED',
RESTORED: 'RESTORED',
COMMENTED: 'COMMENTED',
STATUS_CHANGED: 'STATUS_CHANGED',
ASSIGNED: 'ASSIGNED',
Expand Down
7 changes: 4 additions & 3 deletions prisma/generated/prisma-client-js/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion prisma/generated/prisma-client-js/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "prisma-client-a10afe2d65b1696aceeffd7b7ee9060221c49b4aa8ca29ad38aff4f8c36e19cd",
"name": "prisma-client-9780e8e36b8830e8333f06b5c248c200021c25902ffd14c6f44b19a7776b5264",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",
Expand Down
1 change: 1 addition & 0 deletions prisma/generated/prisma-client-js/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ enum ActionType {
CREATED
UPDATED
DELETED
RESTORED
COMMENTED
STATUS_CHANGED
ASSIGNED
Expand Down
1 change: 1 addition & 0 deletions prisma/generated/prisma-client-js/wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ exports.ActionType = exports.$Enums.ActionType = {
CREATED: 'CREATED',
UPDATED: 'UPDATED',
DELETED: 'DELETED',
RESTORED: 'RESTORED',
COMMENTED: 'COMMENTED',
STATUS_CHANGED: 'STATUS_CHANGED',
ASSIGNED: 'ASSIGNED',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "ActionType" ADD VALUE 'RESTORED';
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ enum ActionType {
CREATED
UPDATED
DELETED
RESTORED
COMMENTED
STATUS_CHANGED
ASSIGNED
Expand Down
203 changes: 203 additions & 0 deletions src/controllers/task.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import {
createTaskValidation,
updateTaskValidation,
} from '../validations/task.validation.js';
import {
createActivityLog,
generateActivityDetails,
} from '../utils/activityLogs.utils.js';

/**
* Helper function to validate required params
Expand Down Expand Up @@ -344,6 +348,37 @@ export const createTask = async (req, res, next) => {
},
});

// Log the activity
await createActivityLog({
entityType: 'TASK',
action: 'CREATED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: sprintId || null,
taskId: task.id,
details: generateActivityDetails('CREATED', null, task),
});

// If task is assigned to someone, log that action too
if (assignedTo) {
await createActivityLog({
entityType: 'TASK',
action: 'ASSIGNED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: sprintId || null,
taskId: task.id,
details: generateActivityDetails('ASSIGNED', null, {
assignedTo,
taskId: task.id,
}),
});
}

// Fetch project members
const projectMembers = await prisma.projectMember.findMany({
where: { projectId },
Expand Down Expand Up @@ -517,6 +552,9 @@ export const updateTask = async (req, res, next) => {
}
}

// Save old task data for activity logging
const oldTaskData = { ...task };

// Update the task
const updatedTask = await prisma.task.update({
where: { id: taskId },
Expand All @@ -536,6 +574,100 @@ export const updateTask = async (req, res, next) => {
},
});

// Log the general update activity
await createActivityLog({
entityType: 'TASK',
action: 'UPDATED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails('UPDATED', oldTaskData, updatedTask),
});

// Assignment change
if (assignedTo !== undefined && assignedTo !== oldTaskData.assignedTo) {
if (assignedTo === null) {
// Task was unassigned
await createActivityLog({
entityType: 'TASK',
action: 'UNASSIGNED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails('UNASSIGNED', oldTaskData, null),
});
} else if (oldTaskData.assignedTo === null) {
// Task was assigned
await createActivityLog({
entityType: 'TASK',
action: 'ASSIGNED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails('ASSIGNED', null, {
assignedTo,
taskId: updatedTask.id,
}),
});
} else {
// Assignment was changed
await createActivityLog({
entityType: 'TASK',
action: 'UNASSIGNED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails('UNASSIGNED', oldTaskData, null),
});

await createActivityLog({
entityType: 'TASK',
action: 'ASSIGNED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails('ASSIGNED', null, {
assignedTo,
taskId: updatedTask.id,
}),
});
}
}

// Sprint change
if (sprintId !== undefined && sprintId !== oldTaskData.sprintId) {
await createActivityLog({
entityType: 'TASK',
action: 'TASK_MOVED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails(
'TASK_MOVED',
oldTaskData,
updatedTask,
),
});
}

return res.status(200).json({
success: true,
message: 'Task updated successfully',
Expand Down Expand Up @@ -625,6 +757,8 @@ export const updateTaskPriority = async (req, res, next) => {
});
}

const oldTaskData = { ...task };

// Update task priority
const updatedTask = await prisma.task.update({
where: { id: taskId },
Expand All @@ -635,6 +769,25 @@ export const updateTaskPriority = async (req, res, next) => {
},
});

// Status change
if (priority && priority !== oldTaskData.priority) {
await createActivityLog({
entityType: 'TASK',
action: 'STATUS_CHANGED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails(
'STATUS_CHANGED',
oldTaskData,
updatedTask,
),
});
}

return res.status(200).json({
success: true,
message: 'Task priority updated successfully',
Expand Down Expand Up @@ -725,6 +878,8 @@ export const updateTaskStatus = async (req, res, next) => {
});
}

const oldTaskData = { ...task };

// Update task status
const updatedTask = await prisma.task.update({
where: { id: taskId },
Expand All @@ -735,6 +890,25 @@ export const updateTaskStatus = async (req, res, next) => {
},
});

// Status change
if (status && status !== oldTaskData.status) {
await createActivityLog({
entityType: 'TASK',
action: 'STATUS_CHANGED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: updatedTask.sprintId || null,
taskId: updatedTask.id,
details: generateActivityDetails(
'STATUS_CHANGED',
oldTaskData,
updatedTask,
),
});
}

return res.status(200).json({
success: true,
message: 'Task status updated successfully',
Expand Down Expand Up @@ -1213,6 +1387,19 @@ export const deleteTask = async (req, res, next) => {
}
});

// Log the delete activity
await createActivityLog({
entityType: 'TASK',
action: 'DELETED',
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: task.sprintId || null,
taskId: task.id,
details: generateActivityDetails('DELETED', task, null),
});

return res.status(200).json({
success: true,
message: `Task ${permanent ? 'permanently ' : ''}deleted successfully`,
Expand Down Expand Up @@ -1367,6 +1554,22 @@ export const restoreTask = async (req, res, next) => {
},
});

// Log the restore activity
await createActivityLog({
entityType: 'TASK',
action: 'UPDATED', // Using UPDATED with specific details
userId: user.id,
organizationId,
teamId,
projectId,
sprintId: restoredTask.sprintId || null,
taskId: restoredTask.id,
details: {
action: 'RESTORE',
restoredAt: new Date(),
},
});

return res.status(200).json({
success: true,
message: `Task restored successfully${restoreSubtasks ? ' with its subtasks' : ''}`,
Expand Down