Setup-Seite: Kanal-Auswahl, Feed-Regeln und Status im Webinterface

- Settings-Tabelle in SQLite; Env-Variablen nur noch Fallback, Änderungen greifen sofort
- /settings (Admin): Devlog-/Commit-Kanal als Dropdown aus allen sichtbaren Textkanälen,
  je mit Test-senden-Button
- Commit-Feed-Regeln: an/aus, Branch-Filter, ignorierte Repos (archiviert wird immer,
  gefiltert wird nur das Posten; ignorierte Repos komplett übersprungen)
- Status-Panel: Bot-Tag, Uptime, Devlog-/Commit-Zahlen, DB-Größe
- API: GET/PUT /api/settings, POST /api/settings/test/:target (alles Admin-only)
- COMMIT_CHANNEL_ID/DEVLOG_CHANNEL_ID in config optional

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 10:21:05 +02:00
co-authored by Claude Opus 4.8
parent 71d2bb07f1
commit ae5732a61b
14 changed files with 516 additions and 23 deletions
+38
View File
@@ -0,0 +1,38 @@
// Effektive Laufzeit-Konfiguration: DB-Setting (Webinterface) vor Env-Variable.
// Wird bei jedem Zugriff frisch aufgelöst — Änderungen greifen ohne Neustart.
import { getSetting } from './db.js';
import { config } from './config.js';
export function commitChannelId() {
return getSetting('commit_channel_id') || config.commitChannelId;
}
export function devlogChannelId() {
return getSetting('devlog_channel_id') || config.devlogChannelId;
}
/** Commit-Feed global an/aus (Default: an). Aus = weiter archivieren, nur nicht posten. */
export function commitFeedEnabled() {
return getSetting('commit_feed_enabled') !== '0';
}
/** Kommagetrennte Liste in Array übersetzen ('' → leer) */
function csv(value) {
return (value ?? '')
.split(',')
.map((s) => s.trim())
.filter(Boolean);
}
/** Branch-Filter: leer = alle Branches werden gepostet */
export function branchAllowed(branch) {
const allowed = csv(getSetting('commit_branch_filter'));
return allowed.length === 0 || allowed.includes(branch);
}
/** Ignorierte Repos (z. B. "D4rkst3r/ecobot") — werden komplett übersprungen */
export function repoIgnored(repo) {
return csv(getSetting('ignored_repos')).some(
(r) => r.toLowerCase() === repo.toLowerCase()
);
}