90 lines
3.6 KiB
C#
90 lines
3.6 KiB
C#
using System.Text.Json;
|
|
|
|
namespace ClawdDotNet.Core.Deploymentcenter;
|
|
|
|
/// <summary>Was aus einem Bugtracker-Eintrag geworden ist.</summary>
|
|
/// <param name="ItemId">Nummer des Eintrags im Deploymentcenter.</param>
|
|
/// <param name="IsNew">False, wenn ein bestehender Eintrag hochgezählt wurde.</param>
|
|
/// <param name="OccurrenceCount">Wie oft dieses Vorkommnis bisher gezählt wurde.</param>
|
|
/// <param name="Url">Adresse der Übersicht, für einen Hinweis an den Benutzer.</param>
|
|
public sealed record BugtrackerReport(long ItemId, bool IsNew, int OccurrenceCount, string? Url);
|
|
|
|
/// <summary>Art eines Eintrags. Der Server kennt darüber hinaus noch <c>idea</c>.</summary>
|
|
public static class BugtrackerItemType
|
|
{
|
|
public const string Bug = "bug";
|
|
public const string Feature = "feature";
|
|
public const string Idea = "idea";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anbindung an <c>POST /api/bugtracker/v1/report</c> — der Weg, auf dem ClawdDotNet
|
|
/// selbst (oder ein Benutzer über die Oberfläche) einen Fehler oder Wunsch einträgt.
|
|
///
|
|
/// <para>Abgegrenzt vom <see cref="ErrorReporter"/>: Der meldet <em>ungefangene</em>
|
|
/// Ausnahmen automatisch; hier geht es um bewusst formulierte Einträge mit Titel und
|
|
/// Beschreibung. Serverseitig landen beide in derselben Tabelle — was richtig ist,
|
|
/// denn ein zweiter Speicher wäre nur ein zweiter Ort, an dem man suchen müsste.</para>
|
|
///
|
|
/// <para><b>Der Absender kommt aus dem Token</b> und lässt sich nicht frei wählen —
|
|
/// sonst könnte sich ein Agent als ein anderer ausgeben.</para>
|
|
/// </summary>
|
|
public sealed class BugtrackerClient(
|
|
DeploymentcenterApi api, string projectSlug, string environment, string build)
|
|
{
|
|
/// <param name="type">Siehe <see cref="BugtrackerItemType"/>.</param>
|
|
/// <param name="clientRef">
|
|
/// Freier Idempotenz-Schlüssel. Zweimal derselbe Wert erzeugt keinen zweiten
|
|
/// Eintrag — nützlich, wenn eine Meldung nach einem Verbindungsabbruch wiederholt
|
|
/// wird.
|
|
/// </param>
|
|
public async Task<BugtrackerReport> ReportAsync(
|
|
string type,
|
|
string title,
|
|
string? description = null,
|
|
string severity = "medium",
|
|
string? clientRef = null,
|
|
IReadOnlyDictionary<string, object?>? context = null,
|
|
CancellationToken ct = default)
|
|
{
|
|
var payload = new Dictionary<string, object?>
|
|
{
|
|
["project_slug"] = projectSlug,
|
|
["type"] = type,
|
|
["title"] = title,
|
|
["description"] = description,
|
|
["severity"] = severity,
|
|
["environment"] = environment,
|
|
["build_version"] = build
|
|
};
|
|
|
|
if (!string.IsNullOrWhiteSpace(clientRef))
|
|
payload["client_ref"] = clientRef;
|
|
|
|
if (context is { Count: > 0 })
|
|
payload["context"] = context;
|
|
|
|
var response = await api.PostAsync("/api/bugtracker/v1/report", payload, ct)
|
|
.ConfigureAwait(false);
|
|
|
|
return new BugtrackerReport(
|
|
ReadLong(response, "item_id"),
|
|
ReadBool(response, "is_new"),
|
|
(int)ReadLong(response, "occurrence_count"),
|
|
ReadString(response, "url"));
|
|
}
|
|
|
|
private static long ReadLong(JsonElement root, string name) =>
|
|
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.Number
|
|
? v.GetInt64()
|
|
: 0;
|
|
|
|
private static bool ReadBool(JsonElement root, string name) =>
|
|
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.True;
|
|
|
|
private static string? ReadString(JsonElement root, string name) =>
|
|
root.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.String
|
|
? v.GetString()
|
|
: null;
|
|
}
|