feat: orphaned data cleanup, file deletion on message/account removal, and group DM improvements
- Add fileCleanup utility to delete uploaded files from disk on message/account deletion - Add migration to clean orphaned DM channels, attachments, reactions, read states, and stale moderator refs - Add FK constraints on dm_message_id in attachments and dm_reactions schema - Make bans.bannedBy and voiceRestrictions.moderatorId nullable for deleted moderators - Transfer group DM ownership on member leave or account deletion - Fully clean up orphaned DM channels (zero members) including files - Add "Leave Group" context menu for group DMs in ChannelSidebar - Add leaveDm action to spaceStore
This commit is contained in:
@@ -13,6 +13,7 @@ import type {
|
||||
Reaction,
|
||||
} from '@backspace/shared';
|
||||
import { sanitizeUser } from '../utils/sanitize.js';
|
||||
import { deleteAttachmentFiles } from '../utils/fileCleanup.js';
|
||||
|
||||
/**
|
||||
* Fetch reactions for a set of message IDs.
|
||||
@@ -417,12 +418,21 @@ export async function messageRoutes(app: FastifyInstance): Promise<void> {
|
||||
return reply.code(403).send({ error: 'You cannot delete this message', statusCode: 403 });
|
||||
}
|
||||
|
||||
// Collect attachment filenames before deleting
|
||||
const attachmentRows = db.select({ filename: schema.attachments.filename })
|
||||
.from(schema.attachments)
|
||||
.where(eq(schema.attachments.messageId, id))
|
||||
.all();
|
||||
|
||||
// Delete attachments and message atomically
|
||||
db.transaction((tx) => {
|
||||
tx.delete(schema.attachments).where(eq(schema.attachments.messageId, id)).run();
|
||||
tx.delete(schema.messages).where(eq(schema.messages.id, id)).run();
|
||||
});
|
||||
|
||||
// Clean up files from disk after transaction commits
|
||||
deleteAttachmentFiles(attachmentRows);
|
||||
|
||||
// Broadcast deletion
|
||||
connectionManager.sendToSpace(spaceId, {
|
||||
type: 'message_deleted',
|
||||
|
||||
Reference in New Issue
Block a user