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:
1 parent
608118a823
commit
de388806cb
8 files changed
+226
-32
No files matched your search
@@ -122,6 +122,46 @@ namespace Gott.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extrahiert Plan/Usage-Metadaten nur aus Response-Headern (kein eigener HTTP-Request).
|
||||
/// Kann null zurückgeben wenn keine Usage-Header vorhanden sind.
|
||||
/// </summary>
|
||||
public static KeyCheckResult ExtractMetaFromHeaders(HttpResponseHeaders headers)
|
||||
{
|
||||
var d7Util = GetHeader(headers, "anthropic-ratelimit-unified-7d-utilization", "unified-7d-utilization");
|
||||
var d5hUtil = GetHeader(headers, "anthropic-ratelimit-unified-5h-utilization", "unified-5h-utilization");
|
||||
|
||||
if (d7Util == null && d5hUtil == null)
|
||||
return null; // Keine Usage-Header → nichts zu updaten
|
||||
|
||||
var overageUtil = GetHeader(headers, "anthropic-ratelimit-unified-overage-utilization", "unified-overage-utilization");
|
||||
var fallbackPct = GetHeader(headers, "anthropic-ratelimit-unified-fallback-percentage", "unified-fallback-percentage");
|
||||
|
||||
string plan;
|
||||
if (overageUtil != null && double.TryParse(overageUtil, NumberStyles.Float, CultureInfo.InvariantCulture, out var ov) && ov > 0)
|
||||
plan = "Max";
|
||||
else if (fallbackPct == null)
|
||||
plan = "Pro";
|
||||
else
|
||||
plan = "Pro/Max";
|
||||
|
||||
var result = new KeyCheckResult
|
||||
{
|
||||
Status = "valid",
|
||||
Plan = plan,
|
||||
IsSubscription = true
|
||||
};
|
||||
|
||||
if (d7Util != null && double.TryParse(d7Util, NumberStyles.Float, CultureInfo.InvariantCulture, out var d7))
|
||||
result.Usage7d = Math.Round(d7 * 100, 1);
|
||||
if (d5hUtil != null && double.TryParse(d5hUtil, NumberStyles.Float, CultureInfo.InvariantCulture, out var d5))
|
||||
result.Usage5h = Math.Round(d5 * 100, 1);
|
||||
if (overageUtil != null && double.TryParse(overageUtil, NumberStyles.Float, CultureInfo.InvariantCulture, out var ovVal))
|
||||
result.Overage = Math.Round(ovVal * 100, 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetHeader(HttpResponseHeaders headers, params string[] names)
|
||||
{
|
||||
foreach (var name in names)
|
||||
|
||||
Reference in new issue
Block a user