deletion reason and email for soft deleted forum posts and comments by admin
This commit is contained in:
@@ -1250,26 +1250,68 @@ router.get('/tags', async (req, res) => {
|
||||
// DELETE /api/forum/admin/posts/:id - Admin soft-delete post
|
||||
router.delete('/admin/posts/:id', authenticateToken, requireAdmin, async (req, res) => {
|
||||
try {
|
||||
const post = await ForumPost.findByPk(req.params.id);
|
||||
const { reason } = req.body;
|
||||
|
||||
if (!reason || !reason.trim()) {
|
||||
return res.status(400).json({ error: "Deletion reason is required" });
|
||||
}
|
||||
|
||||
const post = await ForumPost.findByPk(req.params.id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'author',
|
||||
attributes: ['id', 'username', 'firstName', 'lastName', 'email']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!post) {
|
||||
return res.status(404).json({ error: 'Post not found' });
|
||||
}
|
||||
|
||||
if (post.isDeleted) {
|
||||
return res.status(400).json({ error: 'Post is already deleted' });
|
||||
}
|
||||
|
||||
// Soft delete the post
|
||||
await post.update({
|
||||
isDeleted: true,
|
||||
deletedBy: req.user.id,
|
||||
deletedAt: new Date()
|
||||
deletedAt: new Date(),
|
||||
deletionReason: reason.trim()
|
||||
});
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.info("Admin deleted post", {
|
||||
postId: req.params.id,
|
||||
adminId: req.user.id,
|
||||
originalAuthorId: post.authorId
|
||||
originalAuthorId: post.authorId,
|
||||
reason: reason.trim()
|
||||
});
|
||||
|
||||
// Send email notification to post author (non-blocking)
|
||||
(async () => {
|
||||
try {
|
||||
const admin = await User.findByPk(req.user.id, {
|
||||
attributes: ['id', 'username', 'firstName', 'lastName']
|
||||
});
|
||||
|
||||
if (post.author && admin) {
|
||||
await emailServices.forum.sendForumPostDeletionNotification(
|
||||
post.author,
|
||||
admin,
|
||||
post,
|
||||
reason.trim()
|
||||
);
|
||||
console.log(`Forum post deletion notification email sent to author ${post.authorId}`);
|
||||
}
|
||||
} catch (emailError) {
|
||||
// Log but don't fail the deletion
|
||||
console.error('Failed to send forum post deletion notification email:', emailError.message);
|
||||
}
|
||||
})();
|
||||
|
||||
res.status(200).json({ message: 'Post deleted successfully', post });
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
@@ -1292,11 +1334,16 @@ router.patch('/admin/posts/:id/restore', authenticateToken, requireAdmin, async
|
||||
return res.status(404).json({ error: 'Post not found' });
|
||||
}
|
||||
|
||||
if (!post.isDeleted) {
|
||||
return res.status(400).json({ error: 'Post is not deleted' });
|
||||
}
|
||||
|
||||
// Restore the post
|
||||
await post.update({
|
||||
isDeleted: false,
|
||||
deletedBy: null,
|
||||
deletedAt: null
|
||||
deletedAt: null,
|
||||
deletionReason: null
|
||||
});
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
@@ -1322,25 +1369,44 @@ router.patch('/admin/posts/:id/restore', authenticateToken, requireAdmin, async
|
||||
// DELETE /api/forum/admin/comments/:id - Admin soft-delete comment
|
||||
router.delete('/admin/comments/:id', authenticateToken, requireAdmin, async (req, res) => {
|
||||
try {
|
||||
const comment = await ForumComment.findByPk(req.params.id);
|
||||
const { reason } = req.body;
|
||||
|
||||
if (!reason || !reason.trim()) {
|
||||
return res.status(400).json({ error: "Deletion reason is required" });
|
||||
}
|
||||
|
||||
const comment = await ForumComment.findByPk(req.params.id, {
|
||||
include: [
|
||||
{
|
||||
model: User,
|
||||
as: 'author',
|
||||
attributes: ['id', 'username', 'firstName', 'lastName', 'email']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (!comment) {
|
||||
return res.status(404).json({ error: 'Comment not found' });
|
||||
}
|
||||
|
||||
if (comment.isDeleted) {
|
||||
return res.status(400).json({ error: 'Comment is already deleted' });
|
||||
}
|
||||
|
||||
// Soft delete the comment (preserve original content for potential restoration)
|
||||
await comment.update({
|
||||
isDeleted: true,
|
||||
deletedBy: req.user.id,
|
||||
deletedAt: new Date()
|
||||
deletedAt: new Date(),
|
||||
deletionReason: reason.trim()
|
||||
});
|
||||
|
||||
// Decrement comment count if not already deleted
|
||||
if (!comment.isDeleted) {
|
||||
const post = await ForumPost.findByPk(comment.postId);
|
||||
if (post && post.commentCount > 0) {
|
||||
await post.decrement('commentCount');
|
||||
}
|
||||
// Decrement comment count
|
||||
const post = await ForumPost.findByPk(comment.postId, {
|
||||
attributes: ['id', 'title']
|
||||
});
|
||||
if (post && post.commentCount > 0) {
|
||||
await post.decrement('commentCount');
|
||||
}
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
@@ -1348,9 +1414,32 @@ router.delete('/admin/comments/:id', authenticateToken, requireAdmin, async (req
|
||||
commentId: req.params.id,
|
||||
adminId: req.user.id,
|
||||
originalAuthorId: comment.authorId,
|
||||
postId: comment.postId
|
||||
postId: comment.postId,
|
||||
reason: reason.trim()
|
||||
});
|
||||
|
||||
// Send email notification to comment author (non-blocking)
|
||||
(async () => {
|
||||
try {
|
||||
const admin = await User.findByPk(req.user.id, {
|
||||
attributes: ['id', 'username', 'firstName', 'lastName']
|
||||
});
|
||||
|
||||
if (comment.author && admin && post) {
|
||||
await emailServices.forum.sendForumCommentDeletionNotification(
|
||||
comment.author,
|
||||
admin,
|
||||
post,
|
||||
reason.trim()
|
||||
);
|
||||
console.log(`Forum comment deletion notification email sent to author ${comment.authorId}`);
|
||||
}
|
||||
} catch (emailError) {
|
||||
// Log but don't fail the deletion
|
||||
console.error('Failed to send forum comment deletion notification email:', emailError.message);
|
||||
}
|
||||
})();
|
||||
|
||||
res.status(200).json({ message: 'Comment deleted successfully', comment });
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
@@ -1381,7 +1470,8 @@ router.patch('/admin/comments/:id/restore', authenticateToken, requireAdmin, asy
|
||||
await comment.update({
|
||||
isDeleted: false,
|
||||
deletedBy: null,
|
||||
deletedAt: null
|
||||
deletedAt: null,
|
||||
deletionReason: null
|
||||
});
|
||||
|
||||
// Increment comment count
|
||||
|
||||
Reference in New Issue
Block a user