import { PrismaClient } from "@trigger.dev/database"; import { prisma } from "~/db.server"; import { DeleteEndpointService } from "./endpoints/deleteEndpointService"; import { logger } from "./logger.server"; import { DisableScheduleSourceService } from "./schedules/disableScheduleSource.server"; type Options = ({ projectId: string } | { projectSlug: string }) & { userId: string; }; export class DeleteProjectService { #prismaClient: PrismaClient; constructor(prismaClient: PrismaClient = prisma) { this.#prismaClient = prismaClient; } public async call(options: Options) { const projectId = await this.#getProjectId(options); const project = await this.#prismaClient.project.findFirst({ include: { environments: { include: { endpoints: true, }, }, jobs: { where: { deletedAt: null }, include: { aliases: { where: { name: "latest", }, include: { version: true, }, take: 1, }, }, }, organization: true, }, where: { id: projectId, organization: { members: { some: { userId: options.userId } } }, }, }); if (!project) { throw new Error("Project not found"); } if (project.deletedAt) { return; } //disable and delete all jobs const service = new DisableScheduleSourceService(); for (const environment of project.environments) { //disable the event dispatchers await this.#prismaClient.eventDispatcher.updateMany({ where: { environmentId: environment.id, }, data: { enabled: false, }, }); const eventDispatchers = await this.#prismaClient.eventDispatcher.findMany({ where: { environmentId: environment.id, }, }); logger.info("Deleting jobs", { jobs: project.jobs }); for (const job of project.jobs) { //disable all the job versions await this.#prismaClient.jobVersion.updateMany({ where: { jobId: job.id, }, data: { status: "DISABLED", }, }); await this.#prismaClient.job.update({ where: { id: job.id, }, data: { deletedAt: new Date(), }, }); //disable scheduled sources for (const eventDispatcher of eventDispatchers) { await service.call({ key: job.id, dispatcher: eventDispatcher, }); } } } //delete all endpoints const deleteEndpointService = new DeleteEndpointService(); for (const environment of project.environments) { for (const endpoint of environment.endpoints) { await deleteEndpointService.call(endpoint.id, options.userId); } } //mark the project as deleted await this.#prismaClient.project.update({ where: { id: project.id, }, data: { deletedAt: new Date(), }, }); } async #getProjectId(options: Options) { if ("projectId" in options) { return options.projectId; } const { id } = await this.#prismaClient.project.findFirstOrThrow({ select: { id: true, }, where: { slug: options.projectSlug, }, }); return id; } }