Initial todo app setup
- Backend: Bun + Elysia + Drizzle ORM + PostgreSQL - Frontend: React + Vite + TailwindCSS + Zustand - Auth: better-auth with invite-only system - Features: Tasks, Projects, Sections, Labels, Comments - Hammer API: Dedicated endpoints for AI assistant integration - Unit tests: 24 passing tests - Docker: Compose file for deployment
This commit is contained in:
146
apps/api/src/routes/comments.ts
Normal file
146
apps/api/src/routes/comments.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
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(),
|
||||
}),
|
||||
});
|
||||
Reference in New Issue
Block a user