platform-docs/adr/0015-konfigurationsgruppen-admin-auftragskatalog-ui.md
Thomas Stallinger b9cef457c3 docs: ADR-0015 Gegenlese-Korrekturen
- Anführungszeichen vereinheitlicht auf „..." (Dokument nutzte
  durchgängig gerade Anführungszeichen, alle Nachbar-ADRs die
  deutsche Form) - inkl. Wechsel zu Backticks für die zitierten
  Code-Literale (quelle-Werte), analog zu ADR-0012s Formulierung
  derselben Werte.
- Konsequenzen-Absatz präzisiert: 'Der Admin-Bereich hat zwei
  Zugriffswege' war irreführend, da einer der beiden Wege explizit
  NICHT der Admin-Bereich ist, sondern das Kundenportal. Jetzt
  'OEs sind plattformweit über zwei Wege verwaltbar'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 21:40:48 +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
OEs sind jetzt plattformweit über zwei unterschiedlich mächtige Wege
verwaltbar (volle Selbstverwaltung nur als eingeloggte Kund:in im
Kundenportal, minimale Merkmal-Bearbeitung im Admin-Bereich) — 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`.