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:
smueller
2026-07-22 16:59:23 +02:00
parent 4852f16f79
commit 08af99ed52
42 changed files with 1546 additions and 30 deletions

View File

@@ -11,6 +11,7 @@ export * from './phase6.js';
export * from './dashboard.js';
export * from './owner.js';
export * from './public.js';
export * from './premium.js';
export const LocaleSchema = z.enum(['de', 'en']);
export type Locale = z.infer<typeof LocaleSchema>;
@@ -95,6 +96,15 @@ const de: Dictionary = {
'core.module.feeds': 'Feeds',
'core.module.scheduler': 'Scheduler',
'core.module.guildbackup': 'Backup',
'gdpr.privacy.title': 'Datenschutz',
'gdpr.privacy.body':
'Nexumi speichert Discord-IDs und modulbezogene Daten (z. B. Verwarnungen, XP, Economy), soweit für den Betrieb nötig.',
'gdpr.privacy.link': 'Vollständige Datenschutzerklärung: {url}',
'gdpr.privacy.deleteHint': 'Persönliche Daten löschen: `/gdpr delete confirm:true`',
'gdpr.delete.needConfirm': 'Setze `confirm` auf `true`, um die Löschung zu bestätigen.',
'gdpr.delete.doneTitle': 'Daten gelöscht',
'gdpr.delete.doneBody':
'Gelöscht/anonymisiert: {warnings} Verwarnungen, {levels} Level-Einträge, {economy} Economy-Einträge, {cases} Cases anonymisiert.',
'moderation.success': 'Aktion erfolgreich ausgeführt.',
'moderation.reason.none': 'Kein Grund angegeben',
'moderation.warning.created': 'Verwarnung erstellt: {warningId}',
@@ -239,6 +249,7 @@ const de: Dictionary = {
'utility.embed.sent': 'Embed gesendet.',
'utility.embed.invalidColor': 'Ungültige Farbe. Nutze z. B. 6366F1.',
'utility.snipe.none': 'Nichts zum Anzeigen.',
'utility.snipe.disabled': 'Snipe ist auf diesem Server deaktiviert (Datenschutz).',
'utility.snipe.privacy':
'Datenschutz: Snipe speichert gelöschte/bearbeitete Nachrichten kurzzeitig (1 h) in Redis.',
'utility.snipe.deletedAt': 'Gelöschte Nachricht von {user}',
@@ -498,6 +509,8 @@ const de: Dictionary = {
'tag.error.invalid_name': 'Ungültiger Tag-Name (132 Zeichen, a-z, 0-9, _, -).',
'tag.error.content_required': 'Text-Tags benötigen Inhalt.',
'tag.error.embed_required': 'Embed-Tags benötigen Titel oder Beschreibung.',
'tag.error.premium_limit': 'Tag-Limit für diese Premium-Stufe erreicht.',
'tag.error.premium_feature': 'Tags sind für diese Premium-Stufe deaktiviert.',
'guildbackup.description': 'Server-Backups erstellen und wiederherstellen',
'guildbackup.created': 'Backup **{name}** erstellt (ID: `{id}`).',
'guildbackup.deleted': 'Backup `{id}` gelöscht.',
@@ -532,6 +545,8 @@ const de: Dictionary = {
'guildbackup.error.owner_only': 'Nur der Server-Owner kann Backups wiederherstellen.',
'guildbackup.error.bot_missing_permissions':
'Dem Bot fehlen Manage Roles oder Manage Channels für einen Restore.',
'guildbackup.error.premium_limit': 'Backup-Limit für diese Premium-Stufe erreicht.',
'guildbackup.error.premium_feature': 'Backups sind für diese Premium-Stufe deaktiviert.',
'feeds.added': 'Feed `{id}` ({type}) hinzugefügt.',
'feeds.removed': 'Feed `{id}` entfernt.',
'feeds.list.header': '**Social Feeds**',
@@ -544,6 +559,8 @@ const de: Dictionary = {
'feeds.test.twitchSkipped':
'Twitch-Feed übersprungen: TWITCH_CLIENT_ID und TWITCH_CLIENT_SECRET fehlen in der Bot-Konfiguration.',
'feeds.error.not_found': 'Feed nicht gefunden.',
'feeds.error.premium_limit': 'Feed-Limit für diese Premium-Stufe erreicht.',
'feeds.error.premium_feature': 'Feeds sind für diese Premium-Stufe deaktiviert.',
'scheduler.created': 'Geplante Nachricht erstellt (ID: `{id}`). {timing}',
'scheduler.created.at': 'Sendung: {time}',
'scheduler.created.cron': 'Wiederholung: `{cron}`',
@@ -612,6 +629,15 @@ const en: Dictionary = {
'core.module.feeds': 'Feeds',
'core.module.scheduler': 'Scheduler',
'core.module.guildbackup': 'Backup',
'gdpr.privacy.title': 'Privacy',
'gdpr.privacy.body':
'Nexumi stores Discord IDs and module-related data (e.g. warnings, XP, economy) as needed to operate.',
'gdpr.privacy.link': 'Full privacy policy: {url}',
'gdpr.privacy.deleteHint': 'Delete personal data: `/gdpr delete confirm:true`',
'gdpr.delete.needConfirm': 'Set `confirm` to `true` to confirm deletion.',
'gdpr.delete.doneTitle': 'Data deleted',
'gdpr.delete.doneBody':
'Deleted/anonymized: {warnings} warnings, {levels} level rows, {economy} economy rows, {cases} cases anonymized.',
'moderation.success': 'Action executed successfully.',
'moderation.reason.none': 'No reason provided',
'moderation.warning.created': 'Warning created: {warningId}',
@@ -755,6 +781,7 @@ const en: Dictionary = {
'utility.embed.sent': 'Embed sent.',
'utility.embed.invalidColor': 'Invalid color. Use e.g. 6366F1.',
'utility.snipe.none': 'Nothing to show.',
'utility.snipe.disabled': 'Snipe is disabled on this server (privacy).',
'utility.snipe.privacy':
'Privacy: Snipe stores deleted/edited messages briefly (1 h) in Redis.',
'utility.snipe.deletedAt': 'Deleted message by {user}',
@@ -1014,6 +1041,8 @@ const en: Dictionary = {
'tag.error.invalid_name': 'Invalid tag name (132 chars, a-z, 0-9, _, -).',
'tag.error.content_required': 'Text tags require content.',
'tag.error.embed_required': 'Embed tags require a title or description.',
'tag.error.premium_limit': 'Tag limit reached for this premium tier.',
'tag.error.premium_feature': 'Tags are disabled for this premium tier.',
'guildbackup.description': 'Create and restore server backups',
'guildbackup.created': 'Created backup **{name}** (ID: `{id}`).',
'guildbackup.deleted': 'Deleted backup `{id}`.',
@@ -1048,6 +1077,8 @@ const en: Dictionary = {
'guildbackup.error.owner_only': 'Only the server owner can restore backups.',
'guildbackup.error.bot_missing_permissions':
'The bot is missing Manage Roles or Manage Channels for a restore.',
'guildbackup.error.premium_limit': 'Backup limit reached for this premium tier.',
'guildbackup.error.premium_feature': 'Backups are disabled for this premium tier.',
'feeds.added': 'Added feed `{id}` ({type}).',
'feeds.removed': 'Removed feed `{id}`.',
'feeds.list.header': '**Social Feeds**',
@@ -1060,6 +1091,8 @@ const en: Dictionary = {
'feeds.test.twitchSkipped':
'Twitch feed skipped: TWITCH_CLIENT_ID and TWITCH_CLIENT_SECRET are missing in the bot configuration.',
'feeds.error.not_found': 'Feed not found.',
'feeds.error.premium_limit': 'Feed limit reached for this premium tier.',
'feeds.error.premium_feature': 'Feeds are disabled for this premium tier.',
'scheduler.created': 'Scheduled message created (ID: `{id}`). {timing}',
'scheduler.created.at': 'Sends at: {time}',
'scheduler.created.cron': 'Repeats: `{cron}`',