platform-docs/adr/0015-konfigurationsgruppen-admin-auftragskatalog-ui.md
Thomas Stallinger 172f6f1db8 docs: ADR-0015 Konfigurationsgruppen im Admin-Auftragskatalog-UI
Dokumentiert die direkte Folgeanfrage zu ADR-0012: OE-Spalte + Verschieben
in der Admin-Geräteliste, anklickbare Herkunfts-Links (quelle_id in
resolve_katalog_overrides()), neue bewusst schlanke Admin-OE-Ansicht
(nur Merkmale-Editor, kein CRUD - OE-Struktur bleibt Kunden-Self-Service),
plus den dabei gefundenen und gefixten Routing-Bug im geteilten
Auftragskatalog-Template.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 21:37:23 +02:00

93 lines
4.8 KiB
Markdown

# ADR-0015: Konfigurationsgruppen im Admin-Auftragskatalog-UI
**Status:** Beschlossen
**Datum:** 12.08.2026
## Kontext
ADR-0012 brachte OEs/Gruppen samt Herkunfts-Anzeige ("via OE"/"via Gruppe")
im Auftragskatalog — nutzbar war das aber nur über das Kundenportal. Der
interne Admin-Bereich (`/admin/geraete`) teilt sich zwar dasselbe
Auftragskatalog-Template (`templates/auftragskatalog.html`) mit dem
Kundenportal und bekam die Herkunfts-Anzeige dadurch automatisch mit, aber:
1. Die Admin-Geräteliste zeigte keine OE-Spalte und bot keine Möglichkeit,
ein Gerät zwischen OEs zu verschieben (die Kundenportal-Liste bekam das
bereits in der vorherigen Session).
2. "via OE"/"via Gruppe" war reiner Text ohne Sprungziel — welche konkrete
OE oder Gruppe verantwortlich ist, ließ sich aus der Anzeige nicht
erkennen, geschweige denn direkt dorthin wechseln.
3. Für Gruppen existierte bereits eine Admin-Detailseite
(`/admin/kunden/{org_id}/gruppen/{id}`), für OEs **keine einzige**
Admin-Ansicht — ein Link "via OE" hätte kein Ziel gehabt.
Beim Umsetzen zusätzlich gefunden: `templates/auftragskatalog.html`
verdrahtete die Select-/Deselect-Formulare fest auf
`/geraete/{id}/auftragskatalog/...`, den Kundenportal-Pfad, statt den
mitgelieferten `zurueck_url`-Kontextwert zu nutzen (der in beiden Routern
`routers/geraete.py` und `routers/admin_geraete.py` — bereits exakt den
richtigen Präfix trägt). Für einen Admin, der ein Gerät einer fremden
Organisation ansah, schlug Auswählen/Abwählen dadurch mit `404` fehl
(`find_device_in_organization()` prüft gegen `user.organization_id`, die
für einen Admin nie zur fremden Organisation passt) — ein latenter Bug seit
der gemeinsamen Template-Nutzung (ADR-0011), unabhängig von dieser
Entscheidung hier mitgefixt.
## Entscheidung
**Herkunft bekommt eine konkrete ID, nicht nur einen Typ.**
`resolve_katalog_overrides()` (`provisioning-server/app.py`) liefert
zusätzlich zu `quelle` ("oe"/"gruppe"/"geraet"/"workspace") die konkrete
`quelle_id` — bei OEs eindeutig die gewinnende OE in der Kette, bei Gruppen
eine der zustimmenden Gruppen (bei mehreren gleichzeitig zustimmenden
Gruppen wird bewusst nicht jede einzeln attribuiert, sondern nur eine
davon verlinkt — Sprungziel-Zweck, kein vollständiger Audit-Trail). Die
eigentliche "mehr gewinnt"-Auflösungslogik aus ADR-0012 ändert sich dadurch
nicht, nur die zusätzlich mitgeführte Information.
**`fetch_all_devices()` bekommt denselben OE-Join** wie
`fetch_devices_for_organization()` aus der letzten Session — Grundlage für
OE-Spalte und Verschieben-Aktion in der Admin-Geräteliste, symmetrisch zum
Kundenportal.
**Admin-OE-Ansicht bewusst minimal**, kein Pendant zum vollen Kundenportal-
Self-Service (`/struktur`): nur ein Merkmale-Editor
(`/admin/kunden/{org_id}/organisationseinheiten/{oe_id}/merkmale`), der als
Sprungziel für die Herkunfts-Links dient. Kein Anlegen/Umbenennen/Löschen
von OEs im Admin-Bereich — die OE-Struktur bleibt laut ADR-0012 bewusst
Kunden-Self-Service, das wird hier nicht revidiert. Für die
Merkmal-Bearbeitung selbst reichten die bereits für `/struktur` gebauten
anode-Endpunkte (`GET/POST /api/v1/organisationseinheiten/{oe_id}/merkmale
...`) unverändert aus — keine neuen anode-Endpunkte nötig, exakt das in
ADR-0012 für Gruppen vorhergesagte (und dort auch schon eingetretene)
Muster: Self-Service-Endpunkte sind von Anfang an so generisch, dass eine
zweite Oberfläche (hier: eine schlankere Admin-Ansicht statt vollem
Self-Service) sie ohne Backend-Änderung mitnutzen kann.
**Bugfix ohne Verhaltensänderung für den Kundenportal-Pfad:** Die
Formular-Ziele in `auftragskatalog.html` nutzen jetzt `{{ zurueck_url
}}/{{ device.id }}/...` statt des festen `/geraete/...`-Präfixes.
`zurueck_url` war für beide Aufrufer bereits korrekt gesetzt (`/geraete`
bzw. `/admin/geraete`), nur ungenutzt — reine Fehlerbehebung, keine neue
Fähigkeit.
## Konsequenzen
Der Admin-Bereich hat jetzt für OEs zwei unterschiedlich mächtige
Zugriffswege (volle Selbstverwaltung nur über das Kundenportal als
eingeloggte Kund:in, minimale Merkmal-Bearbeitung über die neue
Admin-Seite) — bewusst asymmetrisch zu Gruppen (dort admin-verwaltbar seit
ADR-0012, inzwischen zusätzlich auch Kundenportal-Self-Service). Sollte
künftig doch ein vollständiges Admin-seitiges OE-CRUD gebraucht werden
(Support-Fall: Kund:in bittet den Betreiber, OEs für sie anzulegen), ist
das eine reine Ergänzung um Create/Rename/Delete-Routen nach dem
Gruppen-Vorbild in `routers/admin_kunden.py` — keine Datenmodell-Änderung.
Der Bugfix betrifft ausschließlich den Admin-Pfad in der Praxis (der
Kundenportal-Pfad war korrekt, weil `zurueck_url` dort zufällig mit dem
zuvor hartkodierten Wert übereinstimmte) — kein Verhalten für bestehende
Kundenportal-Nutzer:innen ändert sich.
Details zum Datenmodell und zur Grundentscheidung: ADR-0012,
`09-data-model-v1.md`.