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:
2026-08-20 17:13:14 +02:00
co-authored by Claude Sonnet 5
parent 331033db5c
commit 038337997f
29 changed files with 1886 additions and 22 deletions
@@ -401,11 +401,17 @@ public partial class DocumentationDialogViewModel : ObservableObject
public class AttachmentItem(string storageId, string fileName, long sizeBytes, DateTime uploadedAt)
{
public const string HazardAssessmentSuffix = ".gbu.json";
public string StorageId { get; } = storageId;
public string FileName { get; } = fileName;
public long SizeBytes { get; } = sizeBytes;
public DateTime UploadedAt { get; } = uploadedAt;
public string SizeDisplay => $"{SizeBytes / 1024.0:0} KB";
/// Strukturierter Gefährdungsbeurteilungs-Anhang (siehe HazardAssessment) statt einer
/// beliebigen hochgeladenen Datei — steuert im Anhang-Editor, ob "Öffnen"+"PDF" statt des
/// generischen "Speichern" angeboten wird.
public bool IsHazardAssessment => FileName.EndsWith(HazardAssessmentSuffix, StringComparison.OrdinalIgnoreCase);
}
public class TagChip(string text)