feat: Anhänge je Stunde, Klausur-Sitzplan mischen, Gefährdungsbeurteilungs-Assistent
Lesson bekommt dieselbe Anhang-Infrastruktur wie Documentation (Material, Arbeitsblätter, Experimentunterlagen), samt Fix einer Sync-Lücke, die Anhang- Dateibytes bisher nur für Documentation statt generisch übertragen hat (IHasAttachments). Sitzplan-Tab bekommt einen "Plätze mischen"-Button für Klausursitzpläne. Neu: mehrschrittiger Gefährdungsbeurteilungs-Assistent mit optionalem KI-Entwurf (ai-backend/gbu.php) und PDF-Export, Format bewusst als JSON-Anhang statt eigener Datenbank-Entität. Details und Architekturentscheidungen in TODO.md (4.2, 7.1.5, 10.1.8). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -381,6 +381,47 @@ public class AiPlanningService(HttpClient http, ILessonRepository lessons,
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fragt einen Entwurf für eine Gefährdungsbeurteilung zu genau dieser Lesson ab (Nutzerwunsch
|
||||
/// neben 4.2 "Anhänge je Stunde"): die KI erkennt aus Thema/Verlaufsplan das Experiment und
|
||||
/// liefert Stoffe, Gefährdungen, Schutzmaßnahmen etc. als Entwurf zur Weiterbearbeitung im
|
||||
/// Gefährdungsbeurteilungs-Assistenten. Ändert nichts an der Lesson selbst.
|
||||
/// </summary>
|
||||
public async Task<AiHazardAssessmentResponse> RequestHazardAssessmentDraftAsync(Unit unit, AiLesson lesson, string token)
|
||||
{
|
||||
var request = new AiHazardAssessmentRequest { Unit = BuildContext(unit, ""), Lesson = lesson };
|
||||
|
||||
using var req = new HttpRequestMessage(HttpMethod.Post, "gbu.php")
|
||||
{
|
||||
Content = JsonContent.Create(request, options: JsonOptions),
|
||||
};
|
||||
req.Headers.Authorization = new("Bearer", token);
|
||||
|
||||
HttpResponseMessage resp;
|
||||
try { resp = await http.SendAsync(req); }
|
||||
catch (HttpRequestException)
|
||||
{
|
||||
throw new AiBackendException("Der KI-Dienst ist nicht erreichbar. Bitte Internetverbindung prüfen.");
|
||||
}
|
||||
|
||||
if (resp.StatusCode == HttpStatusCode.Unauthorized)
|
||||
throw new AiBackendException("Anmeldung abgelaufen. Bitte in den Einstellungen erneut anmelden.");
|
||||
if (resp.StatusCode == (HttpStatusCode)402)
|
||||
throw new AiBackendException("Nicht genügend KI-Guthaben. Bitte Guthaben aufladen.");
|
||||
if (!resp.IsSuccessStatusCode)
|
||||
throw new AiBackendException("Die Anfrage an den KI-Dienst ist fehlgeschlagen.");
|
||||
|
||||
try
|
||||
{
|
||||
var result = await resp.Content.ReadFromJsonAsync<AiHazardAssessmentResponse>(JsonOptions);
|
||||
return result ?? throw new AiBackendException("Die Antwort der KI konnte nicht verarbeitet werden.");
|
||||
}
|
||||
catch (Exception ex) when (ex is not AiBackendException)
|
||||
{
|
||||
throw new AiBackendException("Die Antwort der KI konnte nicht verarbeitet werden. Bitte erneut versuchen.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rein (nur Repository-Lesezugriff für den Alternativpfad-Katalog, kein Schreiben) — testbar
|
||||
/// mit Fakes. Gibt die zu speichernden Lesson-Objekte zurück; der Aufrufer ruft
|
||||
|
||||
Reference in New Issue
Block a user