Linked Roles: Rollen, die an geprueften Werten haengen
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

Neues Modul, standardmaessig aus. Ein Mitglied klickt in Discord auf "Rolle
holen", landet auf /linked-roles, bestaetigt den OAuth-Dialog — und der Bot
schiebt ihm drei Kennzahlen zu, die Discord dann gegen die Rollen-Einstellung
prueft:

  level        Zahl >= eingestelltem Wert
  dabei_seit   Datum <= "vor X Tagen", also Mitglied seit mindestens X Tagen
  playtester   Wahrheitswert

Der Bot vergibt dabei keine Rollen. Er liefert nur die Zahlen; was daraus
wird, entscheidet die Rollen-Einstellung im Server. Die Daten kommen aus dem,
was ohnehin da ist: Level-Tabelle, Playtester-Liste, Discords Beitrittsdatum.

Eigener OAuth-Weg statt /auth/login, weil die Berechtigungen andere sind —
role_connections.write hat der normale Login nicht.

Die Tokens werden gespeichert, und das ist keine Bequemlichkeit: ohne
Refresh-Token bliebe jede Rolle auf dem Stand des Verknuepfungs-Tages stehen,
ein Level-Up kaeme nie an. Discords eigene Anleitung sagt dasselbe. Der
Umfang ist eng (nur identify + role_connections.write), beim Widerruf oder
Entkoppeln fliegt der Datensatz sofort raus. Steht so auch als Kommentar an
der Tabelle.

Abgeglichen wird alle 6 Stunden, einstellbar. Dafuer kann everyTuned jetzt
auch Stunden — und wirft bei einer unbekannten Einheit, statt den Abstand
still um Faktor 60 oder 3600 danebenzulegen.

Beim Bauen gefunden: moduleEnabled fehlte im Import von client.js. Der Bot
waere beim ClientReady mit ReferenceError gestorben.

Geprueft: alle drei Kennzahlen gegen Discords Formatgrenzen (Schluessel-Regex,
Laengen, gueltige Typ-Codes), Modul- und Stellwert-Register, die
Stunden-Umrechnung (6 h = 21600000 ms), Speichern und Loeschen einer
Verknuepfung, dazu 186 SQL-Abfragen und alle Routen auf Rechtepruefung.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 05:57:57 +02:00
co-authored by Claude Fable 5
parent 55e9ef57e2
commit 137452da11
9 changed files with 358 additions and 2 deletions
+14 -2
View File
@@ -103,6 +103,11 @@ export const TUNING = [
id: 'raid_window', module: 'anti_raid', group: 'grenzen', label: 'Raid — Zeitfenster',
unit: 'Sekunden', default: 20, min: 5, max: 600,
},
{
id: 'linked_sync', module: 'linked_roles', group: 'pruefung', label: 'Verknüpfte Rollen abgleichen alle',
hint: 'Discord fragt die Werte nicht selbst nach — ohne Abgleich bliebe eine Rolle auf dem Stand des Verknüpfungs-Tages.',
unit: 'Stunden', default: 6, min: 1, max: 168,
},
{
id: 'raid_lockdown', module: 'anti_raid', group: 'zeiten', label: 'Raid-Sperre dauert',
hint: 'Danach hebt der Bot sie von selbst wieder auf.',
@@ -152,6 +157,7 @@ export function tuning(id) {
export const tuningMs = {
seconds: (id) => tuning(id) * 1000,
minutes: (id) => tuning(id) * 60 * 1000,
hours: (id) => tuning(id) * 60 * 60 * 1000,
};
/**
@@ -207,14 +213,20 @@ export function tuningStates() {
* festem Abstand könnte das nicht.)
*
* @param {string} id — Stellwert
* @param {'minutes'|'seconds'} unit
* @param {'hours'|'minutes'|'seconds'} unit
* @param {() => unknown} task
* @param {string} tag — Kennung fürs Fehler-Log
* @returns {() => void} Abbrechen
*/
export function everyTuned(id, unit, task, tag = id) {
let timer;
const delay = () => (unit === 'minutes' ? tuningMs.minutes(id) : tuningMs.seconds(id));
// Unbekannte Einheit wäre schlimmer als ein Tippfehler: der Abstand läge
// um Faktor 60 oder 3600 daneben, ohne dass es jemand merkt.
const delay = () => {
const f = tuningMs[unit];
if (!f) throw new Error(`everyTuned(${id}): unbekannte Einheit "${unit}"`);
return f(id);
};
const run = async () => {
try {
await task();