import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { FormResult } from './entity/formResult.entity'; import { CreateFormResultDto } from './dto/create-formResult.dto'; import { UpdateFormResultDto } from './dto/update-formResult.dto'; import { Repository } from 'typeorm'; import { Queue } from 'bullmq'; import { Form } from '../form/entity/form.entity'; @Injectable() export class FormResultService { private readonly statisticsQueue: Queue; constructor( @InjectRepository(FormResult) private readonly formResultRepo: Repository, @InjectRepository(Form) private readonly formRepo: Repository
, ) { this.statisticsQueue = new Queue('form-statistics', { connection: { host: 'localhost', port: 6379, }, }); } async create(data: CreateFormResultDto): Promise { const formResult = this.formResultRepo.create({ ...data, }); const savedFormResult = await this.formResultRepo.save(formResult); // Schedule statistics update every 10 minutes await this.scheduleFormStatistics(savedFormResult.formId); return savedFormResult; } async findAll( page = 1, limit = 10, ): Promise<{ docs: FormResult[]; totalDocs: number; limit: number; page: number; totalPages: number; hasNextPage: boolean; hasPrevPage: boolean; nextPage: number | null; prevPage: number | null; }> { const [docs, totalDocs] = await this.formResultRepo.findAndCount({ skip: (page - 1) * limit, take: limit, }); const totalPages = Math.ceil(totalDocs / limit); return { docs, totalDocs, limit, page, totalPages, hasNextPage: page < totalPages, hasPrevPage: page > 1, nextPage: page < totalPages ? page + 1 : null, prevPage: page > 1 ? page - 1 : null, }; } async findById(id: string): Promise { const formResult = await this.formResultRepo.findOne({ where: { id }, }); if (!formResult) { throw new NotFoundException(`FormResult with ID "${id}" not found`); } return formResult; } async update( id: string, data: UpdateFormResultDto, ): Promise { const result = await this.formResultRepo.update( { id }, { ...data, updatedAt: new Date() }, ); if (result.affected === 0) { throw new NotFoundException(`FormResult with ID "${id}" not found`); } return await this.findById(id); } async remove(id: string): Promise { const result = await this.formResultRepo.delete({ id }); if (result.affected === 0) { throw new NotFoundException(`FormResult with ID "${id}" not found`); } } async getFormStatistics(formId: string): Promise { const formResult = await this.formResultRepo.findOne({ where: { formId } }); if (!formResult) { throw new NotFoundException(`FormResult with formId "${formId}" not found`); } return formResult; } async scheduleFormStatistics(formId: string): Promise { const form = await this.formRepo.findOne({ where: { id: formId } }); if (!form) { throw new NotFoundException('Form with this ID not found'); } if (form.isEnded) { await this.statisticsQueue.remove(`form-statistics-${formId}`); return; // Stop scheduler if form is ended } await this.statisticsQueue.upsertJobScheduler( `form-statistics-${formId}`, { every: 10 * 60 * 1000, // 10 minutes in milliseconds }, { name: 'getFormStatistics', data: { formId }, }, ); } }