Files
BRETT/server/api/comments/[id]/reactions.post.ts
T
2026-10-03 20:07:49 +02:00

70 lines
1.9 KiB
TypeScript

import { and, eq, sql } from 'drizzle-orm'
import { z } from 'zod'
import { commentReactions, comments } from '../../../db/schema'
const bodySchema = z.object({
emoji: z.string().min(1).max(32),
})
export default defineEventHandler(async (event) => {
const user = await requireUser(event)
const id = Number(getRouterParam(event, 'id'))
if (!Number.isInteger(id) || id <= 0) {
throw createError({ statusCode: 400, statusMessage: 'Ungültige ID' })
}
const { emoji } = await readValidatedBody(event, bodySchema.parse)
const db = useDb()
const [comment] = await db
.select({ id: comments.id, uploadId: comments.uploadId })
.from(comments)
.where(eq(comments.id, id))
.limit(1)
if (!comment) {
throw createError({ statusCode: 404, statusMessage: 'Kommentar nicht gefunden' })
}
const existing = await db
.select({ userId: commentReactions.userId })
.from(commentReactions)
.where(and(
eq(commentReactions.commentId, id),
eq(commentReactions.userId, user.id),
eq(commentReactions.emoji, emoji),
))
.limit(1)
let active: boolean
if (existing.length) {
await db.delete(commentReactions).where(and(
eq(commentReactions.commentId, id),
eq(commentReactions.userId, user.id),
eq(commentReactions.emoji, emoji),
))
active = false
}
else {
await db.insert(commentReactions).values({ commentId: id, userId: user.id, emoji })
active = true
}
const [{ total }] = await db
.select({ total: sql<number>`count(*)` })
.from(commentReactions)
.where(and(eq(commentReactions.commentId, id), eq(commentReactions.emoji, emoji)))
const count = Number(total)
broadcastToAll({
type: 'reaction',
commentId: id,
uploadId: comment.uploadId,
emoji,
actorId: user.id,
actorName: user.name,
active,
count,
})
return { active, count }
})