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
+13 -1
View File
@@ -9,6 +9,7 @@ import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { config } from '../config.js';
import { saveCommits } from '../db.js';
import { commitFeedEnabled, branchAllowed, repoIgnored } from '../runtime-settings.js';
import { postPushEmbed } from '../bot/commit-feed.js';
import { registerAuthRoutes } from './auth.js';
import { registerApiRoutes } from './api.js';
@@ -59,7 +60,7 @@ export async function startWebServer(client) {
await app.register(fastifyMultipart, { limits: { fileSize: 10 * 1024 * 1024, files: 8 } });
registerAuthRoutes(app);
registerApiRoutes(app);
registerApiRoutes(app, client);
registerDevlogEndpoint(app, client);
// Healthcheck (für Portainer/NPM)
@@ -118,6 +119,11 @@ export async function startWebServer(client) {
const repo = payload.repository?.full_name ?? 'unbekannt';
const branch = (payload.ref ?? '').replace('refs/heads/', '');
// Ignorierte Repos komplett überspringen (Settings-Seite)
if (repoIgnored(repo)) {
return { ok: true, ignored: `repo ${repo}` };
}
const rows = commits.map((c) => ({
sha: c.id,
repo,
@@ -131,6 +137,12 @@ export async function startWebServer(client) {
const inserted = saveCommits(rows);
request.log.info(`Push auf ${repo}@${branch}: ${rows.length} Commit(s), ${inserted} neu gespeichert`);
// Posten nur wenn Feed aktiv und Branch erlaubt (archiviert wird immer)
if (!commitFeedEnabled() || !branchAllowed(branch)) {
request.log.info(`Embed übersprungen (Feed aus oder Branch ${branch} gefiltert)`);
return { ok: true, commits: rows.length, new: inserted, posted: false };
}
// Embed posten — Fehler hier sollen den Webhook nicht scheitern lassen (Gitea würde sonst retrien)
try {
await postPushEmbed(client, {