mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 11:31:11 -05:00
Add blog and content approvals logging
Implement Phase 3 audit logging: - Blog management: create, update, delete, publish - Manual content deletions (force deletions) - Direct entity approvals bypassing moderation queue (loggable events where applicable) Includes integration with central logAdminAction helper and updates to relevant components/hooks: AdminBlog.tsx (create/update/delete/publish paths) Moderation queue deletion path (force delete) Moderation actions paths with direct approvals where possible New logs for blog_post_created, blog_post_updated, blog_post_deleted, blog_post_published, submission_force_deleted, etc.
This commit is contained in:
@@ -311,6 +311,19 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
|
|||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// Log manual submission deletion
|
||||||
|
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
|
||||||
|
await logAdminAction(
|
||||||
|
'submission_force_deleted',
|
||||||
|
{
|
||||||
|
submission_id: item.id,
|
||||||
|
submission_type: item.content?.action || 'unknown',
|
||||||
|
entity_type: item.content?.entity_type,
|
||||||
|
reason: 'Manual deletion by moderator',
|
||||||
|
},
|
||||||
|
item.user_id
|
||||||
|
);
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "Submission deleted",
|
title: "Submission deleted",
|
||||||
description: "The submission has been permanently deleted",
|
description: "The submission has been permanently deleted",
|
||||||
@@ -336,7 +349,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig):
|
|||||||
setActionLoading(null);
|
setActionLoading(null);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[actionLoading, toast],
|
[actionLoading, toast, queue],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -65,16 +65,47 @@ export default function AdminBlog() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (editingPost) {
|
if (editingPost) {
|
||||||
|
const oldStatus = editingPost.status;
|
||||||
const { error } = await supabase
|
const { error } = await supabase
|
||||||
.from('blog_posts')
|
.from('blog_posts')
|
||||||
.update(postData)
|
.update(postData)
|
||||||
.eq('id', editingPost.id);
|
.eq('id', editingPost.id);
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// Log blog post update
|
||||||
|
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
|
||||||
|
const statusChanged = oldStatus !== postData.status;
|
||||||
|
await logAdminAction(
|
||||||
|
statusChanged && postData.status === 'published' ? 'blog_post_published' : 'blog_post_updated',
|
||||||
|
{
|
||||||
|
post_id: editingPost.id,
|
||||||
|
title: postData.title,
|
||||||
|
slug: postData.slug,
|
||||||
|
old_status: oldStatus,
|
||||||
|
new_status: postData.status,
|
||||||
|
status_changed: statusChanged,
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const { error } = await supabase
|
const { data: newPost, error } = await supabase
|
||||||
.from('blog_posts')
|
.from('blog_posts')
|
||||||
.insert(postData);
|
.insert(postData)
|
||||||
|
.select('id')
|
||||||
|
.single();
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// Log blog post creation
|
||||||
|
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
|
||||||
|
await logAdminAction(
|
||||||
|
'blog_post_created',
|
||||||
|
{
|
||||||
|
post_id: newPost.id,
|
||||||
|
title: postData.title,
|
||||||
|
slug: postData.slug,
|
||||||
|
status: postData.status,
|
||||||
|
is_draft: isDraft,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess: (_, { isDraft }) => {
|
onSuccess: (_, { isDraft }) => {
|
||||||
@@ -89,12 +120,31 @@ export default function AdminBlog() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async (id: string) => {
|
mutationFn: async (postId: string) => {
|
||||||
|
// Get post details before deletion for audit log
|
||||||
|
const { data: post } = await supabase
|
||||||
|
.from('blog_posts')
|
||||||
|
.select('title, slug, status')
|
||||||
|
.eq('id', postId)
|
||||||
|
.single();
|
||||||
|
|
||||||
const { error } = await supabase
|
const { error } = await supabase
|
||||||
.from('blog_posts')
|
.from('blog_posts')
|
||||||
.delete()
|
.delete()
|
||||||
.eq('id', id);
|
.eq('id', postId);
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// Log blog post deletion
|
||||||
|
const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
|
||||||
|
await logAdminAction(
|
||||||
|
'blog_post_deleted',
|
||||||
|
{
|
||||||
|
post_id: postId,
|
||||||
|
title: post?.title,
|
||||||
|
slug: post?.slug,
|
||||||
|
status: post?.status,
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ['admin-blog-posts'] });
|
queryClient.invalidateQueries({ queryKey: ['admin-blog-posts'] });
|
||||||
|
|||||||
Reference in New Issue
Block a user