all repos — stealth-developers @ 8456beb89cb3f3bb4b338c00e04341cff62d4711

db: comment db schema
vi did:web:vt3e.cat
Wed, 24 Jun 2026 03:53:10 +0100
commit

8456beb89cb3f3bb4b338c00e04341cff62d4711

parent

a3e5c2d613f5af7a35cca701005377844609fcc4

3 files changed, 96 insertions(+), 2 deletions(-)

jump to
M pkgs/db/src/schemas/relations.tspkgs/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.tspkgs/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.tspkgs/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; +}