initial project setup
Fastify + Prisma backend, React + Vite frontend, Docker deployment. Multi-board feedback platform with anonymous cookie auth, passkey upgrade path, ALTCHA spam protection, plugin system, and full privacy-first architecture.
This commit is contained in:
70
packages/api/src/routes/reactions.ts
Normal file
70
packages/api/src/routes/reactions.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { z } from "zod";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const reactionBody = z.object({
|
||||
emoji: z.string().min(1).max(8),
|
||||
});
|
||||
|
||||
export default async function reactionRoutes(app: FastifyInstance) {
|
||||
app.post<{ Params: { id: string }; Body: z.infer<typeof reactionBody> }>(
|
||||
"/comments/:id/reactions",
|
||||
{ preHandler: [app.requireUser] },
|
||||
async (req, reply) => {
|
||||
const comment = await prisma.comment.findUnique({ where: { id: req.params.id } });
|
||||
if (!comment) {
|
||||
reply.status(404).send({ error: "Comment not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
const { emoji } = reactionBody.parse(req.body);
|
||||
|
||||
const existing = await prisma.reaction.findUnique({
|
||||
where: {
|
||||
commentId_userId_emoji: {
|
||||
commentId: comment.id,
|
||||
userId: req.user!.id,
|
||||
emoji,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
await prisma.reaction.delete({ where: { id: existing.id } });
|
||||
reply.send({ toggled: false });
|
||||
} else {
|
||||
await prisma.reaction.create({
|
||||
data: {
|
||||
emoji,
|
||||
commentId: comment.id,
|
||||
userId: req.user!.id,
|
||||
},
|
||||
});
|
||||
reply.send({ toggled: true });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
app.delete<{ Params: { id: string; emoji: string } }>(
|
||||
"/comments/:id/reactions/:emoji",
|
||||
{ preHandler: [app.requireUser] },
|
||||
async (req, reply) => {
|
||||
const deleted = await prisma.reaction.deleteMany({
|
||||
where: {
|
||||
commentId: req.params.id,
|
||||
userId: req.user!.id,
|
||||
emoji: req.params.emoji,
|
||||
},
|
||||
});
|
||||
|
||||
if (deleted.count === 0) {
|
||||
reply.status(404).send({ error: "Reaction not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
reply.send({ ok: true });
|
||||
}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user