mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -23,6 +23,8 @@ const { filterableFields } = require('../../models/task/task.attributes');
|
||||
const { getFieldValues } = require('../../utils/fieldValues.util');
|
||||
const { archiveOne, archiveMany } = require("../../utils/courses/archive.util");
|
||||
const { restoreOne, restoreMany } = require("../../utils/courses/restore.util");
|
||||
const { permanentDeleteOne, permanentDeleteMany } = require("../../utils/courses/permanentDelete.util");
|
||||
const { TaskCompletion } = require('../../models/task/task_completion.mdl');
|
||||
const logActivity = require('../../utils/logActivity.util');
|
||||
|
||||
// ─── URL normalizer — ensures protocol prefix so link_url is never a relative path ──
|
||||
@@ -260,6 +262,76 @@ exports.bulkRestoreTaskLists = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// ─── PERMANENT DELETE ─────────────────────────────────────────────────────────
|
||||
|
||||
exports.permanentlyDeleteTaskList = async (req, res) => {
|
||||
const t = await sequelize.transaction();
|
||||
try {
|
||||
const { taskListId } = req.params;
|
||||
|
||||
const record = await permanentDeleteOne(TaskList, { task_list_id: taskListId }, t);
|
||||
if (record === null) { await t.rollback(); return R.error(res, 'Task list not found.', 404); }
|
||||
if (record === false) { await t.rollback(); return R.error(res, 'Task list must be archived before it can be permanently deleted.', 400); }
|
||||
|
||||
await t.commit();
|
||||
logActivity(req.user.user_id, 'permanently_delete_task_list', { entityType: 'task_list', entityId: Number(taskListId) });
|
||||
return R.success(res, 'Task list permanently deleted.');
|
||||
} catch (err) {
|
||||
await t.rollback();
|
||||
console.error('[ADMIN][PERMANENT DELETE TASK LIST]', err);
|
||||
return R.error(res, 'Could not permanently delete task list.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
// ─── BULK PERMANENT DELETE ────────────────────────────────────────────────────
|
||||
|
||||
exports.bulkPermanentlyDeleteTaskLists = async (req, res) => {
|
||||
const t = await sequelize.transaction();
|
||||
try {
|
||||
const { ids } = req.body;
|
||||
if (!Array.isArray(ids) || !ids.length)
|
||||
return R.error(res, 'No task list IDs provided.', 400);
|
||||
|
||||
const taskLists = await TaskList.findAll({ where: { task_list_id: ids }, paranoid: false });
|
||||
if (!taskLists.length) return R.error(res, 'No task lists found.', 404);
|
||||
|
||||
const deletedIds = taskLists.filter((tl) => tl.deletedAt).map((tl) => tl.task_list_id);
|
||||
if (!deletedIds.length)
|
||||
return R.error(res, 'All selected task lists must be archived before they can be permanently deleted.', 400);
|
||||
|
||||
const count = await permanentDeleteMany(TaskList, 'task_list_id', deletedIds, t);
|
||||
await t.commit();
|
||||
logActivity(req.user.user_id, 'bulk_permanently_delete_task_lists', { entityType: 'task_list', details: { ids: deletedIds, count } });
|
||||
return R.success(res, `${count} task list(s) permanently deleted.`, {
|
||||
deleted_ids: deletedIds,
|
||||
skipped_ids: ids.filter((id) => !deletedIds.includes(id)),
|
||||
});
|
||||
} catch (err) {
|
||||
await t.rollback();
|
||||
console.error('[ADMIN][BULK PERMANENT DELETE TASK LISTS]', err);
|
||||
return R.error(res, 'Could not permanently delete task lists.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
// ─── PERMANENT DELETE IMPACT ──────────────────────────────────────────────────
|
||||
|
||||
exports.getTaskListPermanentDeleteImpact = async (req, res) => {
|
||||
try {
|
||||
const { taskListId } = req.params;
|
||||
|
||||
const taskCount = await Task.count({ where: { task_list_id: taskListId }, paranoid: false });
|
||||
const tasks = await Task.findAll({ where: { task_list_id: taskListId }, attributes: ['task_id'], paranoid: false });
|
||||
const completionCount = tasks.length
|
||||
? await TaskCompletion.count({ where: { task_id: tasks.map((task) => task.task_id) }, paranoid: false })
|
||||
: 0;
|
||||
|
||||
return R.success(res, 'Impact retrieved.', { taskCount, completionCount });
|
||||
} catch (err) {
|
||||
console.error('[ADMIN][TASK LIST PERMANENT DELETE IMPACT]', err);
|
||||
return R.error(res, 'Could not retrieve impact.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
// =============================================================================
|
||||
// ── TASK LIST GROUPS (assign / unassign / list) ──────────────────────────────
|
||||
// =============================================================================
|
||||
@@ -848,5 +920,60 @@ exports.bulkRestoreTasks = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// ─── PERMANENT DELETE ─────────────────────────────────────────────────────────
|
||||
|
||||
exports.permanentlyDeleteTask = async (req, res) => {
|
||||
const t = await sequelize.transaction();
|
||||
try {
|
||||
const { taskListId, taskId } = req.params;
|
||||
|
||||
const record = await permanentDeleteOne(Task, { task_id: taskId, task_list_id: taskListId }, t);
|
||||
if (record === null) { await t.rollback(); return R.error(res, 'Task not found.', 404); }
|
||||
if (record === false) { await t.rollback(); return R.error(res, 'Task must be archived before it can be permanently deleted.', 400); }
|
||||
|
||||
await t.commit();
|
||||
logActivity(req.user.user_id, 'permanently_delete_task', { entityType: 'task', entityId: Number(taskId) });
|
||||
return R.success(res, 'Task permanently deleted.');
|
||||
} catch (err) {
|
||||
await t.rollback();
|
||||
console.error('[ADMIN][PERMANENT DELETE TASK]', err);
|
||||
return R.error(res, 'Could not permanently delete task.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
// ─── BULK PERMANENT DELETE ────────────────────────────────────────────────────
|
||||
|
||||
exports.bulkPermanentlyDeleteTasks = async (req, res) => {
|
||||
const t = await sequelize.transaction();
|
||||
try {
|
||||
const { taskListId } = req.params;
|
||||
const { ids } = req.body;
|
||||
if (!Array.isArray(ids) || !ids.length)
|
||||
return R.error(res, 'No task IDs provided.', 400);
|
||||
|
||||
const tasks = await Task.findAll({
|
||||
where: { task_id: ids, task_list_id: taskListId },
|
||||
paranoid: false,
|
||||
});
|
||||
if (!tasks.length) return R.error(res, 'No tasks found.', 404);
|
||||
|
||||
const deletedIds = tasks.filter((task) => task.deletedAt).map((task) => task.task_id);
|
||||
if (!deletedIds.length)
|
||||
return R.error(res, 'All selected tasks must be archived before they can be permanently deleted.', 400);
|
||||
|
||||
const count = await permanentDeleteMany(Task, 'task_id', deletedIds, t);
|
||||
await t.commit();
|
||||
logActivity(req.user.user_id, 'bulk_permanently_delete_tasks', { entityType: 'task', details: { ids: deletedIds, count } });
|
||||
return R.success(res, `${count} task(s) permanently deleted.`, {
|
||||
deleted_ids: deletedIds,
|
||||
skipped_ids: ids.filter((id) => !deletedIds.includes(id)),
|
||||
});
|
||||
} catch (err) {
|
||||
await t.rollback();
|
||||
console.error('[ADMIN][BULK PERMANENT DELETE TASKS]', err);
|
||||
return R.error(res, 'Could not permanently delete tasks.', 500);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getTaskFieldValues = getFieldValues(Task, "TASK");
|
||||
exports.getTaskListFieldValues = getFieldValues(TaskList, "TASKLIST");
|
||||
Reference in New Issue
Block a user