Implement premium features and GDPR compliance in bot and WebUI
- Added new models for premium tier configurations and assignments, enabling feature limits for free and premium users. - Introduced GDPR deletion logging and commands for user data management. - Enhanced logging configuration with retention days for audit logs. - Updated bot commands and job processing to include new premium and GDPR functionalities. - Improved localization with new keys for premium features and GDPR commands in both English and German. - Added UI components for managing premium settings and logging retention in the WebUI.
This commit is contained in:
@@ -36,6 +36,8 @@ import {
|
||||
presenceQueue,
|
||||
presenceQueueName,
|
||||
reminderQueueName,
|
||||
retentionQueue,
|
||||
retentionQueueName,
|
||||
scheduleQueueName,
|
||||
suggestionsQueueName,
|
||||
ticketQueue,
|
||||
@@ -321,6 +323,20 @@ export function startWorkers(context: BotContext): Worker[] {
|
||||
logger.error({ jobId: job?.id, error }, 'Presence refresh job failed');
|
||||
});
|
||||
|
||||
const retentionWorker = new Worker(
|
||||
retentionQueueName,
|
||||
async (job) => {
|
||||
if (job.name !== 'purgeExpiredLogs') {
|
||||
return;
|
||||
}
|
||||
await runLogRetentionJob(context);
|
||||
},
|
||||
{ connection: redis }
|
||||
);
|
||||
retentionWorker.on('failed', (job, error) => {
|
||||
logger.error({ jobId: job?.id, error }, 'Log retention job failed');
|
||||
});
|
||||
|
||||
return [
|
||||
moderationWorker,
|
||||
backupWorker,
|
||||
@@ -335,7 +351,8 @@ export function startWorkers(context: BotContext): Worker[] {
|
||||
scheduleWorker,
|
||||
guildBackupWorker,
|
||||
suggestionsWorker,
|
||||
presenceWorker
|
||||
presenceWorker,
|
||||
retentionWorker
|
||||
];
|
||||
}
|
||||
|
||||
@@ -403,6 +420,41 @@ export async function ensureRecurringJobs(): Promise<void> {
|
||||
removeOnFail: 5
|
||||
}
|
||||
);
|
||||
|
||||
await retentionQueue.add(
|
||||
'purgeExpiredLogs',
|
||||
{},
|
||||
{
|
||||
repeat: { pattern: '15 4 * * *' },
|
||||
removeOnComplete: 20,
|
||||
removeOnFail: 20
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function runLogRetentionJob(context: BotContext): Promise<void> {
|
||||
const configs = await context.prisma.loggingConfig.findMany({
|
||||
where: { retentionDays: { gt: 0 } },
|
||||
select: { guildId: true, retentionDays: true }
|
||||
});
|
||||
|
||||
for (const config of configs) {
|
||||
const cutoff = new Date(Date.now() - config.retentionDays * 24 * 60 * 60 * 1000);
|
||||
const [cases, audits] = await Promise.all([
|
||||
context.prisma.case.deleteMany({
|
||||
where: { guildId: config.guildId, createdAt: { lt: cutoff } }
|
||||
}),
|
||||
context.prisma.dashboardAuditLog.deleteMany({
|
||||
where: { guildId: config.guildId, createdAt: { lt: cutoff } }
|
||||
})
|
||||
]);
|
||||
if (cases.count > 0 || audits.count > 0) {
|
||||
logger.info(
|
||||
{ guildId: config.guildId, cases: cases.count, audits: audits.count, retentionDays: config.retentionDays },
|
||||
'Log retention purge completed'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function runPgDumpBackup(): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user