Deleting a ticket now sends it to the trash, for whoever opened it or an admin: it disappears from boards, searches and statistics, cannot change, and comes back from the ticket page or the trash page for 30 days. After that it is deleted for good with the usual cascade. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
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<typeof setTimeout>[] = [];
|
|
|
|
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<void> {
|
|
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}`,
|
|
);
|
|
}
|
|
}
|
|
}
|