API-Keys: Source-URL, einheitliches Status-Schema, passive Usage-Erfassung, Usage-Bars

- SourceUrl-Feld in api_keys: GitHub-URL bei adoptierten Scan-Keys gespeichert
- HandleAdopt: Name = user/repo (aus URL extrahiert), SourceUrl = vollständige URL
- Status-Schema vereinheitlicht: überall 'valid' statt 'ok'/'usage_limited'
- AnthropicKeyChecker.ExtractMetaFromHeaders(): passive Header-Auswertung
- AnthropicService: TryUpdateKeyMeta() nach jedem Chat-Request (fire-and-forget)
- DatabaseService: UpdateApiKeyMetaByToken() für passive Updates per Token
- Frontend: formatKeyStatus() zentrale Status-Labels für API-Keys + Scanned-Keys
- Frontend: createUsageBadge() zweizeiliger Balken (Sitzung/Woche) mit Farbstufen
- CSS: Usage-Badge mit Track/Fill, warn (>=70%) und danger (>=90%) Klassen
This commit is contained in:
Meleki committed 2026-03-12 18:33:37 +01:00
1 parent 608118a823
commit de388806cb
8 files changed
+226 -32

No files matched your search

+16 -7
View File
@@ -49,6 +49,7 @@ public static class ApiKeysEndpoint
k.Usage7d,
k.Usage5h,
k.CheckedAt,
k.SourceUrl,
k.CreatedAt,
k.UpdatedAt
});
@@ -205,15 +206,16 @@ public static class ApiKeysEndpoint
}
var result = await AnthropicKeyChecker.CheckKeyAsync(httpFactory, existing.ApiKey);
var dbStatus = (result.Status == "ok" || result.Status == "usage_limited") ? "valid" : result.Status;
// Metadaten in DB speichern
await db.UpdateApiKeyMeta(keyId, result.Status, result.Plan, result.Usage7d, result.Usage5h);
await db.UpdateApiKeyMeta(keyId, dbStatus, result.Plan, result.Usage7d, result.Usage5h);
await ctx.Response.WriteAsJsonAsync(new
{
status = (result.Status == "ok" || result.Status == "usage_limited") ? "ok" : "error",
status = dbStatus,
message = result.Message,
keyType = result.Plan,
plan = result.Plan,
result.IsSubscription,
result.Usage7d,
result.Usage5h,
@@ -324,10 +326,16 @@ public static class ApiKeysEndpoint
return;
}
// URL als Titel verwenden, Metadaten übertragen
var title = !string.IsNullOrWhiteSpace(sk.SourceUrl)
? sk.SourceUrl.Replace("https://github.com/", "")
: $"Scan: {sk.Plan}";
// Name: user/repo aus URL extrahieren, SourceUrl: vollständige URL
var sourceUrl = !string.IsNullOrWhiteSpace(sk.SourceUrl) ? sk.SourceUrl : null;
var title = $"Scan: {sk.Plan ?? "Unknown"}";
if (sourceUrl != null)
{
var path = sourceUrl.Replace("https://github.com/", "");
var parts = path.Split('/');
if (parts.Length >= 2)
title = parts[0] + "/" + parts[1];
}
var now = DateTime.UtcNow.ToString("o");
var record = new ApiKeyRecord
@@ -342,6 +350,7 @@ public static class ApiKeysEndpoint
Usage7d = sk.Usage7d,
Usage5h = sk.Usage5h,
CheckedAt = sk.CheckedAt,
SourceUrl = sourceUrl,
CreatedAt = now,
UpdatedAt = now
};