feat: ditch triplit, move to postgresql + drizzle orm
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { messages } from "~~/drizzle/schema";
|
||||
import { db } from "~~/server/lib/db";
|
||||
import { topicEvents } from "~~/server/utils/events";
|
||||
|
||||
async function deeplyDeleteMessage(messageId: string, topicId: string, userId: string) {
|
||||
const children = await db.query.messages.findMany({
|
||||
where: {
|
||||
parentMessageId: messageId,
|
||||
userId,
|
||||
}
|
||||
} as any);
|
||||
|
||||
for (const child of children) {
|
||||
await deeplyDeleteMessage(child.id, topicId, userId);
|
||||
}
|
||||
|
||||
await db.delete(messages).where(sql`${messages.id} = ${messageId} AND ${messages.userId} = ${userId}`);
|
||||
|
||||
topicEvents.emit(topicId, {
|
||||
type: 'MESSAGE_DELETED',
|
||||
payload: { id: messageId },
|
||||
});
|
||||
}
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
await protectRoute(event);
|
||||
|
||||
const userId = event.context.user!.id;
|
||||
const messageId = getRouterParam(event, 'messageId')!;
|
||||
|
||||
const message = await db.query.messages.findFirst({
|
||||
where: {
|
||||
id: messageId,
|
||||
userId,
|
||||
}
|
||||
} as any);
|
||||
|
||||
if (!message) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Invalid message',
|
||||
});
|
||||
}
|
||||
|
||||
const topicId = message.topicId;
|
||||
|
||||
const allTopicMessages = await db.query.messages.findMany({
|
||||
where: {
|
||||
topicId,
|
||||
userId,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
const messagesMap = new Map(allTopicMessages.map(m => [m.id, { ...m, children: [] as typeof m[] }]));
|
||||
|
||||
for (const msg of messagesMap.values()) {
|
||||
if (msg.parentMessageId && messagesMap.has(msg.parentMessageId)) {
|
||||
messagesMap.get(msg.parentMessageId)!.children.push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
const rootMessage = messagesMap.get(messageId);
|
||||
if (!rootMessage) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Invalid message',
|
||||
});
|
||||
}
|
||||
|
||||
if (rootMessage.role === 'user') {
|
||||
await deeplyDeleteMessage(rootMessage.id, topicId, userId);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
if (rootMessage.deleted === true) {
|
||||
const childMessage = rootMessage.children[rootMessage.focusedIndex!];
|
||||
if (!childMessage) {
|
||||
console.error('Message not found');
|
||||
return { ok: false };
|
||||
}
|
||||
|
||||
await deeplyDeleteMessage(childMessage.id, topicId, userId);
|
||||
|
||||
const remainingChildren = rootMessage.children.filter(child => child!.id !== childMessage.id);
|
||||
if (remainingChildren.length === 0) {
|
||||
await deeplyDeleteMessage(rootMessage.id, topicId, userId);
|
||||
} else {
|
||||
const newFocusedIndex = rootMessage.focusedIndex && rootMessage.focusedIndex > 0
|
||||
? Math.min(rootMessage.focusedIndex - 1, remainingChildren.length - 1)
|
||||
: 0;
|
||||
|
||||
await db.update(messages).set({ focusedIndex: newFocusedIndex }).where(sql`${messages.id} = ${rootMessage.id} AND ${messages.userId} = ${userId}`);
|
||||
|
||||
topicEvents.emit(topicId, {
|
||||
type: 'MESSAGE_UPDATED',
|
||||
payload: { ...rootMessage, focusedIndex: newFocusedIndex },
|
||||
});
|
||||
}
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
if (
|
||||
(rootMessage.focusedIndex !== undefined && rootMessage.focusedIndex !== null)
|
||||
&& rootMessage.focusedIndex > 0
|
||||
&& rootMessage.children.length > 0
|
||||
) {
|
||||
const childMessage = rootMessage.children[rootMessage.focusedIndex - 1];
|
||||
if (!childMessage) {
|
||||
console.error('Message not found');
|
||||
return { ok: false };
|
||||
}
|
||||
|
||||
await deeplyDeleteMessage(childMessage.id, topicId, userId);
|
||||
|
||||
const remainingChildren = rootMessage.children.filter(child => child!.id !== childMessage.id);
|
||||
const newFocusedIndex = remainingChildren.length > 0
|
||||
? Math.min(rootMessage.focusedIndex - 1, remainingChildren.length - 1)
|
||||
: 0;
|
||||
|
||||
await db.update(messages).set({ focusedIndex: newFocusedIndex }).where(sql`${messages.id} = ${rootMessage.id} AND ${messages.userId} = ${userId}`);
|
||||
|
||||
topicEvents.emit(topicId, {
|
||||
type: 'MESSAGE_UPDATED',
|
||||
payload: { ...rootMessage, focusedIndex: newFocusedIndex },
|
||||
});
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
if (rootMessage.children.length === 0) {
|
||||
await deeplyDeleteMessage(rootMessage.id, topicId, userId);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
await db.update(messages).set({ deleted: true }).where(sql`${messages.id} = ${rootMessage.id} AND ${messages.userId} = ${userId}`);
|
||||
|
||||
topicEvents.emit(topicId, {
|
||||
type: 'MESSAGE_UPDATED',
|
||||
payload: { ...rootMessage, deleted: true },
|
||||
});
|
||||
|
||||
return { ok: true };
|
||||
});
|
||||
Reference in New Issue
Block a user