feat: GitHub Key Scanner mit automatischem Intervall und manueller UI
- KeyScannerService als BackgroundService (Timer + manueller Trigger) - GitHub Code Search: sucht nach sk-ant-oat01-* Keys in Dotenv-Dateien - AnthropicKeyChecker: shared Key-Check-Logik (ersetzt Duplikat in ApiKeysEndpoint) - ScannedKeyRecord Model mit Soft-Delete und Adopt-Verknüpfung - Scan-Endpoints: trigger, status, list, recheck, adopt, delete - API-Keys-Page: Scanner-UI mit Status-Indikator und Scanned-Keys-Liste - GitHub-URL pro gefundenem Key (html_url aus Search API) - Server-Settings: GitHubToken + ScanIntervalHours konfigurierbar - DB-Migration: scanned_keys Tabelle + api_keys Meta-Spalten (status, plan, usage) - ApiKeyRecord erweitert um Status/Plan/Usage-Felder mit UpdateApiKeyMeta()
This commit is contained in:
1 parent
db1a7c7f64
commit
006ef223bf
15 files changed
+996
-107
No files matched your search
@@ -306,9 +306,36 @@ public partial class DatabaseService
|
||||
// Migration: AnthropicToken aus appsettings.Production.json → api_keys Tabelle
|
||||
MigrateAnthropicTokenFromConfig(conn);
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS scanned_keys (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
scanned_key_id TEXT NOT NULL UNIQUE,
|
||||
api_key TEXT NOT NULL,
|
||||
source_url TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'unchecked',
|
||||
plan TEXT NOT NULL DEFAULT 'Unknown',
|
||||
usage_7d REAL,
|
||||
usage_5h REAL,
|
||||
scanned_at TEXT NOT NULL,
|
||||
checked_at TEXT,
|
||||
deleted INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_scanned_keys_api_key ON scanned_keys(api_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_scanned_keys_status ON scanned_keys(status);
|
||||
");
|
||||
|
||||
TryAddColumn(conn, "agents", "avatar_small", "TEXT");
|
||||
TryAddColumn(conn, "agents", "is_public", "INTEGER NOT NULL DEFAULT 0");
|
||||
TryAddColumn(conn, "sessions", "image_small", "TEXT");
|
||||
TryAddColumn(conn, "scanned_keys", "deleted", "INTEGER NOT NULL DEFAULT 0");
|
||||
TryAddColumn(conn, "scanned_keys", "adopted_api_key_id", "INTEGER");
|
||||
|
||||
// api_keys Metadaten-Spalten
|
||||
TryAddColumn(conn, "api_keys", "status", "TEXT");
|
||||
TryAddColumn(conn, "api_keys", "plan", "TEXT");
|
||||
TryAddColumn(conn, "api_keys", "usage_7d", "REAL");
|
||||
TryAddColumn(conn, "api_keys", "usage_5h", "REAL");
|
||||
TryAddColumn(conn, "api_keys", "checked_at", "TEXT");
|
||||
|
||||
// Migration: Bestehende PNG/JPEG-Avatare/Images zu WebP konvertieren
|
||||
MigrateImagesToWebP(conn);
|
||||
|
||||
Reference in new issue
Block a user