Playtester werden jetzt beworben, nicht angeklickt
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

Der Knopf unter dem Playtester-Aufruf hat jeden aufgenommen, der ihn gedrueckt
hat — ohne Frage, ohne Pruefung. Fuer ein Programm, dessen Teilnehmer Zugang
und Alpha-Keys bekommen, ist das die falsche Tuer.

Statt einen zweiten Pruef-Ablauf danebenzustellen, laeuft die Aufnahme jetzt
ueber die Bewerbungs-Formulare, die es laengst gibt: Modal ausfuellen,
Review-Embed im Staff-Kanal,  oder , Rolle und Antwort-DM bei Zusage. Das
ist dieselbe Maschinerie, nur ein anderer Aufhaenger — und damit auch nur eine
Stelle, an der spaeter etwas kaputtgehen kann.

Ein Formular laesst sich als Playtester-Formular markieren ("Annahme traegt als
Playtester ein"). Wer dort angenommen wird, landet zusaetzlich in der
Playtester-Liste, damit die Schluessel-Verteilung ihn kennt. Nur eines kann es
sein — sonst wuesste /playtester-setup nicht, welches es posten soll.

/playtester-setup postet jetzt den Knopf dieses Formulars. Fehlt das Formular,
fehlen Fragen oder fehlt der Review-Kanal, sagt der Befehl das, statt einen
Aufruf zu posten, der ins Leere fuehrt.

Der alte Knopf in bereits geposteten Nachrichten nimmt niemanden mehr auf: er
verweist auf den Aufruf. Austreten bleibt Selbstbedienung — dafuer braucht es
keine Freigabe.

Im Panel steht im Playtester-Bereich, ueber welches Formular die Aufnahme
laeuft, ob es schon gepostet ist, und ein Weg dorthin. Ohne markiertes Formular
steht dort, dass gerade niemand hereinkommt — das ist sonst der Grund, warum
sich tagelang niemand bewirbt.

Geprueft: Routen, SQL gegen das Schema, und im Browser beide Zustaende des
Hinweises sowie der neue Schalter — beim Wechsel zwischen zwei Formularen
folgt er dem richtigen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 10:04:16 +02:00
co-authored by Claude Opus 5
parent ddd7610d6c
commit 1c5c7d2470
8 changed files with 139 additions and 31 deletions
+42 -5
View File
@@ -1,20 +1,52 @@
// /playtester-setup — postet das Bewerbungs-Embed mit Button in den aktuellen Kanal (Admin)
// /playtester-setup — postet den Playtester-Aufruf in den aktuellen Kanal (Admin)
//
// Ist ein Bewerbungs-Formular als Playtester-Formular markiert, führt der Knopf
// dorthin: ausfüllen, das Team entscheidet. Ohne Formular gäbe es nur den alten
// Selbstbedienungs-Knopf — und der macht jeden zum Playtester, der draufdrückt.
// Deshalb sagt der Befehl dann, was zu tun ist, statt ihn zu posten.
import {
SlashCommandBuilder, PermissionFlagsBits, MessageFlags,
ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder,
} from 'discord.js';
import { playtesterRoleId, brandColor, brandFooter } from '../../runtime-settings.js';
import { renderTemplate } from '../../templates.js';
import { playtesterForm } from '../../db.js';
export const data = new SlashCommandBuilder()
.setName('playtester-setup')
.setDescription('Postet das Playtester-Bewerbungs-Embed in diesen Kanal')
.setDescription('Postet den Playtester-Aufruf in diesen Kanal')
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator);
export async function execute(interaction) {
if (!playtesterRoleId()) {
await interaction.reply({
content: '❌ Erst auf der Config-Seite eine Playtester-Rolle wählen.',
content: '❌ Erst in der Config eine Playtester-Rolle wählen.',
flags: MessageFlags.Ephemeral,
});
return;
}
const form = playtesterForm();
if (!form) {
await interaction.reply({
content: '❌ Kein Playtester-Formular gesetzt.\n'
+ 'Config → **Bewerbungen**: ein Formular anlegen und dort '
+ '„Annahme trägt als Playtester ein" ankreuzen. Dann kann sich '
+ 'niemand mehr per Knopfdruck selbst aufnehmen.',
flags: MessageFlags.Ephemeral,
});
return;
}
if (JSON.parse(form.questions || '[]').length === 0) {
await interaction.reply({
content: `❌ Das Formular „${form.title}" hat noch keine Fragen.`,
flags: MessageFlags.Ephemeral,
});
return;
}
if (!form.review_channel_id) {
await interaction.reply({
content: `❌ Für „${form.title}" fehlt der Review-Kanal — sonst sieht niemand die Bewerbungen.`,
flags: MessageFlags.Ephemeral,
});
return;
@@ -26,14 +58,19 @@ export async function execute(interaction) {
.setDescription(renderTemplate('playtester.panel_text'))
.setFooter({ text: brandFooter('PLAYTEST') });
// Derselbe Knopf wie beim Bewerbungs-Formular — das Formular, die Prüfung
// und die Antwort-DMs sind dieselbe Maschinerie, nur ein anderer Aufhänger.
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setCustomId('playtester_toggle')
.setCustomId(`apply:${form.id}`)
.setStyle(ButtonStyle.Success)
.setLabel('Als Playtester bewerben')
.setEmoji('🧪')
);
await interaction.channel.send({ embeds: [embed], components: [row] });
await interaction.reply({ content: '✅ Bewerbungs-Post erstellt.', flags: MessageFlags.Ephemeral });
await interaction.reply({
content: `✅ Aufruf gepostet — Bewerbungen laufen über „${form.title}".`,
flags: MessageFlags.Ephemeral,
});
}