import { Injectable, Logger } from '@nestjs/common' import { Cron } from '@nestjs/schedule' import { SlotGeneratorService } from '../time-slot/slot-generator.service' import { FlashSaleService } from '../flash-sale/flash-sale.service' @Injectable() export class SchedulerService { private readonly logger = new Logger(SchedulerService.name) constructor( private readonly slotGenerator: SlotGeneratorService, private readonly flashSaleService: FlashSaleService, ) {} /** 02:00 daily — generate slots 14 days ahead from week templates */ @Cron('0 2 * * *') async handleSlotGeneration(): Promise { try { const count = await this.slotGenerator.generateSlots(14) this.logger.log(`[handleSlotGeneration] Created ${count} new time slots`) } catch (err) { this.logger.error('[handleSlotGeneration] Failed to generate slots', err) } } /** 02:30 daily — close past OPEN slots */ @Cron('30 2 * * *') async handleCleanupSlots(): Promise { try { const count = await this.slotGenerator.cleanupExpiredSlots() this.logger.log(`[handleCleanupSlots] Closed ${count} expired slots`) } catch (err) { this.logger.error('[handleCleanupSlots] Failed to clean up slots', err) } } /** 03:00 daily — expire memberships past their end date or with 0 sessions */ @Cron('0 3 * * *') async handleCheckMemberships(): Promise { try { const count = await this.slotGenerator.checkExpiredMemberships() this.logger.log(`[handleCheckMemberships] Updated ${count} memberships`) } catch (err) { this.logger.error('[handleCheckMemberships] Failed to check memberships', err) } } /** 22:00 daily — mark past CONFIRMED bookings as COMPLETED */ @Cron('0 22 * * *') async handleCompleteBookings(): Promise { try { const count = await this.slotGenerator.completeBookings() this.logger.log(`[handleCompleteBookings] Completed ${count} bookings`) } catch (err) { this.logger.error('[handleCompleteBookings] Failed to complete bookings', err) } } /** Every 5 min — expire unpaid flash sale reservations older than 15min */ @Cron('*/5 * * * *') async handleExpireFlashSaleReservations(): Promise { try { const count = await this.flashSaleService.expireUnpaidReservations(15) if (count > 0) { this.logger.log(`[handleExpireFlashSaleReservations] Expired ${count} unpaid reservations`) } } catch (err) { this.logger.error('[handleExpireFlashSaleReservations] Failed', err) } } }