import { defineRelations, sql } from "drizzle-orm"; import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; export const tickets = sqliteTable( "tickets", { /** @internal this should never be exposed to an end user */ id: integer("id").primaryKey({ autoIncrement: true }), guildId: text("guild_id").notNull(), channelId: text("channel_id"), authorId: text("author_id").notNull(), anonymousId: text("anonymous_id").notNull(), type: text("type").notNull(), status: text("status", { enum: ["open", "closed", "archived"] }) .default("open") .notNull(), topic: text("topic"), createdAt: integer("created_at", { mode: "timestamp" }) .default(sql`(unixepoch())`) .notNull(), closedAt: integer("closed_at", { mode: "timestamp" }), closeReason: text("close_reason"), privateReason: text("private_reason"), }, (t) => [ index("tickets_guild_idx").on(t.guildId), index("tickets_author_idx").on(t.authorId), index("tickets_status_idx").on(t.status), ], ); export const ticketMessages = sqliteTable( "ticket_messages", { id: integer("id").primaryKey({ autoIncrement: true }), ticketId: integer("ticket_id") .references(() => tickets.id, { onDelete: "cascade" }) .notNull(), authorId: text("author_id").notNull(), authorType: text("author_type", { enum: ["user", "staff", "system"] }) .default("user") .notNull(), content: text("content").notNull(), createdAt: integer("created_at", { mode: "timestamp" }) .default(sql`(unixepoch())`) .notNull(), }, (t) => [index("ticket_msgs_ticket_idx").on(t.ticketId)], ); export const ticketAttachments = sqliteTable("ticket_attachments", { id: text("id").primaryKey(), ticketId: integer("ticket_id") .references(() => tickets.id, { onDelete: "cascade" }) .notNull(), messageId: integer("message_id").references(() => ticketMessages.id, { onDelete: "cascade", }), fileName: text("file_name").notNull(), contentType: text("content_type").notNull(), size: integer("size").notNull(), bucket: text("bucket").notNull(), key: text("key").notNull(), url: text("url").notNull(), uploadedAt: integer("uploaded_at", { mode: "timestamp" }) .default(sql`(unixepoch())`) .notNull(), }); export const TicketRelations = defineRelations( { tickets, ticketMessages, ticketAttachments, }, (r) => ({ tickets: { messages: r.many.ticketMessages({ from: r.tickets.id, to: r.ticketMessages.ticketId, }), attachments: r.many.ticketAttachments({ from: r.tickets.id, to: r.ticketAttachments.ticketId, }), }, ticketMessages: { ticket: r.one.tickets({ from: r.ticketMessages.ticketId, to: r.tickets.id, }), attachments: r.many.ticketAttachments({ from: r.ticketMessages.id, to: r.ticketAttachments.messageId, }), }, ticketAttachments: { ticket: r.one.tickets({ from: r.ticketAttachments.ticketId, to: r.tickets.id, }), message: r.one.ticketMessages({ from: r.ticketAttachments.messageId, to: r.ticketMessages.id, }), }, }), ); export type Ticket = typeof tickets.$inferSelect; export type TicketMessage = typeof ticketMessages.$inferSelect; export type ticketAttachment = typeof ticketAttachments.$inferSelect;