import { Prisma, SupportTicket } from "@toolctrl/db/prisma-browser"; import { FilterablePropertyDto } from "~/application/dtos/data/FilterablePropertyDto"; import { FiltersDto } from "~/application/dtos/data/FiltersDto"; import { PaginationDto } from "~/application/dtos/data/PaginationDto"; import { db } from "~/utils/db.server"; import { TenantSimple } from "~/utils/db/tenants.db.server"; import { UserSimple } from "~/utils/db/users.db.server"; import TenantModelHelper from "~/utils/helpers/models/TenantModelHelper"; import UserModelHelper from "~/utils/helpers/models/UserModelHelper"; export type SupportTicketWithDetails = SupportTicket & { tenant: TenantSimple | null; user: UserSimple | null; }; export type SupportTicketCreateInput = { tenantId?: string | null; userId?: string | null; source: "inline" | "email" | "api"; subject: string; message: string; fromEmail?: string | null; fromUrl?: string | null; inboundMessageId?: string | null; priority?: string; }; export async function getAllSupportTickets({ filters, filterableProperties, pagination, }: { filters: FiltersDto; filterableProperties: FilterablePropertyDto[]; pagination: { pageSize: number; page: number }; }): Promise<{ items: SupportTicketWithDetails[]; pagination: PaginationDto; }> { const q = filters.query || ""; const AND: Prisma.SupportTicketWhereInput[] = []; for (const filter of filterableProperties) { const value = filters.properties.find((item) => item.name === filter.name)?.value; if (value) { AND.push({ [filter.name]: value === "null" ? null : value }); } } const OR: Prisma.SupportTicketWhereInput[] = q ? [{ subject: { contains: q } }, { message: { contains: q } }, { fromEmail: { contains: q } }] : []; const where: Prisma.SupportTicketWhereInput = {}; if (AND.length > 0) where.AND = AND; if (OR.length > 0) where.OR = OR; const [items, totalItems] = await Promise.all([ db.supportTicket.findMany({ where, take: pagination.pageSize, skip: pagination.pageSize * (pagination.page - 1), orderBy: { createdAt: "desc" }, include: { tenant: { select: TenantModelHelper.selectSimpleTenantProperties }, user: { select: UserModelHelper.selectSimpleUserProperties }, }, }), db.supportTicket.count({ where }), ]); return { items, pagination: { page: pagination.page, pageSize: pagination.pageSize, totalItems, totalPages: Math.ceil(totalItems / pagination.pageSize), }, }; } export async function createSupportTicket(data: SupportTicketCreateInput) { return await db.supportTicket.create({ data: { tenantId: data.tenantId ?? null, userId: data.userId ?? null, source: data.source, subject: data.subject, message: data.message, fromEmail: data.fromEmail ?? null, fromUrl: data.fromUrl ?? null, inboundMessageId: data.inboundMessageId ?? null, priority: data.priority ?? "normal", }, }); } export async function updateSupportTicketStatus(id: string, status: string) { return await db.supportTicket.update({ where: { id }, data: { status } }); }