Add giveaway, ticket, self-role, starboard, and suggestion features to the bot

- Introduced new models in the Prisma schema for giveaways, tickets, self-role panels, starboard configurations, and suggestions, enhancing the bot's functionality.
- Implemented job handling for self-role expiration and ticket management, improving user experience.
- Updated command localization to support new features in both German and English.
- Enhanced the job processing system to include dedicated workers for managing tickets and self-role expirations.
- Documented the new features and their setup processes in PHASE-TRACKING.md for clarity on implementation steps.
This commit is contained in:
smueller
2026-07-22 13:08:37 +02:00
parent f2f856628d
commit a583db7a15
50 changed files with 7820 additions and 4 deletions

View File

@@ -682,6 +682,518 @@ export const commandLocales = {
'fun.common.options.opponent': {
de: 'Gegner',
en: 'Opponent'
},
'starboard.description': {
de: 'Starboard konfigurieren',
en: 'Configure starboard'
},
'starboard.setup.description': {
de: 'Starboard einrichten',
en: 'Set up starboard'
},
'starboard.setup.options.channel': {
de: 'Starboard-Kanal',
en: 'Starboard channel'
},
'starboard.setup.options.threshold': {
de: 'Mindestanzahl Reaktionen',
en: 'Minimum reaction count'
},
'starboard.setup.options.emoji': {
de: 'Emoji (Standard: ⭐)',
en: 'Emoji (default: ⭐)'
},
'starboard.setup.options.allow_self_star': {
de: 'Self-Star erlauben',
en: 'Allow self-star'
},
'suggest.description': {
de: 'Einen Vorschlag einreichen',
en: 'Submit a suggestion'
},
'suggest.options.content': {
de: 'Vorschlagstext',
en: 'Suggestion content'
},
'suggestion.description': {
de: 'Vorschläge verwalten',
en: 'Manage suggestions'
},
'suggestion.setup.description': {
de: 'Vorschlagssystem einrichten',
en: 'Set up suggestions'
},
'suggestion.setup.options.open_channel': {
de: 'Kanal für offene Vorschläge',
en: 'Open suggestions channel'
},
'suggestion.setup.options.approved_channel': {
de: 'Kanal für angenommene Vorschläge',
en: 'Approved suggestions channel'
},
'suggestion.setup.options.denied_channel': {
de: 'Kanal für abgelehnte Vorschläge',
en: 'Denied suggestions channel'
},
'suggestion.setup.options.create_thread': {
de: 'Diskussions-Thread erstellen',
en: 'Create discussion thread'
},
'suggestion.approve.description': {
de: 'Vorschlag annehmen',
en: 'Approve suggestion'
},
'suggestion.deny.description': {
de: 'Vorschlag ablehnen',
en: 'Deny suggestion'
},
'suggestion.consider.description': {
de: 'Vorschlag in Prüfung markieren',
en: 'Mark suggestion as under consideration'
},
'suggestion.implement.description': {
de: 'Vorschlag als umgesetzt markieren',
en: 'Mark suggestion as implemented'
},
'suggestion.options.suggestion_id': {
de: 'Vorschlags-ID',
en: 'Suggestion ID'
},
'suggestion.options.reason': {
de: 'Begründung',
en: 'Reason'
},
'giveaway.description': {
de: 'Giveaways verwalten',
en: 'Manage giveaways'
},
'giveaway.start.description': {
de: 'Giveaway starten',
en: 'Start a giveaway'
},
'giveaway.start.options.duration': {
de: 'Dauer (z. B. 1h, 2d)',
en: 'Duration (e.g. 1h, 2d)'
},
'giveaway.start.options.winners': {
de: 'Anzahl Gewinner',
en: 'Number of winners'
},
'giveaway.start.options.prize': {
de: 'Preis',
en: 'Prize'
},
'giveaway.start.options.role': {
de: 'Erforderliche Rolle',
en: 'Required role'
},
'giveaway.start.options.level': {
de: 'Mindest-Level',
en: 'Minimum level'
},
'giveaway.start.options.member_days': {
de: 'Mindest-Mitgliedschaft in Tagen',
en: 'Minimum membership in days'
},
'giveaway.end.description': {
de: 'Giveaway vorzeitig beenden',
en: 'End a giveaway early'
},
'giveaway.reroll.description': {
de: 'Gewinner neu ziehen',
en: 'Reroll winners'
},
'giveaway.list.description': {
de: 'Aktive Giveaways anzeigen',
en: 'List active giveaways'
},
'giveaway.delete.description': {
de: 'Giveaway löschen',
en: 'Delete a giveaway'
},
'giveaway.pause.description': {
de: 'Giveaway pausieren oder fortsetzen',
en: 'Pause or resume a giveaway'
},
'giveaway.common.options.id': {
de: 'Giveaway-ID',
en: 'Giveaway ID'
},
'ticket.description': {
de: 'Ticket-System verwalten',
en: 'Manage the ticket system'
},
'ticket.panel.description': {
de: 'Ticket-Panels',
en: 'Ticket panels'
},
'ticket.panel.create.description': {
de: 'Ticket-Panel erstellen',
en: 'Create a ticket panel'
},
'ticket.panel.create.options.name': {
de: 'Kategoriename',
en: 'Category name'
},
'ticket.panel.create.options.description': {
de: 'Panel-Beschreibung',
en: 'Panel description'
},
'ticket.category.description': {
de: 'Ticket-Kategorien',
en: 'Ticket categories'
},
'ticket.category.create.description': {
de: 'Ticket-Kategorie mit Support-Rolle erstellen',
en: 'Create a ticket category with support role'
},
'ticket.category.create.options.name': {
de: 'Kategoriename',
en: 'Category name'
},
'ticket.category.create.options.support_role': {
de: 'Support-Rolle',
en: 'Support role'
},
'ticket.close.description': {
de: 'Ticket schließen',
en: 'Close the ticket'
},
'ticket.close.options.reason': {
de: 'Optionaler Schließgrund',
en: 'Optional close reason'
},
'ticket.claim.description': {
de: 'Ticket übernehmen',
en: 'Claim the ticket'
},
'ticket.add.description': {
de: 'Nutzer zum Ticket hinzufügen',
en: 'Add a user to the ticket'
},
'ticket.remove.description': {
de: 'Nutzer aus dem Ticket entfernen',
en: 'Remove a user from the ticket'
},
'ticket.rename.description': {
de: 'Ticket umbenennen',
en: 'Rename the ticket'
},
'ticket.rename.options.name': {
de: 'Neuer Name',
en: 'New name'
},
'ticket.priority.description': {
de: 'Ticket-Priorität setzen',
en: 'Set ticket priority'
},
'ticket.priority.options.level': {
de: 'Priorität',
en: 'Priority'
},
'ticket.priority.choice.low': {
de: 'Niedrig',
en: 'Low'
},
'ticket.priority.choice.normal': {
de: 'Normal',
en: 'Normal'
},
'ticket.priority.choice.high': {
de: 'Hoch',
en: 'High'
},
'ticket.priority.choice.urgent': {
de: 'Dringend',
en: 'Urgent'
},
'ticket.common.options.user': {
de: 'Nutzer',
en: 'User'
},
'birthdays.description': {
de: 'Geburtstage verwalten und anzeigen',
en: 'Manage and view birthdays'
},
'birthdays.set.description': {
de: 'Eigenen Geburtstag eintragen',
en: 'Set your birthday'
},
'birthdays.set.options.month': {
de: 'Monat (112)',
en: 'Month (112)'
},
'birthdays.set.options.day': {
de: 'Tag (131)',
en: 'Day (131)'
},
'birthdays.set.options.year': {
de: 'Optionales Geburtsjahr',
en: 'Optional birth year'
},
'birthdays.remove.description': {
de: 'Eigenen Geburtstag entfernen',
en: 'Remove your birthday'
},
'birthdays.next.description': {
de: 'Nächste Geburtstage anzeigen',
en: 'Show upcoming birthdays'
},
'birthdays.list.description': {
de: 'Alle Geburtstage auflisten',
en: 'List all birthdays'
},
'birthdays.setup.description': {
de: 'Geburtstags-Modul einrichten',
en: 'Configure the birthday module'
},
'birthdays.setup.options.channel': {
de: 'Kanal für Glückwünsche',
en: 'Channel for congratulations'
},
'birthdays.setup.options.role': {
de: 'Optionale 24h-Geburtstagsrolle',
en: 'Optional 24h birthday role'
},
'birthdays.setup.options.timezone': {
de: 'Zeitzone (z. B. Europe/Berlin)',
en: 'Timezone (e.g. Europe/Berlin)'
},
'birthdays.setup.options.message': {
de: 'Nachrichtenvorlage ({user}, {age})',
en: 'Message template ({user}, {age})'
},
'tempvoice.description': {
de: 'Temp-Voice (Join to Create) steuern',
en: 'Control temp voice (join to create)'
},
'tempvoice.setup.description': {
de: 'Temp-Voice einrichten',
en: 'Configure temp voice'
},
'tempvoice.setup.options.hub_channel': {
de: 'Hub-Sprachkanal (Join to Create)',
en: 'Hub voice channel (join to create)'
},
'tempvoice.setup.options.category': {
de: 'Kategorie für neue Kanäle',
en: 'Category for new channels'
},
'tempvoice.setup.options.default_name': {
de: 'Standardname ({user})',
en: 'Default name ({user})'
},
'tempvoice.setup.options.limit': {
de: 'Standard-Nutzerlimit (0 = unbegrenzt)',
en: 'Default user limit (0 = unlimited)'
},
'tempvoice.rename.description': {
de: 'Eigenen Temp-Kanal umbenennen',
en: 'Rename your temp channel'
},
'tempvoice.rename.options.name': {
de: 'Neuer Kanalname',
en: 'New channel name'
},
'tempvoice.limit.description': {
de: 'Nutzerlimit des Temp-Kanals setzen',
en: 'Set temp channel user limit'
},
'tempvoice.limit.options.limit': {
de: 'Limit (0 = unbegrenzt)',
en: 'Limit (0 = unlimited)'
},
'tempvoice.lock.description': {
de: 'Temp-Kanal sperren',
en: 'Lock temp channel'
},
'tempvoice.hide.description': {
de: 'Temp-Kanal verstecken',
en: 'Hide temp channel'
},
'tempvoice.kick.description': {
de: 'Nutzer aus Temp-Kanal entfernen',
en: 'Kick user from temp channel'
},
'tempvoice.kick.options.user': {
de: 'Zielnutzer',
en: 'Target user'
},
'tempvoice.transfer.description': {
de: 'Besitz an anderen Nutzer übertragen',
en: 'Transfer ownership to another user'
},
'tempvoice.transfer.options.user': {
de: 'Neuer Besitzer',
en: 'New owner'
},
'tempvoice.claim.description': {
de: 'Temp-Kanal übernehmen wenn Besitzer weg ist',
en: 'Claim temp channel when owner left'
},
'tempvoice.panel.description': {
de: 'Control-Panel mit Buttons anzeigen',
en: 'Show control panel with buttons'
},
'selfroles.description': {
de: 'Self-Roles (Reaction Roles) verwalten',
en: 'Manage self roles (reaction roles)'
},
'selfroles.panel.description': {
de: 'Self-Role-Panels',
en: 'Self-role panels'
},
'selfroles.panel.create.description': {
de: 'Self-Role-Panel erstellen',
en: 'Create a self-role panel'
},
'selfroles.panel.edit.description': {
de: 'Self-Role-Panel bearbeiten',
en: 'Edit a self-role panel'
},
'selfroles.panel.delete.description': {
de: 'Self-Role-Panel löschen',
en: 'Delete a self-role panel'
},
'selfroles.panel.create.options.title': {
de: 'Panel-Titel',
en: 'Panel title'
},
'selfroles.panel.create.options.description': {
de: 'Panel-Beschreibung',
en: 'Panel description'
},
'selfroles.panel.create.options.mode': {
de: 'Darstellungsmodus',
en: 'Display mode'
},
'selfroles.panel.create.options.behavior': {
de: 'Rollen-Verhalten',
en: 'Role behavior'
},
'selfroles.panel.create.options.roles': {
de: 'Rollen (roleId:label:emoji, …)',
en: 'Roles (roleId:label:emoji, …)'
},
'selfroles.panel.create.options.channel': {
de: 'Zielkanal',
en: 'Target channel'
},
'selfroles.panel.create.options.duration': {
de: 'Temporäre Rollendauer (z. B. 24h)',
en: 'Temporary role duration (e.g. 24h)'
},
'selfroles.panel.common.options.panel_id': {
de: 'Panel-ID',
en: 'Panel ID'
},
'selfroles.choice.mode.buttons': {
de: 'Buttons',
en: 'Buttons'
},
'selfroles.choice.mode.dropdown': {
de: 'Dropdown',
en: 'Dropdown'
},
'selfroles.choice.mode.reactions': {
de: 'Reaktionen',
en: 'Reactions'
},
'selfroles.choice.behavior.normal': {
de: 'Normal (Toggle)',
en: 'Normal (toggle)'
},
'selfroles.choice.behavior.unique': {
de: 'Nur eine Rolle',
en: 'Unique (one role)'
},
'selfroles.choice.behavior.verify': {
de: 'Nur hinzufügen',
en: 'Verify (add only)'
},
'selfroles.choice.behavior.temporary': {
de: 'Temporär',
en: 'Temporary'
},
'tag.description': {
de: 'Custom Commands (Tags) verwalten',
en: 'Manage custom commands (tags)'
},
'tag.create.description': {
de: 'Tag erstellen',
en: 'Create a tag'
},
'tag.edit.description': {
de: 'Tag bearbeiten',
en: 'Edit a tag'
},
'tag.delete.description': {
de: 'Tag löschen',
en: 'Delete a tag'
},
'tag.list.description': {
de: 'Tags auflisten',
en: 'List tags'
},
'tag.info.description': {
de: 'Tag-Details anzeigen',
en: 'Show tag details'
},
'tag.run.description': {
de: 'Tag ausführen',
en: 'Run a tag'
},
'tag.common.options.name': {
de: 'Tag-Name',
en: 'Tag name'
},
'tag.edit.options.new_name': {
de: 'Neuer Name',
en: 'New name'
},
'tag.create.options.response_type': {
de: 'Antworttyp',
en: 'Response type'
},
'tag.create.options.content': {
de: 'Textinhalt',
en: 'Text content'
},
'tag.create.options.embed_title': {
de: 'Embed-Titel',
en: 'Embed title'
},
'tag.create.options.embed_description': {
de: 'Embed-Beschreibung',
en: 'Embed description'
},
'tag.create.options.embed_color': {
de: 'Embed-Farbe (Dezimal)',
en: 'Embed color (decimal)'
},
'tag.create.options.trigger_word': {
de: 'Trigger-Wort (Auto-Responder)',
en: 'Trigger word (auto-responder)'
},
'tag.create.options.allowed_roles': {
de: 'Erlaubte Rollen-IDs (kommagetrennt)',
en: 'Allowed role IDs (comma-separated)'
},
'tag.create.options.allowed_channels': {
de: 'Erlaubte Kanal-IDs (kommagetrennt)',
en: 'Allowed channel IDs (comma-separated)'
},
'tag.run.options.args': {
de: 'Argumente für Platzhalter {args}',
en: 'Arguments for {args} placeholder'
},
'tag.choice.response_type.text': {
de: 'Text',
en: 'Text'
},
'tag.choice.response_type.embed': {
de: 'Embed',
en: 'Embed'
}
} as const;