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:
Meleki committed 2026-03-12 15:35:22 +01:00
1 parent db1a7c7f64
commit 006ef223bf
15 files changed
+996 -107

No files matched your search

+5
View File
@@ -8,6 +8,11 @@ public class ApiKeyRecord
public string Name { get; set; } // Anzeigename z.B. "Tausi Pro Key"
public string ApiKey { get; set; } // Der eigentliche Key
public bool IsActive { get; set; } // Nur einer pro Provider aktiv
public string Status { get; set; } // ok, invalid, rate_limited, quota_exceeded, error
public string Plan { get; set; } // Pro, Max, Pro/Max, API Console, Unknown
public double? Usage7d { get; set; }
public double? Usage5h { get; set; }
public string CheckedAt { get; set; } // Wann zuletzt geprüft
public string CreatedAt { get; set; }
public string UpdatedAt { get; set; }
}
+17
View File
@@ -0,0 +1,17 @@
namespace Gott.Models;
public class ScannedKeyRecord
{
public long Id { get; set; }
public string ScannedKeyId { get; set; }
public string ApiKey { get; set; }
public string SourceUrl { get; set; } // GitHub-URL wo der Key gefunden wurde
public string Status { get; set; } // valid, invalid, auth_error, rate_limited, quota_exceeded, error
public string Plan { get; set; } // Pro, Max, Pro/Max, API, Unknown
public double? Usage7d { get; set; }
public double? Usage5h { get; set; }
public string ScannedAt { get; set; } // Wann gefunden
public string CheckedAt { get; set; } // Wann zuletzt geprüft
public int Deleted { get; set; } // Soft-Delete (1 = gelöscht/ignoriert)
public long? AdoptedApiKeyId { get; set; } // Verknüpfung zur api_keys.id (null = nicht übernommen)
}