add: more things

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
This commit is contained in:
2026-07-04 03:35:09 +08:00
parent a572c1e25f
commit 3c13bb9821
36 changed files with 896 additions and 928 deletions
+127
View File
@@ -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");