db: comment db schema
vi did:web:vt3e.cat
Wed, 24 Jun 2026 03:53:10 +0100
3 files changed,
96 insertions(+),
2 deletions(-)
M
pkgs/db/src/schemas/relations.ts
→
pkgs/db/src/schemas/relations.ts
@@ -2,7 +2,13 @@ import { defineRelations } from "drizzle-orm";
import { guilds } from "./guilds"; import { users, sessions } from "./users"; import { actors } from "./actors"; -import { tickets, ticketParticipants, ticketMessages, ticketAttachments } from "./tickets"; +import { + tickets, + ticketParticipants, + ticketMessages, + ticketAttachments, + ticketComments, +} from "./tickets"; export default defineRelations( {@@ -14,6 +20,7 @@ tickets,
ticketParticipants, ticketMessages, ticketAttachments, + ticketComments, }, (r) => ({ guilds: {@@ -91,6 +98,13 @@ attachments: r.many.ticketAttachments({
from: r.tickets.id, to: r.ticketAttachments.ticketId, }), + + comments: r.many.ticketComments({ from: r.tickets.id, to: r.ticketComments.ticketId }), + }, + + ticketComments: { + ticket: r.one.tickets({ from: r.ticketComments.ticketId, to: r.tickets.id }), + actor: r.one.actors({ from: r.ticketComments.actorId, to: r.actors.id }), }, ticketParticipants: {
M
pkgs/db/src/schemas/tickets.ts
→
pkgs/db/src/schemas/tickets.ts
@@ -129,6 +129,28 @@ s.index("ticket_attachments_public_id_idx").on(table.publicId),
], ); +export const ticketComments = s.sqliteTable( + "ticket_comments", + { + id: s.text("id").primaryKey(), + ticketId: s + .text("ticket_id") + .notNull() + .references(() => tickets.id, { onDelete: "cascade" }), + actorId: s + .integer("actor_id") + .notNull() + .references(() => actors.id, { onDelete: "cascade" }), + content: s.text("content").notNull(), + createdAt: s.integer("created_at", { mode: "timestamp" }).notNull(), + updatedAt: s.integer("updated_at", { mode: "timestamp" }).notNull(), + }, + (table) => [ + s.index("ticket_comments_ticket_idx").on(table.ticketId), + s.index("ticket_comments_actor_idx").on(table.actorId), + ], +); + export type Ticket = typeof tickets.$inferSelect; export type NewTicket = typeof tickets.$inferInsert;@@ -140,3 +162,6 @@ export type NewTicketMessage = typeof ticketMessages.$inferInsert;
export type TicketAttachment = typeof ticketAttachments.$inferSelect; export type NewTicketAttachment = typeof ticketAttachments.$inferInsert; + +export type TicketComment = typeof ticketComments.$inferSelect; +export type NewTicketComment = typeof ticketComments.$inferInsert;
M
pkgs/db/src/utils/ticket.ts
→
pkgs/db/src/utils/ticket.ts
@@ -1,10 +1,11 @@
import { randomUUID } from "node:crypto"; import { and, desc, eq } from "drizzle-orm"; import db, { + tickets, ticketMessages, ticketAttachments, ticketParticipants, - tickets, + ticketComments, type Ticket, } from "..";@@ -261,3 +262,57 @@ actor: true,
}, }); } + +// comments +export async function getTicketComments(ticketId: string) { + return await db.query.ticketComments.findMany({ + where: { + ticketId: ticketId, + }, + with: { + actor: true, + }, + }); +} + +export async function addTicketComment(data: { + ticketId: string; + actorId: number; + content: string; +}) { + const [comment] = await db + .insert(ticketComments) + .values({ + id: randomUUID(), + ticketId: data.ticketId, + actorId: data.actorId, + content: data.content, + createdAt: new Date(), + updatedAt: new Date(), + }) + .returning(); + + return comment; +} + +export async function removeTicketComment(commentId: number) { + const [removed] = await db + .delete(ticketComments) + .where(eq(ticketComments.id, commentId)) + .returning(); + + return removed; +} + +export async function editTicketComment(commentId: number, content: string) { + const [updated] = await db + .update(ticketComments) + .set({ + content: content, + updatedAt: new Date(), + }) + .where(eq(ticketComments.id, commentId)) + .returning(); + + return updated; +}