import { Injectable, NotFoundException, BadRequestException } from "@nestjs/common"; import { PrismaService } from "../prisma/prisma.service"; // Cron expression validation regex (simplified) const CRON_REGEX = /^((\*|[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])\ ?){5}$/; export interface CreateCronDto { workspaceId: string; expression: string; command: string; } export interface UpdateCronDto { expression?: string; command?: string; enabled?: boolean; } @Injectable() export class CronService { constructor(private readonly prisma: PrismaService) {} async create(dto: CreateCronDto) { if (!this.isValidCronExpression(dto.expression)) { throw new BadRequestException("Invalid cron expression"); } return this.prisma.cronSchedule.create({ data: { workspaceId: dto.workspaceId, expression: dto.expression, command: dto.command, enabled: true, }, }); } async findAll(workspaceId: string) { return this.prisma.cronSchedule.findMany({ where: { workspaceId }, orderBy: { createdAt: "desc" }, }); } async findOne(id: string, workspaceId?: string) { const schedule = await this.prisma.cronSchedule.findUnique({ where: { id }, }); if (!schedule) { return null; } if (workspaceId && schedule.workspaceId !== workspaceId) { return null; } return schedule; } async update(id: string, workspaceId: string, dto: UpdateCronDto) { const schedule = await this.findOne(id, workspaceId); if (!schedule) { throw new NotFoundException("Cron schedule not found"); } if (dto.expression && !this.isValidCronExpression(dto.expression)) { throw new BadRequestException("Invalid cron expression"); } return this.prisma.cronSchedule.update({ where: { id }, data: { ...(dto.expression && { expression: dto.expression }), ...(dto.command && { command: dto.command }), ...(dto.enabled !== undefined && { enabled: dto.enabled }), }, }); } async remove(id: string, workspaceId: string) { const schedule = await this.prisma.cronSchedule.findUnique({ where: { id }, }); if (!schedule) { throw new NotFoundException("Cron schedule not found"); } if (schedule.workspaceId !== workspaceId) { throw new BadRequestException("Not authorized to delete this schedule"); } return this.prisma.cronSchedule.delete({ where: { id }, }); } private isValidCronExpression(expression: string): boolean { return CRON_REGEX.test(expression); } }