import { Injectable, NotFoundException, BadRequestException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { ScheduledTask } from '../../entities/scheduled-task.entity'; import { CreateTaskDto } from './dto/create-task.dto'; import { UpdateTaskDto } from './dto/update-task.dto'; @Injectable() export class SchedulesService { constructor( @InjectRepository(ScheduledTask) private taskRepository: Repository, ) {} async getTasks(licenseId: string): Promise { return await this.taskRepository.find({ where: { license_id: licenseId }, order: { created_at: 'DESC' }, }); } async createTask( licenseId: string, dto: CreateTaskDto, ): Promise { // Validate cron expression is parseable // In production, you'd use a cron parser library to validate // For now, we rely on the regex in the DTO // Set default timezone if not provided const timezone = dto.timezone || 'UTC'; const task = this.taskRepository.create({ license_id: licenseId, task_type: dto.task_type, task_name: dto.task_name, cron_expression: dto.cron_expression, timezone: timezone, task_config: dto.task_config || {}, is_active: true, next_run: null, // Would be calculated by scheduler created_at: new Date(), }); const saved = await this.taskRepository.save(task); // TODO: Register task with scheduler (tokio-cron-scheduler in Rust) // This would send a NATS message to the scheduler service to register the task return saved; } async updateTask( licenseId: string, taskId: string, dto: UpdateTaskDto, ): Promise { const task = await this.taskRepository.findOne({ where: { id: taskId, license_id: licenseId, }, }); if (!task) { throw new NotFoundException(`Scheduled task ${taskId} not found`); } // Update fields Object.assign(task, dto); const updated = await this.taskRepository.save(task); // TODO: Update task registration with scheduler // Send NATS message to update the task in tokio-cron-scheduler return updated; } async deleteTask(licenseId: string, taskId: string) { const task = await this.taskRepository.findOne({ where: { id: taskId, license_id: licenseId, }, }); if (!task) { throw new NotFoundException(`Scheduled task ${taskId} not found`); } await this.taskRepository.delete(taskId); // TODO: Unregister task from scheduler // Send NATS message to remove the task from tokio-cron-scheduler return { deleted: true }; } async toggleTask(licenseId: string, taskId: string, enabled: boolean) { const task = await this.taskRepository.findOne({ where: { id: taskId, license_id: licenseId, }, }); if (!task) { throw new NotFoundException(`Scheduled task ${taskId} not found`); } task.is_active = enabled; const updated = await this.taskRepository.save(task); // TODO: Enable/disable task in scheduler // Send NATS message to pause or resume the task return updated; } }