feat: Posteingang und Entscheiden für die Fachebene (Schritt 5 der Baureihenfolge)
Ebene 3 (Rollen verantwortlicher/pruefer) bekommt GET /faelle
(Posteingang aller offenen Anträge des Mandanten) und GET/POST
/faelle/{id} zum Entscheiden. Eine Entscheidung friert Regelwerk-,
Katalog- und den vollständigen Werkzeugdatensatz ein, verlangt eine
Begründung bei Abweichung vom abgeleiteten Vorschlag, erlaubt bei
Genehmigung nur ein durch die Bewertung zulässiges Werkzeug und
protokolliert die Entscheidung im Audit-Log. entscheidung ist
append-only wie bewertung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,60 +14,7 @@
|
||||
<p><strong>Häufigkeit:</strong> {{.Haeufigkeit}}</p>
|
||||
|
||||
{{if .Bewertung}}
|
||||
<h2>Bewertung</h2>
|
||||
|
||||
{{if .Bewertung.Verboten}}
|
||||
<p class="fehler"><strong>Verboten.</strong> Diese Nutzung fällt laut Einstufung unter ein verbotenes KI-Praktiken-Muster der KI-VO ({{.Bewertung.Einstufung}}). {{.Bewertung.EinstufungHerleitung}}</p>
|
||||
{{end}}
|
||||
|
||||
<p><strong>Datenklasse:</strong> {{.Bewertung.Datenklasse}}<br>
|
||||
<span class="hinweis">{{.Bewertung.DatenklasseHerleitung}}</span></p>
|
||||
|
||||
<p><strong>KI-VO-Einstufung:</strong> {{.Bewertung.Einstufung}}<br>
|
||||
<span class="hinweis">{{.Bewertung.EinstufungHerleitung}}</span></p>
|
||||
|
||||
{{if .Bewertung.Anforderungen}}
|
||||
<h3>Anforderungen</h3>
|
||||
<ul class="findings">
|
||||
{{range .Bewertung.Anforderungen}}
|
||||
<li class="finding finding-mittel">
|
||||
<strong>{{.Beschreibung}}</strong>
|
||||
<p>{{.Herleitung}}</p>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{end}}
|
||||
|
||||
{{if not .Bewertung.Verboten}}
|
||||
<h3>Zulässige Werkzeuge</h3>
|
||||
{{if .Bewertung.ZulaessigeWerkzeuge}}
|
||||
<ul>
|
||||
{{range .Bewertung.ZulaessigeWerkzeuge}}<li>{{.}}</li>{{end}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<p class="rueckfrage">Kein Werkzeug im Katalog erfüllt aktuell alle Anforderungen dieses Antrags.</p>
|
||||
{{end}}
|
||||
|
||||
{{if .Bewertung.AusgeschlosseneWerkzeuge}}
|
||||
<h3>Ausgeschlossene Werkzeuge</h3>
|
||||
<ul class="findings">
|
||||
{{range .Bewertung.AusgeschlosseneWerkzeuge}}
|
||||
<li class="finding finding-niedrig">
|
||||
<strong>{{.Name}}</strong>
|
||||
<p>Nicht erfüllt: {{range $i, $a := .NichtErfuellt}}{{if $i}}, {{end}}{{$a}}{{end}}</p>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<p class="disclaimer">
|
||||
Das System entscheidet nicht. Es bereitet vor. Diese Einstufung ist ein
|
||||
Vorschlag zur Herleitung von Datenklasse, KI-VO-Einstufung und
|
||||
Anforderungen (Regelwerk {{.Bewertung.RegelwerkVersion}}, Katalog
|
||||
{{.Bewertung.KatalogVersion}}, berechnet am {{.Bewertung.CreatedAt}}) —
|
||||
die Entscheidung trifft ein Mensch.
|
||||
</p>
|
||||
{{template "bewertung-block" .Bewertung}}
|
||||
{{else}}
|
||||
<p class="hinweis">Die Bewertung wird berechnet, sobald der Antrag eingereicht ist.</p>
|
||||
{{end}}
|
||||
|
||||
24
internal/web/templates/faelle_liste.html
Normal file
24
internal/web/templates/faelle_liste.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{{define "faelle-liste"}}<!doctype html>
|
||||
<html lang="de">
|
||||
<head>{{template "head" .}}</head>
|
||||
<body>
|
||||
{{template "nav" .Nav}}
|
||||
<div class="page">
|
||||
<h1>Posteingang</h1>
|
||||
{{if not .Faelle}}
|
||||
<p class="keine-findings">Keine offenen Anträge — alles bearbeitet.</p>
|
||||
{{else}}
|
||||
<ul class="beitraege-liste">
|
||||
{{range .Faelle}}
|
||||
<li>
|
||||
<a href="/faelle/{{.ID}}">
|
||||
<strong>{{.Titel}}</strong> · {{.Haeufigkeit}} · eingereicht am {{.CreatedAt}}
|
||||
</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
60
internal/web/templates/fall_detail.html
Normal file
60
internal/web/templates/fall_detail.html
Normal file
@@ -0,0 +1,60 @@
|
||||
{{define "fall-detail"}}<!doctype html>
|
||||
<html lang="de">
|
||||
<head>{{template "head" .}}</head>
|
||||
<body>
|
||||
{{template "nav" .Nav}}
|
||||
<div class="page">
|
||||
<p><a href="/faelle">← Posteingang</a></p>
|
||||
<h1>{{.Titel}}</h1>
|
||||
<p class="hinweis">Eingereicht am {{.CreatedAt}} — Status: <span class="status status-{{.Status}}">{{.Status}}</span></p>
|
||||
|
||||
<h2>Vorhaben</h2>
|
||||
<p><strong>Was soll die KI tun?</strong><br>{{.Beschreibung}}</p>
|
||||
<p><strong>Was soll herauskommen?</strong><br>{{.Ergebnis}}</p>
|
||||
<p><strong>Häufigkeit:</strong> {{.Haeufigkeit}}</p>
|
||||
|
||||
{{if .Bewertung}}
|
||||
{{template "bewertung-block" .Bewertung}}
|
||||
{{else}}
|
||||
<p class="hinweis">Für diesen Antrag liegt noch keine Bewertung vor.</p>
|
||||
{{end}}
|
||||
|
||||
{{if .Entscheidung}}
|
||||
<h2>Entscheidung</h2>
|
||||
<p><strong>{{.Entscheidung.Entscheidung}}</strong>{{if .Entscheidung.WerkzeugName}} — {{.Entscheidung.WerkzeugName}}{{end}}<br>
|
||||
<span class="hinweis">am {{.Entscheidung.CreatedAt}}{{if .Entscheidung.GueltigBis}}, gültig bis {{.Entscheidung.GueltigBis}}{{end}}</span></p>
|
||||
{{if .Entscheidung.Begruendung}}<p>{{.Entscheidung.Begruendung}}</p>{{end}}
|
||||
{{else if .CanEntscheiden}}
|
||||
<h2>Entscheiden</h2>
|
||||
{{if .Error}}<p class="fehler">{{.Error}}</p>{{end}}
|
||||
<form method="post" action="/faelle/{{.ID}}/entscheiden">
|
||||
<fieldset>
|
||||
<legend>Entscheidung</legend>
|
||||
<label><input type="radio" name="entscheidung" value="genehmigt" required> Genehmigt</label>
|
||||
<label><input type="radio" name="entscheidung" value="genehmigt_mit_auflagen"> Genehmigt mit Auflagen</label>
|
||||
<label><input type="radio" name="entscheidung" value="abgelehnt"> Abgelehnt</label>
|
||||
<label><input type="radio" name="entscheidung" value="rueckfrage"> Rückfrage</label>
|
||||
</fieldset>
|
||||
|
||||
{{if .WerkzeugOptionen}}
|
||||
<label>Werkzeug (bei Genehmigung erforderlich)
|
||||
<select name="werkzeug_id">
|
||||
<option value="">— auswählen —</option>
|
||||
{{range .WerkzeugOptionen}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
|
||||
</select>
|
||||
</label>
|
||||
{{end}}
|
||||
|
||||
<label>Begründung (Pflicht bei Abweichung vom Vorschlag)
|
||||
<textarea name="begruendung" rows="3"></textarea>
|
||||
</label>
|
||||
|
||||
<button type="submit">Entscheidung speichern</button>
|
||||
</form>
|
||||
{{else}}
|
||||
<p class="hinweis">Noch keine Entscheidung getroffen. Nur die Rolle "Verantwortlicher" kann entscheiden.</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -10,9 +10,72 @@
|
||||
<nav>
|
||||
<a href="/">Start</a>
|
||||
{{if not .IsBetreiber}}<a href="/antraege">Meine Anträge</a>{{end}}
|
||||
{{if .IsFachebene}}<a href="/faelle">Posteingang</a>{{end}}
|
||||
{{if .IsBetreiber}}<a href="/betreiber">Plattform</a>{{end}}
|
||||
<form method="post" action="/logout" style="display:inline">
|
||||
<button type="submit">Abmelden</button>
|
||||
</form>
|
||||
</nav>
|
||||
{{end}}
|
||||
|
||||
{{/* bewertung-block rendert eine Bewertung (Datenklasse, KI-VO-
|
||||
Einstufung, Anforderungen, Werkzeuge, Pflicht-Disclaimer) — gemeinsam
|
||||
genutzt von antrag_detail.html (Ebene 2, nur Ansicht) und
|
||||
fall_detail.html (Ebene 3, mit Entscheiden-Formular). Erwartet eine
|
||||
*bewertungView als . */}}
|
||||
{{define "bewertung-block"}}
|
||||
<h2>Bewertung</h2>
|
||||
|
||||
{{if .Verboten}}
|
||||
<p class="fehler"><strong>Verboten.</strong> Diese Nutzung fällt laut Einstufung unter ein verbotenes KI-Praktiken-Muster der KI-VO ({{.Einstufung}}). {{.EinstufungHerleitung}}</p>
|
||||
{{end}}
|
||||
|
||||
<p><strong>Datenklasse:</strong> {{.Datenklasse}}<br>
|
||||
<span class="hinweis">{{.DatenklasseHerleitung}}</span></p>
|
||||
|
||||
<p><strong>KI-VO-Einstufung:</strong> {{.Einstufung}}<br>
|
||||
<span class="hinweis">{{.EinstufungHerleitung}}</span></p>
|
||||
|
||||
{{if .Anforderungen}}
|
||||
<h3>Anforderungen</h3>
|
||||
<ul class="findings">
|
||||
{{range .Anforderungen}}
|
||||
<li class="finding finding-mittel">
|
||||
<strong>{{.Beschreibung}}</strong>
|
||||
<p>{{.Herleitung}}</p>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{end}}
|
||||
|
||||
{{if not .Verboten}}
|
||||
<h3>Zulässige Werkzeuge</h3>
|
||||
{{if .ZulaessigeWerkzeuge}}
|
||||
<ul>
|
||||
{{range .ZulaessigeWerkzeuge}}<li>{{.}}</li>{{end}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<p class="rueckfrage">Kein Werkzeug im Katalog erfüllt aktuell alle Anforderungen dieses Antrags.</p>
|
||||
{{end}}
|
||||
|
||||
{{if .AusgeschlosseneWerkzeuge}}
|
||||
<h3>Ausgeschlossene Werkzeuge</h3>
|
||||
<ul class="findings">
|
||||
{{range .AusgeschlosseneWerkzeuge}}
|
||||
<li class="finding finding-niedrig">
|
||||
<strong>{{.Name}}</strong>
|
||||
<p>Nicht erfüllt: {{range $i, $a := .NichtErfuellt}}{{if $i}}, {{end}}{{$a}}{{end}}</p>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
<p class="disclaimer">
|
||||
Das System entscheidet nicht. Es bereitet vor. Diese Einstufung ist ein
|
||||
Vorschlag zur Herleitung von Datenklasse, KI-VO-Einstufung und
|
||||
Anforderungen (Regelwerk {{.RegelwerkVersion}}, Katalog
|
||||
{{.KatalogVersion}}, berechnet am {{.CreatedAt}}) —
|
||||
die Entscheidung trifft ein Mensch.
|
||||
</p>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user