Stufe 4c (#764): Kommentare in C#, WebUI-Skripten, CSS und HTML auf Englisch

Rund 2.600 Kommentarblöcke in 310 C#-Dateien übersetzt, Begründungen vollständig
erhalten: blockweise gleiche Anzahl wie vorher, kein Block unter 60 % seiner
Länge, der Code außerhalb der Kommentare per Tokenizer byte-identisch geprüft.
Zitate deutscher Oberflächentexte und Testdaten bleiben deutsch.

WebUI: Kommentare in JS/CSS/HTML übersetzt, JSDoc-@param an die in 4b
umbenannten Parameter angeglichen.

Dabei behoben:
- 4b hatte "tag" (HTML-Tag) als deutsches "Tag" gelesen und zu "dayValue"
  gemacht (makeElement, svg, Tagesübersicht) - zurück auf tag/day.
- Aufgaben "InProgress" bekamen die Plakettenart "laufend", für die es nie eine
  CSS-Klasse gab - jetzt "success" wie laufende Instanzen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-10-04 12:45:03 +02:00
co-authored by Claude Opus 5.5
parent da4ceac7d5
commit 837a634a22
311 changed files with 7238 additions and 7252 deletions
@@ -3,7 +3,7 @@ using System.Text;
namespace ClawdDotNet.Core.Tests.Deploymentcenter;
/// <summary>Fängt die letzte Anfrage ab und antwortet fest, ohne Netzwerkzugriff.</summary>
/// <summary>Captures the last request and answers with a fixed response, without network access.</summary>
internal sealed class CapturingHandler(
HttpStatusCode status = HttpStatusCode.OK,
string responseBody = """{"status":"success"}""")
@@ -33,8 +33,8 @@ public sealed class DeploymentcenterApiTests
}
/// <summary>
/// Ein Fehlerumschlag zählt auch dann, wenn der Statuscode 200 lautet — der Server
/// antwortet nicht überall mit passendem HTTP-Code.
/// An error envelope counts even if the status code is 200 — the server
/// does not answer with a matching HTTP code everywhere.
/// </summary>
[Fact]
public async Task Fehlerumschlag_mit_HTTP_200_zaehlt_trotzdem()
@@ -54,15 +54,15 @@ public sealed class DeploymentcenterApiTests
[Fact]
public void Nicht_HTTPS_wird_abgelehnt()
{
// Über eine ungesicherte Verbindung ginge das Token im Klartext.
// Over an unsecured connection the token would go in plain text.
Should.Throw<ArgumentException>(() => new DeploymentcenterApi("http://dc.example", "tok"));
}
[Fact]
public void Localhost_darf_auch_ohne_TLS()
{
// Eine lokale Testinstallation hat selten ein Zertifikat, und mithören kann
// auf dem eigenen Rechner niemand.
// A local test installation rarely has a certificate, and nobody can listen in
// on the own machine.
using var api = new DeploymentcenterApi("http://localhost:8080", "tok");
api.BaseUrl.ShouldBe("http://localhost:8080");
}
@@ -44,9 +44,9 @@ public sealed class ErrorReporterTests
}
/// <summary>
/// Eine Fehlerschleife darf nicht in tausend Anfragen münden. Derselbe Fehler geht
/// höchstens einmal je Zeitfenster raus — der Server drosselt zwar auch, aber erst,
/// nachdem die Anfragen schon über die Leitung waren.
/// An error loop must not turn into a thousand requests. The same error goes out
/// at most once per time window — the server throttles too, but only
/// after the requests have already gone over the line.
/// </summary>
[Fact]
public async Task Derselbe_Fehler_geht_nur_einmal_je_Zeitfenster_raus()
@@ -81,8 +81,8 @@ public sealed class ErrorReporterTests
}
/// <summary>
/// Ein Meldeweg, der selbst wirft, wäre die schlechteste aller Welten — der
/// ursprüngliche Fehler ginge dabei verloren.
/// A reporting path that throws itself would be the worst of all worlds — the
/// original error would get lost in the process.
/// </summary>
[Fact]
public async Task Ein_abgelehnter_Aufruf_wirft_nicht_nach_aussen()
@@ -7,7 +7,7 @@ namespace ClawdDotNet.Core.Tests.Deploymentcenter;
public sealed class InstanceHealthProviderTests
{
/// <summary>Liefert einen festen Tagesverbrauch, ohne DB.</summary>
/// <summary>Delivers a fixed daily consumption, without a DB.</summary>
private sealed class FakeUsage(DailyUsage daily) : IUsageRepository
{
public Task RecordAsync(RunUsage usage, CancellationToken ct) => Task.CompletedTask;
@@ -54,8 +54,8 @@ public sealed class InstanceHealthProviderTests
}
/// <summary>
/// Ein Heartbeat beweist nur, dass ein Faden läuft. Steht der Scanner, arbeitet die
/// Instanz nichts mehr ab — und genau das soll die Prüfung sichtbar machen.
/// A heartbeat only proves that a thread is running. If the scanner stands still, the
/// instance no longer works through anything — and exactly that is what the check should make visible.
/// </summary>
[Fact]
public async Task Stehender_Scanner_meldet_warning()
@@ -89,8 +89,8 @@ public sealed class InstanceHealthProviderTests
}
/// <summary>
/// Metriken werden serverseitig nur ausgewertet, wenn sie Zahlen sind — alles andere
/// verwirft der Verlauf stillschweigend. Beschreibendes gehört in die Meldung.
/// Metrics are only evaluated server-side if they are numbers — everything else
/// the history silently discards. Descriptive things belong in the message.
/// </summary>
[Fact]
public async Task Instanzname_steht_in_der_Meldung_nicht_in_den_Metriken()
@@ -31,8 +31,8 @@ public sealed class TokenProvisionerTests
}
/// <summary>
/// Ein Sub-Token darf keine weiteren ausstellen. Das ist der Regelfall beim zweiten
/// Start und muss als sauberer Fehler herauskommen, nicht als Absturz.
/// A sub-token may not issue further ones. That is the normal case at the second
/// start and must come out as a clean error, not as a crash.
/// </summary>
[Fact]
public async Task Abgelehnte_Provisionierung_wirft_mit_Code()
@@ -50,12 +50,12 @@ public sealed class TokenProvisionerTests
// ─── whoami (SDK 2.7.1) ───
/// <summary>
/// Die Auskunft, auf die es ankommt: an welches Projekt das Token gebunden ist.
/// The information that matters: which project the token is bound to.
///
/// <para>Seit SDK 2.8.1 erbt ein Watchdog-Monitor das Projekt seines Ping-Tokens.
/// Fehlt die Bindung, landen die Befunde im Scheinprojekt „default" — und eine
/// Abfrage nach dem eigenen Projekt liefert für eine laufende, meldende Instanz null
/// Befunde. Die Aufsicht sähe aus wie „nichts auffällig".</para>
/// <para>Since SDK 2.8.1 a watchdog monitor inherits the project of its ping token.
/// If the binding is missing, the findings land in the phantom project "default" — and a
/// query for the own project returns zero findings for a running, reporting instance.
/// Supervision would look like "nothing unusual".</para>
/// </summary>
[Fact]
public async Task Whoami_liest_die_Projektbindung()
@@ -85,7 +85,7 @@ public sealed class TokenProvisionerTests
[Fact]
public async Task Ein_Token_ohne_Projekt_faellt_auf()
{
// project_slug ist JSON-null, nicht abwesend - genau so kommt es vom Server.
// project_slug is JSON null, not absent - exactly as it comes from the server.
var handler = new CapturingHandler(HttpStatusCode.OK,
"""
{"status":"success","token_id":"tok_s_9","name":"Instanz","type":"sub",
@@ -103,8 +103,8 @@ public sealed class TokenProvisionerTests
[Fact]
public async Task Eine_Antwort_ohne_Felder_wirft_nicht()
{
// Ein aelterer Server kennt whoami nicht in dieser Form. Die Auskunft darf
// ausfallen; abstuerzen darf sie nicht.
// An older server does not know whoami in this form. The information may
// be missing; it must not crash.
var handler = new CapturingHandler(HttpStatusCode.OK, """{"status":"success"}""");
using var api = new DeploymentcenterApi("https://dc.example", "t", new HttpClient(handler));
@@ -37,9 +37,9 @@ public sealed class WatchdogClientTests
}
/// <summary>
/// Der Server legt die Version in <c>watchdog_monitors.app_version</c> ab. Bei
/// mehreren Instanzen ist das der Unterschied zwischen „läuft" und „läuft noch auf
/// der alten Fassung".
/// The server stores the version in <c>watchdog_monitors.app_version</c>. With
/// several instances that is the difference between "runs" and "still runs on
/// the old version".
/// </summary>
[Fact]
public async Task Heartbeat_traegt_die_Anwendungsversion()
@@ -52,9 +52,9 @@ public sealed class WatchdogClientTests
}
/// <summary>
/// Der Monitor wird serverseitig über source + instance geführt. Zwei Instanzen
/// derselben Anwendung müssen deshalb unterschiedliche instance-Werte melden —
/// sonst überschreiben sie sich gegenseitig, und der Ausfall einer bliebe unsichtbar.
/// The monitor is tracked server-side via source + instance. Two instances
/// of the same application must therefore report different instance values —
/// otherwise they overwrite each other, and the failure of one would stay invisible.
/// </summary>
[Fact]
public async Task Jede_Instanz_meldet_unter_eigenem_Instanznamen()
@@ -87,7 +87,7 @@ public sealed class WatchdogClientTests
handler.LastBody.ShouldNotBeNull().ShouldContain("\"scheduler\":{\"ok\":false,\"message\":\"Steht.\"}");
}
/// <summary>Leere Angaben bleiben weg, statt als leeres Objekt zu erscheinen.</summary>
/// <summary>Empty details are left out instead of appearing as an empty object.</summary>
[Fact]
public async Task Ohne_Checks_und_Metriken_bleiben_die_Felder_weg()
{
@@ -6,7 +6,7 @@ namespace ClawdDotNet.Core.Tests.Deploymentcenter;
public sealed class WatchdogHeartbeatServiceTests
{
/// <summary>Merkt sich, was gesendet wurde, ohne Netzwerk.</summary>
/// <summary>Remembers what was sent, without a network.</summary>
private sealed class RecordingClient : IWatchdogClient
{
public List<(string Status, string? Message)> Heartbeats { get; } = [];
@@ -49,8 +49,8 @@ public sealed class WatchdogHeartbeatServiceTests
}
/// <summary>
/// Beim Update ist die Instanz gleich weg, kommt aber wieder. <c>stopped</c> wäre
/// die falsche Auskunft: Der Monitor bliebe liegen, bis jemand ihn anfasst.
/// On update the instance is about to go away, but comes back. <c>stopped</c> would be
/// the wrong information: the monitor would be left alone until someone touches it.
/// </summary>
[Fact]
public async Task Angekuendigte_Wartung_meldet_maintenance()
@@ -69,7 +69,7 @@ public sealed class WatchdogHeartbeatServiceTests
client.Events[^1].Kind.ShouldBe(WatchdogEventKind.MaintenanceStart);
}
/// <summary>Der erste Beat geht sofort raus, nicht erst nach einem vollen Intervall.</summary>
/// <summary>The first beat goes out immediately, not only after a full interval.</summary>
[Fact]
public async Task Erster_Heartbeat_kommt_sofort()
{
@@ -79,7 +79,7 @@ public sealed class WatchdogHeartbeatServiceTests
service.Start();
await service.DisposeAsync();
// Start-Ereignis, mindestens ein Beat, dann die Abmeldung.
// Start event, at least one beat, then the deregistration.
client.Events[0].Kind.ShouldBe(WatchdogEventKind.Started);
client.Heartbeats.Count.ShouldBeGreaterThanOrEqualTo(2);
client.Heartbeats[0].Status.ShouldBe(WatchdogStatus.Ok);