import { Elysia, t } from 'elysia'; import { db } from '../db'; import { comments, tasks } from '../db/schema'; import { eq, and, asc } from 'drizzle-orm'; import type { User } from '../lib/auth'; export const commentRoutes = new Elysia({ prefix: '/comments' }) // Get comments for a task .get('/task/:taskId', async ({ params, user, set }) => { // Verify task ownership const task = await db.query.tasks.findFirst({ where: and( eq(tasks.id, params.taskId), eq(tasks.userId, (user as User).id) ), }); if (!task) { set.status = 404; throw new Error('Task not found'); } const taskComments = await db.query.comments.findMany({ where: eq(comments.taskId, params.taskId), orderBy: [asc(comments.createdAt)], with: { user: { columns: { id: true, name: true, image: true }, }, }, }); return taskComments; }, { params: t.Object({ taskId: t.String(), }), }) // Create comment .post('/', async ({ body, user }) => { const userId = (user as User).id; // Verify task ownership const task = await db.query.tasks.findFirst({ where: and( eq(tasks.id, body.taskId), eq(tasks.userId, userId) ), }); if (!task) { throw new Error('Task not found'); } const [comment] = await db.insert(comments).values({ taskId: body.taskId, userId, content: body.content, attachments: body.attachments || [], }).returning(); // Return with user info const fullComment = await db.query.comments.findFirst({ where: eq(comments.id, comment.id), with: { user: { columns: { id: true, name: true, image: true }, }, }, }); return fullComment; }, { body: t.Object({ taskId: t.String(), content: t.String({ minLength: 1 }), attachments: t.Optional(t.Array(t.Object({ name: t.String(), url: t.String(), type: t.String(), }))), }), }) // Update comment .patch('/:id', async ({ params, body, user, set }) => { const existing = await db.query.comments.findFirst({ where: and( eq(comments.id, params.id), eq(comments.userId, (user as User).id) ), }); if (!existing) { set.status = 404; throw new Error('Comment not found'); } const [updated] = await db .update(comments) .set({ content: body.content, attachments: body.attachments, updatedAt: new Date(), }) .where(eq(comments.id, params.id)) .returning(); return updated; }, { params: t.Object({ id: t.String(), }), body: t.Object({ content: t.Optional(t.String({ minLength: 1 })), attachments: t.Optional(t.Array(t.Object({ name: t.String(), url: t.String(), type: t.String(), }))), }), }) // Delete comment .delete('/:id', async ({ params, user, set }) => { const existing = await db.query.comments.findFirst({ where: and( eq(comments.id, params.id), eq(comments.userId, (user as User).id) ), }); if (!existing) { set.status = 404; throw new Error('Comment not found'); } await db.delete(comments).where(eq(comments.id, params.id)); return { success: true }; }, { params: t.Object({ id: t.String(), }), });