import { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { CommandBus } from '@nestjs/cqrs'; import { EmptyTrashCommand, TRASH_DAYS, } from '@task-stream/api/tracker/application'; const HOUR = 3_600_000; /** * Deletes for good what has been in the trash longer than TRASH_DAYS (30 * by default), a few minutes after start and then every six hours. */ @Injectable() export class TrashScheduler implements OnApplicationBootstrap, OnApplicationShutdown { private readonly logger = new Logger(TrashScheduler.name); private timers: ReturnType[] = []; constructor( private readonly commandBus: CommandBus, private readonly config: ConfigService, ) {} onApplicationBootstrap(): void { const first = setTimeout(() => void this.run(), 5 * 60_000); const every = setInterval(() => void this.run(), 6 * HOUR); first.unref?.(); every.unref?.(); this.timers = [first, every]; } onApplicationShutdown(): void { this.timers.forEach((timer) => clearTimeout(timer)); } private async run(): Promise { const days = Number(this.config.get('TRASH_DAYS') ?? TRASH_DAYS) || TRASH_DAYS; const before = new Date(Date.now() - days * 24 * HOUR).toISOString(); try { const deleted: number = await this.commandBus.execute( new EmptyTrashCommand(before), ); if (deleted) this.logger.log(`Deleted ${deleted} ticket(s) from the trash`); } catch (error) { this.logger.warn( `Emptying the trash failed: ${(error as Error).message}`, ); } } }