Textreduktion

This commit is contained in:
2026-09-07 23:37:09 +02:00
parent 3ecc28ef73
commit 235b471ad9
39 changed files with 205 additions and 553 deletions
+6 -27
View File
@@ -1,40 +1,23 @@
\section{Autorisierungskonzept}
\label{sec:authorization}
Der Dokumentenbereich verarbeitet Vertragsunterlagen, Abrechnungsdaten und Security Assessments. Das Autorisierungskonzept arbeitet zweistufig: Eine Rollenprüfung entscheidet, \emph{ob} ein Benutzer den Bereich betreten darf, eine Mandantenprüfung, \emph{welche} Dokumente er sieht.
Das Autorisierungskonzept arbeitet zweistufig: Eine Rollenprüfung entscheidet, \emph{ob} ein Benutzer den Bereich betreten darf, eine Mandantenprüfung, \emph{welche} Dokumente er sieht.
\subsection{Authentifizierung und Claims}
Die Authentifizierung erfolgt über Microsoft Entra~ID. Das Token enthält zwei für dieses Projekt wesentliche Angaben:
\begin{itemize}
\item die \textbf{Efecte-Organisations-ID} des Benutzers, über die seine Zugehörigkeit zu einem Kunden bestimmt wird,
\item den \textbf{Efecte-Firmennamen}, der über den Claim \texttt{efecte:company\_name} bereitgestellt wird.
\end{itemize}
Beide Werte lagen bereits vor Projektbeginn im Token vor. Dass der Firmenname verfügbar ist, wurde erst bei der Recherche zum Kundenordner-Lookup erkannt — er ermöglicht die Bestimmung des Ordnernamens ohne zusätzlichen Efecte-Aufruf (siehe Abschnitt~\ref{sec:lookup-decision}).
Die Authentifizierung erfolgt über Microsoft Entra~ID. Das Token enthält die \textbf{Efecte-Organisations-ID}, über die die Kundenzugehörigkeit bestimmt wird, und den \textbf{Efecte-Firmennamen} aus dem Claim \texttt{efecte:company\_name}. Dass der Firmenname verfügbar ist, wurde erst bei der Lookup-Recherche erkannt — er ermöglicht die Bestimmung des Ordnernamens ohne zusätzlichen Efecte-Aufruf (siehe Abschnitt~\ref{sec:lookup-decision}).
\subsection{Anwendungsrolle Documents.Read}
Für den Zugriff auf den Dokumentenbereich wurde in Entra~ID die Anwendungsrolle \texttt{Documents.Read} angelegt. Eine Differenzierung nach Dokumententyp ist nicht vorgesehen: Ein Benutzer sieht entweder alle Dokumente seiner Organisation oder gar keine.
Die Rolle wirkt an zwei Stellen: Sie steuert die Sichtbarkeit des Navigationspunkts und schützt die Seite gegen direkten URL-Aufruf. Die zweite Prüfung ist sicherheitsrelevant; das Ausblenden des Menüpunkts ist reine Benutzerführung.
Für den Zugriff wurde in Entra~ID die Anwendungsrolle \texttt{Documents.Read} angelegt; eine Differenzierung nach Dokumententyp gibt es nicht. Sie steuert die Sichtbarkeit des Navigationspunkts und schützt die Seite gegen direkten URL-Aufruf. Nur die zweite Prüfung ist sicherheitsrelevant; das Ausblenden des Menüpunkts ist Benutzerführung.
\subsection{403 statt 404}
Ein diskutierter Punkt war die Antwort bei unberechtigtem Zugriff auf \texttt{/documents}. Die ursprüngliche Anforderung sah 404 vor, um die Existenz der Ressource zu verbergen.
Die Anforderung wurde auf 403 geändert. Die Existenz des Dokumentenbereichs ist kein Geheimnis. Zudem erschwert 404 die Fehlersuche: Ein Benutzer ohne Rolle erhält dieselbe Antwort wie bei einem Tippfehler. Dieser Fall trat später im Abnahmetest ein (siehe Abschnitt~\ref{sec:acceptance-testing}) und bestätigte die Entscheidung.
Der Trade-off: minimaler Informationsgewinn für einen Angreifer gegen deutlich bessere Diagnostizierbarkeit.
Die ursprüngliche Anforderung sah bei unberechtigtem Zugriff auf \texttt{/documents} eine 404-Antwort vor, um die Existenz der Ressource zu verbergen. Sie wurde auf 403 geändert: Die Existenz des Bereichs ist kein Geheimnis, und 404 erschwert die Fehlersuche, weil ein Benutzer ohne Rolle dieselbe Antwort wie bei einem Tippfehler erhält. Dieser Fall trat später im Abnahmetest ein (siehe Abschnitt~\ref{sec:acceptance-testing}) und bestätigte die Entscheidung.
\subsection{Mandantentrennung}
Die zweite Stufe stellt sicher, dass ein berechtigter Benutzer ausschließlich die Dokumente seiner Organisation sieht. Aus der Organisations-ID wird der zugehörige Kundenordner aufgelöst, und alle Abfragen werden auf dieses Präfix eingeschränkt (siehe Abschnitt~\ref{sec:s3-layout}).
Entscheidend ist, dass die Einschränkung bereits Bestandteil der Abfrage ist — Houston lädt nie Dokumente fremder Kunden, um sie nachträglich herauszufiltern. Ein Fehler in der Darstellungsschicht kann damit nicht zu einer Offenlegung führen.
Abbildung~\ref{fig:auth-sequence} stellt den vollständigen Ablauf dar.
Aus der Organisations-ID wird der zugehörige Kundenordner aufgelöst, und alle Abfragen werden auf dieses Präfix eingeschränkt (siehe Abschnitt~\ref{sec:s3-layout}). Da die Einschränkung bereits Bestandteil der Abfrage ist, lädt Houston nie Dokumente fremder Kunden, um sie nachträglich herauszufiltern; ein Fehler in der Darstellungsschicht kann somit nicht zu einer Offenlegung führen. Abbildung~\ref{fig:auth-sequence} stellt den Ablauf dar.
\begin{figure}[H]
\centering
@@ -45,8 +28,4 @@ Abbildung~\ref{fig:auth-sequence} stellt den vollständigen Ablauf dar.
\subsection{Absicherung der Einzelzugriffe}
Auch Download, ZIP-Download, PDF-Vorschau und Freigabelinks nehmen jeweils einen Dokumentschlüssel entgegen. Für jeden Pfad wird der angeforderte Schlüssel gegen das aufgelöste Kundenpräfix geprüft, bevor auf den Speicher zugegriffen wird.
Zusätzlich wird der Pfad auf Bestandteile untersucht, mit denen sich der Kundenordner verlassen ließe (NFA-6). Ohne diese Prüfung könnte ein Benutzer durch Manipulation des Parameters auf fremde Ordner zugreifen.
Freigabelinks stellen keine Ausnahme dar: Sie enthalten keine Anmeldeinformationen und gewähren keinen eigenständigen Zugriff. Ein Empfänger ohne Rolle und passende Organisationszugehörigkeit erhält dieselbe 403-Antwort. Der Link verweist lediglich innerhalb des berechtigten Personenkreises auf ein Dokument.
Auch Download, ZIP-Download, PDF-Vorschau und Freigabelinks nehmen einen Dokumentschlüssel entgegen. Für jeden Pfad wird der Schlüssel gegen das aufgelöste Kundenpräfix geprüft und auf Bestandteile untersucht, mit denen sich der Kundenordner verlassen ließe (NFA-6). Freigabelinks bilden keine Ausnahme: Sie enthalten keine Anmeldeinformationen; ein Empfänger ohne Rolle und passende Organisationszugehörigkeit erhält dieselbe 403-Antwort.
+4 -18
View File
@@ -26,28 +26,14 @@ Die sieben Dokumententypen wurden in der Feature-Beschreibung festgelegt und im
\subsection{Feste Kodierung statt Konfiguration}
Im Approval-Termin stellte \emph{Timo Walter} die Frage, ob die Kategorien konfigurierbar sein sollen. Die Entscheidung fiel auf eine feste Kodierung in Houston.
Der Typenkatalog ist fachlich stabil und ändert sich allenfalls im Rhythmus von Jahren. Konfigurierbarkeit würde Verwaltungsoberfläche, Speicherformat und Migrationsstrategie erfordern — ein unverhältnismäßiger Aufwand.
Hinzu kommt, dass jeder Typ ein Icon und eine Übersetzung benötigt, die bei einem frei konfigurierbaren Katalog ebenfalls hinterlegbar sein müssten. Die feste Kodierung stellt sicher, dass Ordnername, Anzeigetext und Icon gemeinsam gepflegt werden.
Der Preis: Das Hinzufügen eines Typs erfordert eine Codeänderung und ein Release. Angesichts der erwarteten Änderungshäufigkeit ist das vertretbar.
Im Approval-Termin stellte \emph{Timo Walter} die Frage, ob die Kategorien konfigurierbar sein sollen. Die Entscheidung fiel auf eine feste Kodierung in Houston. Der Typenkatalog ist fachlich stabil und ändert sich allenfalls im Rhythmus von Jahren; Konfigurierbarkeit würde Verwaltungsoberfläche, Speicherformat und Migrationsstrategie erfordern. Da jeder Typ zudem ein Icon und eine Übersetzung benötigt, stellt die feste Kodierung sicher, dass Ordnername, Anzeigetext und Icon gemeinsam gepflegt werden. Der Preis — eine Codeänderung und ein Release je neuem Typ — ist bei der erwarteten Änderungshäufigkeit vertretbar.
\subsection{Verhalten bei unbekannten Ordnern}
Aus der festen Kodierung ergibt sich die Frage, wie mit Unterordnern umzugehen ist, die nicht im Katalog stehen — etwa einem in Filestash von Hand angelegten Ordner \texttt{Sonstiges}.
Unterordner, die nicht im Katalog stehen — etwa ein in Filestash von Hand angelegtes \texttt{Sonstiges} — werden angezeigt: Die Typableitung liefert keinen Treffer, das Dokument gilt als typlos und erhält den Anzeigetext \emph{Sonstige Dokumente} sowie ein neutrales Standard-Icon. Ausblenden wurde verworfen, weil es stilles Fehlverhalten erzeugen würde. Dieselbe Behandlung greift für Dokumente unmittelbar im Kundenordner. Praktisch bleibt der Fall die Ausnahme, da Houston die Ordnerstruktur selbst anlegt (siehe Abschnitt~\ref{sec:folder-management}) und dabei nur Katalog-Ordner erzeugt.
Dokumente in solchen Ordnern werden angezeigt: Die Typableitung liefert keinen Treffer, das Dokument gilt als typlos und erhält den Anzeigetext \emph{Sonstige Dokumente} sowie ein neutrales Standard-Icon. Ausblenden wurde verworfen, weil es stilles Fehlverhalten erzeugen würde: Ein Dokument wäre unsichtbar, ohne dass der Betreuer dies bemerkt. Dieselbe Behandlung greift für Dokumente, die unmittelbar im Kundenordner liegen.
Praktisch bleibt der Fall die Ausnahme, da Houston die Ordnerstruktur selbst anlegt und pflegt (siehe Abschnitt~\ref{sec:folder-management}) und dabei ausschließlich Ordner des Katalogs erzeugt.
Zu unterscheiden ist dieser Fall vom Umgang mit unbekannten Ordnern auf der \emph{obersten} Ebene, wo ein fehlendes Marker-Metadatum zum vollständigen Ausschluss führt (siehe Abschnitt~\ref{sec:s3-layout}). Der Unterschied ist beabsichtigt: Auf oberster Ebene entscheidet die Struktur über die Mandantentrennung; innerhalb eines Kundenordners ist die Zugehörigkeit bereits geklärt.
Zu unterscheiden ist dieser Fall vom Umgang mit unbekannten Ordnern auf der \emph{obersten} Ebene, wo ein fehlendes Marker-Metadatum zum vollständigen Ausschluss führt (siehe Abschnitt~\ref{sec:s3-layout}). Der Unterschied ist beabsichtigt: Auf oberster Ebene entscheidet die Struktur über die Mandantentrennung; innerhalb eines Kundenordners ist die Zugehörigkeit bereits geklärt.
Zu unterscheiden ist dies vom Umgang mit unbekannten Ordnern auf der \emph{obersten} Ebene, wo ein fehlendes Marker-Metadatum zum vollständigen Ausschluss führt (siehe Abschnitt~\ref{sec:s3-layout}): Dort entscheidet die Struktur über die Mandantentrennung, während innerhalb eines Kundenordners die Zugehörigkeit bereits geklärt ist.
\subsection{Übersetzung der Anzeigenamen}
Die Ordnernamen im Speicher dienen zwei Zielgruppen: Für die Kundenbetreuer in Filestash müssen sie lesbar und eindeutig sein, für den Kunden in Houston sollen sie sich in die Oberfläche einfügen.
Der Ordnername wird nicht unverändert angezeigt, sondern über eine Ressourcendatei auf einen Anzeigetext abgebildet. Dies entspricht dem in Houston etablierten Lokalisierungsmuster und erlaubt Änderungen am Anzeigetext, ohne die Speicherstruktur anzufassen — eine Umbenennung dort würde das Umkopieren sämtlicher betroffenen Objekte erfordern.
Die Ordnernamen müssen für die Kundenbetreuer in Filestash lesbar und eindeutig sein, für den Kunden in Houston aber in die Oberfläche passen. Der Ordnername wird daher über eine Ressourcendatei auf einen Anzeigetext abgebildet — das etablierte Lokalisierungsmuster. So lässt sich der Anzeigetext ändern, ohne die Speicherstruktur anzufassen, deren Umbenennung das Umkopieren sämtlicher betroffenen Objekte erfordern würde.
+9 -25
View File
@@ -3,27 +3,17 @@
\subsection{Die zugrunde liegende Idee}
Alle in Abschnitt~\ref{sec:lookup-research} betrachteten Ansätze hinterlegen die Zuordnung \emph{zusätzlich} irgendwo — in Cache, Token, Efecte oder einer Zuordnungsdatei. Jeder führt eine zweite, konsistent zu haltende Datenhaltung ein.
Alle in Abschnitt~\ref{sec:lookup-research} betrachteten Ansätze hinterlegen die Zuordnung \emph{zusätzlich} irgendwo und führen so eine zweite, konsistent zu haltende Datenhaltung ein. Die gewählte Lösung dreht die Fragestellung um: Lässt sich der Ordnername deterministisch aus dem Firmennamen ableiten und steht dieser im Token, bestimmt Houston ihn ohne Nachschlagevorgang — aus der Suche wird ein direkter Zugriff.
Die gewählte Lösung dreht die Fragestellung um: Lässt sich der Ordnername deterministisch aus dem Firmennamen ableiten und steht dieser im Token, kann Houston den Ordnernamen ohne Nachschlagevorgang bestimmen. Aus der Suche wird ein direkter Zugriff.
Voraussetzung ist, dass die Ordner tatsächlich so heißen, wie Houston es erwartet. \textbf{Houston wird zur führenden Instanz für die Namensgebung der Kundenordner.} Weicht ein Ordner ab, wird er umbenannt.
Diese Festlegung ist vertretbar, weil Houston die Ordnerstruktur ohnehin selbst anlegt (FA-13). Die Kundenbetreuer verlieren nichts: Der Ordner heißt weiterhin nach dem Kunden, nur normalisiert.
Voraussetzung ist, dass die Ordner so heißen, wie Houston es erwartet. \textbf{Houston wird zur führenden Instanz für die Namensgebung der Kundenordner}; weicht ein Ordner ab, wird er umbenannt. Das ist vertretbar, weil Houston die Ordnerstruktur ohnehin selbst anlegt (FA-13), und die Kundenbetreuer verlieren nichts: Der Ordner heißt weiterhin nach dem Kunden, nur normalisiert.
\subsection{Ableitung des Ordnernamens}
Der Firmenname aus dem Token kann nicht unverändert als Ordnername dienen — er kann problematische Zeichen, führende Leerzeichen oder beliebige Länge aufweisen. Er wird durch eine Normalisierungsfunktion geführt, im Folgenden \emph{Slug} genannt.
Die Normalisierung muss \textbf{deterministisch} sein — derselbe Firmenname muss stets denselben Ordnernamen ergeben — und das Ergebnis \textbf{lesbar} halten, weil der Ordner in Filestash von Menschen bedient wird. Umlaute werden bewusst \emph{nicht} ersetzt: „Müller GmbH" erhält den Ordner \texttt{Müller GmbH}, nicht \texttt{Mueller GmbH}, weil der Betreuer die Firma sonst in der alphabetischen Liste an unerwarteter Stelle suchen müsste. Die Zulässigkeit solcher Zeichen in Objektschlüsseln wurde anhand der Herstellerdokumentation geprüft \autocite{aws-s3-naming, ibm-s3-naming}.
Der Firmenname aus dem Token kann problematische Zeichen, führende Leerzeichen oder beliebige Länge aufweisen und wird daher durch eine Normalisierungsfunktion geführt, im Folgenden \emph{Slug} genannt. Sie muss \textbf{deterministisch} und \textbf{lesbar} sein, da der Ordner in Filestash von Menschen bedient wird. Umlaute werden bewusst \emph{nicht} ersetzt: „Müller GmbH" erhält den Ordner \texttt{Müller GmbH}, nicht \texttt{Mueller GmbH}, sonst stünde die Firma in der alphabetischen Liste an unerwarteter Stelle. Die Zulässigkeit solcher Zeichen in Objektschlüsseln wurde anhand der Herstellerdokumentation geprüft \autocite{aws-s3-naming, ibm-s3-naming}.
\subsection{Umgang mit Namenskollisionen}
Firmennamen sind nicht garantiert eindeutig. Efecte lässt zwei Organisationen mit identischem Namen zu, und beide würden auf denselben Ordnernamen treffen. Da eine Verwechslung bedeuten würde, dass ein Kunde fremde Dokumente sieht, muss der Fall abgedeckt sein.
Die erste Organisation, die den Namen beansprucht, erhält ihn. Jede weitere erhält einen Ordner mit angehängter Organisations-ID, etwa \texttt{Beispielkunde GmbH (77)} — eindeutig, lesbar und alphabetisch neben dem gleichnamigen Ordner.
Sicherheitsregel: Ein Zielname wird nur beansprucht, wenn er frei ist oder ausweislich seines Markers der eigenen Organisation gehört. Ein fremder Kundenordner wird unter keinen Umständen überschrieben. Die Zuordnung entscheidet immer das Metadatum, nie der Name.
Firmennamen sind nicht garantiert eindeutig: Efecte lässt zwei Organisationen mit identischem Namen zu, die auf denselben Ordnernamen träfen — eine Verwechslung würde bedeuten, dass ein Kunde fremde Dokumente sieht. Die erste Organisation, die den Namen beansprucht, erhält ihn; jede weitere erhält einen Ordner mit angehängter Organisations-ID, etwa \texttt{Beispielkunde GmbH (77)}. Ein Zielname wird nur beansprucht, wenn er frei ist oder ausweislich seines Markers der eigenen Organisation gehört; die Zuordnung entscheidet immer das Metadatum, nie der Name.
\subsection{Der resultierende Ablauf}
@@ -37,21 +27,15 @@ Aus diesen Überlegungen ergibt sich ein dreistufiges Verfahren (Abbildung~\ref{
\end{figure}
\begin{enumerate}
\item \textbf{Direktzugriff.} Houston bildet den erwarteten Ordnernamen aus dem Firmennamen und ruft die Metadaten des Markers ab. Stimmt die Organisations-ID, ist die Auflösung mit einem Aufruf abgeschlossen. Dies ist der Regelfall.
\item \textbf{Kollisionsprüfung.} Fehlt der Marker oder trägt er eine fremde ID, wird der Zugriff mit dem um die Organisations-ID ergänzten Namen wiederholt — zwei Aufrufe für den Kollisionsfall.
\item \textbf{Rückfallebene.} Erst dann kommt das lineare Verfahren zum Einsatz. Wird ein Ordner mit passender ID gefunden, wird er auf den kanonischen Namen umbenannt. Wird keiner gefunden, wird die vollständige Struktur angelegt.
\item \textbf{Direktzugriff.} Houston bildet den erwarteten Ordnernamen aus dem Firmennamen und ruft die Metadaten des Markers ab. Stimmt die Organisations-ID, ist die Auflösung mit einem Aufruf abgeschlossen — der Regelfall.
\item \textbf{Kollisionsprüfung.} Fehlt der Marker oder trägt er eine fremde ID, wird der Zugriff mit dem um die Organisations-ID ergänzten Namen wiederholt — zwei Aufrufe.
\item \textbf{Rückfallebene.} Erst dann kommt das lineare Verfahren zum Einsatz. Ein Ordner mit passender ID wird auf den kanonischen Namen umbenannt; wird keiner gefunden, wird die vollständige Struktur angelegt.
\end{enumerate}
\subsection{Selbstheilung}
Die entscheidende Eigenschaft liegt im dritten Schritt: Die Rückfallebene beseitigt nicht nur den Fehlschlag, sondern auch dessen Ursache. Nach der Umbenennung trägt der Ordner den erwarteten Namen, und der nächste Zugriff läuft direkt.
Der teure Pfad wird pro Kunde höchstens einmal durchlaufen. Bestehende Ordner migrieren sich beim ersten Zugriff von selbst — eine gesonderte Migration entfällt.
Das Verfahren erfordert keine zusätzliche Datenhaltung: keinen Cache, kein Feld in einem Fremdsystem, keine Zuordnungsdatei. Der Zustand liegt vollständig im Speicher, und die Anwendung kann aus jedem Ausgangszustand den Sollzustand herstellen.
Die Rückfallebene beseitigt nicht nur den Fehlschlag, sondern dessen Ursache: Nach der Umbenennung trägt der Ordner den erwarteten Namen, und der nächste Zugriff läuft direkt. Der teure Pfad wird pro Kunde höchstens einmal durchlaufen, Bestandsordner migrieren sich beim ersten Zugriff von selbst. Das Verfahren erfordert keine zusätzliche Datenhaltung; der Zustand liegt vollständig im Speicher.
\subsection{Bewusst offen gelassener Bereich}
Die Rückfallebene ist nicht nur lesend: Sie benennt Ordner um und legt sie an — im Rahmen einer gewöhnlichen Seitenanfrage. Da Houston in mehreren Instanzen läuft, können zwei Anfragen gleichzeitig denselben Ordner betreffen.
Dieser Umstand wurde analysiert und als eigenes Backlog Item vom laufenden Pull Request abgegrenzt. Abschnitt~\ref{sec:race-conditions} behandelt die Szenarien und erwogenen Gegenmaßnahmen.
Die Rückfallebene benennt Ordner um und legt sie an — im Rahmen einer gewöhnlichen Seitenanfrage. Da Houston in mehreren Instanzen läuft, können zwei Anfragen gleichzeitig denselben Ordner betreffen. Dieser Umstand wurde als eigenes Backlog Item vom laufenden Pull Request abgegrenzt; Abschnitt~\ref{sec:race-conditions} behandelt die Szenarien und Gegenmaßnahmen.
+9 -33
View File
@@ -3,46 +3,22 @@
\subsection{Entstehung}
Der Document Explorer war zum Zeitpunkt seines Merges am 31.~Juli 2026 funktionsfähig, enthielt aber eine im Code-Review angesprochene Schwäche. Um den Kundenordner zu einer Organisations-ID zu finden, listete Houston sämtliche Ordner auf oberster Ebene auf, rief für jeden die Metadaten ab und verglich die \texttt{efecte-org-id} mit der des Benutzers.
Der Document Explorer war zu seinem Merge am 31.~Juli 2026 funktionsfähig, enthielt aber eine im Code-Review angesprochene Schwäche: Um den Kundenordner zu einer Organisations-ID zu finden, listete Houston sämtliche Ordner auf oberster Ebene auf, rief für jeden die Metadaten ab und verglich die \texttt{efecte-org-id} mit der des Benutzers. Ursache ist, dass S3 keine Suche nach benutzerdefinierten Metadaten bietet: \texttt{ListObjectsV2} liefert Schlüssel, Größe und Änderungszeitpunkt, aber keine Metadaten \autocite{aws-listobjectsv2}, sodass jeder Kandidat einen eigenen Aufruf erfordert.
Die Ursache: S3 bietet keine Suche nach benutzerdefinierten Metadaten. \texttt{ListObjectsV2} liefert Schlüssel, Größe und Änderungszeitpunkt, aber keine benutzerdefinierten Metadaten \autocite{aws-listobjectsv2}. Für jeden Kandidaten ist ein eigener Aufruf nötig.
Der Aufwand wächst linear mit der Kundenzahl — bei \emph{jedem} Seitenaufruf. Bei einigen hundert Kunden bedeutet das einige hundert Netzwerkaufrufe, bevor das erste Dokument geladen wird. Das Problem ist nicht akut, aber strukturell.
Am 28.~Juli entstand daraus ein eigenes Backlog Item, bewusst als \emph{Recherche}-Item. Das Akzeptanzkriterium lautete nicht „das Problem ist behoben", sondern „es ist sich für einen Lösungsansatz entschieden worden". So wird der Rechercheaufwand als eigenständige Leistung sichtbar.
Der Aufwand wächst linear mit der Kundenzahl — bei \emph{jedem} Seitenaufruf, also einige hundert Netzwerkaufrufe bei einigen hundert Kunden, bevor das erste Dokument geladen wird. Das Problem ist nicht akut, aber strukturell. Am 28.~Juli entstand daraus ein eigenes Backlog Item, bewusst als \emph{Recherche}-Item mit dem Akzeptanzkriterium „es ist sich für einen Lösungsansatz entschieden worden", um den Rechercheaufwand als eigenständige Leistung sichtbar zu machen.
\subsection{Untersuchte Lösungsansätze}
Die sechs im Folgenden dargestellten Ansätze habe ich im Rahmen des Recherche-Items selbst erarbeitet und gegeneinander abgewogen; \emph{Timo Walter} und \emph{Bianco Veigel} dienten als Gesprächspartner für die Rückversicherung und prüften das Ergebnis im Review. Wo Angaben zur Speicherinfrastruktur nötig waren, wurden diese bei den zuständigen Ansprechpartnern eingeholt. Tabelle~\ref{tab:lookup-tradeoffs} im Anhang fasst die Bewertung zusammen.
Die sechs folgenden Ansätze habe ich im Rahmen des Recherche-Items selbst erarbeitet und abgewogen; \emph{Timo Walter} und \emph{Bianco Veigel} dienten als Gesprächspartner und prüften das Ergebnis im Review. Tabelle~\ref{tab:lookup-tradeoffs} im Anhang fasst die Bewertung zusammen.
\subsubsection{In-Memory-Cache}
\textbf{In-Memory-Cache.} Das Auflösungsergebnis zwischenspeichern macht Folgeaufrufe kostenlos. Da Houston in mehreren Instanzen läuft und der Cache nach jedem Neustart leer ist, bleibt der lineare Aufwand jedoch bestehen, er wird nur seltener bezahlt.
Der naheliegendste Ansatz: das Auflösungsergebnis im Arbeitsspeicher zwischenspeichern. Der erste Aufruf bleibt teuer, alle folgenden sind kostenlos.
\textbf{Speicherung im Anmeldetoken.} Der Ordnername könnte als Claim abgelegt werden. Der lineare Aufwand bliebe erhalten, und ein Token ist über seine Laufzeit unveränderlich: Nach einer Umbenennung zeigt der Claim bis zur Erneuerung auf einen nicht mehr existierenden Ordner.
Houston läuft jedoch in mehreren Instanzen, sodass jede ihren Cache aufbauen müsste. Nach jedem Neustart ist der Cache leer, und es entsteht ein Ansturm teurer Auflösungen. Der lineare Aufwand bleibt unverändert — er wird lediglich seltener bezahlt.
\textbf{Speicherung als Feld in Efecte.} Der Ordnername könnte an der Organisation in Efecte gepflegt werden. Das löst das Problem technisch, führt aber eine zweite Datenhaltung neben dem Marker-Metadatum ein, die auseinanderlaufen kann, und müsste für jeden Bestandskunden nachgepflegt werden.
\subsubsection{Speicherung im Anmeldetoken}
\textbf{S3 Select.} \texttt{SelectObjectContent} filtert den \emph{Inhalt} eines Objekts serverseitig per SQL-ähnlicher Abfrage \autocite{aws-s3-select}; denkbar wäre eine Zuordnungstabelle als Datei. Die Freischaltung wurde am 7.~August bestätigt (siehe Abschnitt~\ref{sec:infrastructure}), doch S3 Select filtert Inhalte einzelner Objekte, nicht Metadaten mehrerer — die Zuordnungsdatei hätte dasselbe Konsistenzproblem wie das Efecte-Feld ohne dessen Werkzeugunterstützung.
Der Ordnername könnte bei der Anmeldung ermittelt und als Claim im Token abgelegt werden. Der lineare Aufwand bliebe erhalten. Hinzu kommt: Ein Token ist über seine Laufzeit unveränderlich. Wird der Ordner umbenannt, zeigt der Claim auf einen nicht mehr existierenden Ordner, bis das Token erneuert wird.
\textbf{StorageGRID Search Integration.} Der Search Integration Service spiegelt Objektmetadaten in einen Elasticsearch-Index und ermöglicht eine echte Metadatensuche \autocite{storagegrid-search-integration} — fachlich die sauberste Lösung. Die Anfrage ergab am 17.~August, dass die Funktion derzeit nicht angeboten wird; der Ansatz wurde in den Ausblick übernommen (siehe Abschnitt~\ref{sec:outlook}).
\subsubsection{Speicherung als Feld in Efecte}
Der Ordnername könnte als Feld an der Organisation in Efecte gepflegt werden. Das löst das Problem technisch, führt aber eine Abhängigkeit ein: Die Zuordnung läge an zwei Stellen — im Efecte-Feld und im Marker-Metadatum — die auseinanderlaufen können. Zudem müsste das Feld für jeden Bestandskunden nachgepflegt werden.
\subsubsection{S3 Select}
\texttt{SelectObjectContent} filtert den \emph{Inhalt} eines Objekts serverseitig per SQL-ähnlicher Abfrage \autocite{aws-s3-select}. Denkbar wäre eine Zuordnungstabelle als Datei im Bucket, aus der der passende Eintrag gefiltert wird.
Die Freischaltung wurde beantragt und am 7.~August bestätigt (siehe Abschnitt~\ref{sec:infrastructure}). S3 Select filtert jedoch Inhalte einzelner Objekte, nicht Metadaten mehrerer Objekte. Eine Zuordnungsdatei wäre eine zusätzlich zu pflegende Struktur mit demselben Konsistenzproblem wie beim Efecte-Feld, nur ohne dessen Werkzeugunterstützung.
\subsubsection{StorageGRID Search Integration}
Der Search Integration Service spiegelt Objektmetadaten in einen Elasticsearch-Index und ermöglicht eine echte Metadatensuche \autocite{storagegrid-search-integration}. Fachlich die sauberste Lösung, da sie das Problem an der Wurzel behebt, ohne eine zweite Datenhaltung einzuführen. Die Anfrage ergab am 17.~August, dass die Funktion derzeit nicht angeboten wird; der Ansatz wurde in den Ausblick übernommen (siehe Abschnitt~\ref{sec:outlook}).
\subsubsection{Organisations-ID im Ordnernamen}
Der einfachste Ansatz: die Organisations-ID zum Bestandteil des Ordnernamens machen — etwa \texttt{42\_Beispielkunde GmbH}. Der Lookup reduzierte sich auf eine Präfixabfrage.
In der Abstimmung mit \emph{Ralf Schulte} wurde deutlich, dass die Kundenbetreuer die Ordner in Filestash nach Kundennamen sortiert vorfinden müssen. Ein vorangestellter Zahlenschlüssel zerstört diese Sortierung. Der Konflikt: Houston autorisiert über die Organisations-ID, die Betreuer arbeiten über den Kundennamen, und der Speicher vermittelt nicht zwischen beiden.
Die entscheidende Beobachtung war, dass die Anforderung eine Sortierung nach Kundennamen verlangt — nicht zwingend, dass der Ordnername \emph{ausschließlich} aus dem Kundennamen besteht. Diese Unterscheidung eröffnete den Weg zur in Abschnitt~\ref{sec:lookup-decision} beschriebenen Lösung.
\textbf{Organisations-ID im Ordnernamen.} Die ID zum Bestandteil des Ordnernamens machen — etwa \texttt{42\_Beispielkunde GmbH} — reduzierte den Lookup auf eine Präfixabfrage. In der Abstimmung mit \emph{Ralf Schulte} wurde deutlich, dass die Kundenbetreuer die Ordner in Filestash nach Kundennamen sortiert vorfinden müssen; ein vorangestellter Zahlenschlüssel zerstört diese Sortierung. Die entscheidende Beobachtung war, dass die Anforderung eine Sortierung nach Kundennamen verlangt — nicht, dass der Ordnername \emph{ausschließlich} aus dem Kundennamen besteht. Das eröffnete den Weg zur in Abschnitt~\ref{sec:lookup-decision} beschriebenen Lösung.
+9 -23
View File
@@ -1,19 +1,17 @@
\section{Ablagekonzept im S3-Speicher}
\label{sec:s3-layout}
Das Ablagekonzept muss zwei Aufgaben erfüllen: die Zuordnung von Dokumenten zu Kunden und die Abbildung des fachlichen Dokumententyps. Beides geschieht ausschließlich über die Struktur im Speicher, ohne eine zusätzliche Datenbank.
Das Ablagekonzept muss die Zuordnung von Dokumenten zu Kunden und die Abbildung des fachlichen Dokumententyps leisten — beides ausschließlich über die Struktur im Speicher, ohne zusätzliche Datenbank.
\subsection{Präfixe statt Ordner}
S3 kennt technisch keine Ordner. Jedes Objekt wird über einen Schlüssel in einem flachen Namensraum adressiert. Die scheinbare Hierarchie entsteht beim Auflisten: \texttt{ListObjectsV2} liefert mit Präfix und Trennzeichen nur die Objekte unterhalb eines Präfixes sowie die gemeinsamen Teilpräfixe der nächsten Ebene \autocite{aws-listobjectsv2}. Ein Schlüssel wie
S3 adressiert jedes Objekt über einen Schlüssel in einem flachen Namensraum; die scheinbare Hierarchie entsteht beim Auflisten über Präfix und Trennzeichen \autocite{aws-listobjectsv2}. Ein Schlüssel wie
\begin{quote}
\texttt{Beispielkunde GmbH/Service-Protokoll/Protokoll-2026-07.pdf}
\end{quote}
erscheint in Filestash als zweistufige Ordnerhierarchie, ist im Speicher aber nur eine Zeichenkette. Ein „Ordner" existiert erst, wenn mindestens ein Objekt mit dem entsprechenden Präfix vorhanden ist; ein leerer Ordner lässt sich nur durch ein Platzhalterobjekt simulieren, dessen Schlüssel auf das Trennzeichen endet.
Abbildung~\ref{fig:s3-layout} zeigt die resultierende Struktur.
erscheint in Filestash als zweistufige Ordnerhierarchie, ist im Speicher aber nur eine Zeichenkette. Ein „Ordner" existiert erst mit einem Objekt unter dem Präfix; ein leerer Ordner lässt sich nur durch ein Platzhalterobjekt simulieren, dessen Schlüssel auf das Trennzeichen endet. Abbildung~\ref{fig:s3-layout} zeigt die Struktur.
\begin{figure}[H]
\centering
@@ -24,36 +22,24 @@ Abbildung~\ref{fig:s3-layout} zeigt die resultierende Struktur.
\subsection{Kundenzuordnung über ein Marker-Objekt}
Auf der obersten Ebene des Buckets liegt für jeden Kunden ein Ordner. Dessen Platzhalterobjekt trägt ein benutzerdefiniertes Metadatum \texttt{efecte-org-id} zur Zuordnung an eine Organisation und wird im Folgenden als \emph{Marker} bezeichnet.
Auf der obersten Ebene liegt für jeden Kunden ein Ordner. Dessen Platzhalterobjekt trägt ein benutzerdefiniertes Metadatum \texttt{efecte-org-id} und wird im Folgenden \emph{Marker} genannt. Er sorgt dafür, dass der Kundenordner auch ohne Dokumente existiert, und trägt die Organisationszugehörigkeit an genau einer Stelle.
Er sorgt dafür, dass der Kundenordner auch ohne Dokumente existiert, und trägt die Organisationszugehörigkeit an genau einer Stelle.
Die Organisations-ID wird als Metadatum statt als Bestandteil des Ordnernamens geführt (siehe Abschnitt~\ref{sec:feature-analysis}). Die Ordner werden von Kundenbetreuern über Filestash gepflegt; ein Name wie \texttt{42} wäre dort schwer handhabbar. Der lesbare Firmenname bleibt daher der Ordnername, die technische Zuordnung wandert in die Metadaten.
Genau diese Entscheidung erzeugt das zentrale technische Problem des Projekts (Abschnitt~\ref{sec:lookup-research}): Houston kennt die Organisations-ID, muss daraus den Ordnernamen ermitteln — und S3 bietet keine Suche nach Metadaten.
Die Organisations-ID wird als Metadatum statt als Bestandteil des Ordnernamens geführt (siehe Abschnitt~\ref{sec:feature-analysis}): Die Ordner werden von Kundenbetreuern über Filestash gepflegt, ein Name wie \texttt{42} wäre dort schwer handhabbar. Genau diese Entscheidung erzeugt das zentrale technische Problem des Projekts (Abschnitt~\ref{sec:lookup-research}): Houston kennt die Organisations-ID, muss daraus den Ordnernamen ermitteln — und S3 bietet keine Suche nach Metadaten.
\subsection{Typisierung über Unterordner}
Innerhalb des Kundenordners liegt für jeden der sieben Dokumententypen ein Unterordner. Der Typ ergibt sich aus dem Unterordner; direkt im Kundenordner liegende Dokumente gelten als untypisiert.
Innerhalb des Kundenordners liegt für jeden der sieben Dokumententypen ein Unterordner; der Typ ergibt sich aus dem Unterordner, direkt im Kundenordner liegende Dokumente gelten als untypisiert. Die Alternative — den Typ als Metadatum an jeder Datei zu hinterlegen — wurde verworfen: Ein Metadatum müsste bei jedem Upload manuell gesetzt werden, wofür Filestash keine komfortable Unterstützung bietet, während das Ablegen in einem Ordner die natürliche Bedienhandlung ist. Zudem ist der Typ als Präfixbestandteil unmittelbar aus dem Schlüssel ablesbar und serverseitig filterbar, während ein Metadatum für jedes Objekt einzeln abgerufen werden müsste, da \texttt{ListObjectsV2} es nicht mitliefert — bei $n$ Dokumenten also $n$ zusätzliche Aufrufe.
Die Alternative — den Typ als Metadatum an jeder Datei zu hinterlegen — wurde verglichen:
\begin{itemize}
\item \textbf{Pflegeaufwand:} Ein Metadatum müsste bei jedem Upload manuell gesetzt werden; Filestash bietet hierfür keine komfortable Unterstützung. Das Ablegen in einem Ordner ist die natürliche Bedienhandlung.
\item \textbf{Abfragbarkeit:} Der Typ ist als Präfixbestandteil unmittelbar aus dem Schlüssel ablesbar. Ein Metadatum müsste dagegen für jedes Objekt einzeln abgerufen werden, da \texttt{ListObjectsV2} benutzerdefinierte Metadaten nicht mitliefert — bei $n$ Dokumenten also $n$ zusätzliche Aufrufe.
\item \textbf{Filterung:} Eine Filterung nach Typ reduziert sich auf eine Präfixabfrage und ist damit serverseitig umsetzbar.
\end{itemize}
Dem stehen zwei Nachteile gegenüber: Ein Dokument kann nur einen Typ haben, und die Ordner müssen existieren — die automatische Anlage wird damit zu einer eigenen Anforderung (FA-13). Beide Einschränkungen wurden bewusst in Kauf genommen.
Dem stehen zwei bewusst in Kauf genommene Nachteile gegenüber: Ein Dokument kann nur einen Typ haben, und die Ordner müssen existieren — die automatische Anlage wird damit zu einer eigenen Anforderung (FA-13).
\subsection{Sichtbarkeitsregeln}
Für die Darstellung gelten drei Regeln:
\begin{enumerate}
\item \textbf{Ordner werden nicht als Einträge angezeigt.} Die Liste zeigt ausschließlich Dokumente; die Ordnerstruktur wird über Typ-Icons und Filter abgebildet. Der Benutzer sieht eine flache Liste aller seiner Dokumente.
\item \textbf{Ordner werden nicht als Einträge angezeigt.} Die Liste zeigt ausschließlich Dokumente; die Ordnerstruktur wird über Typ-Icons und Filter abgebildet.
\item \textbf{Leere Typordner erscheinen nicht.}
\item \textbf{Ordner ohne gültiges Marker-Metadatum werden ignoriert.} Fehlt die Organisations-ID, bleibt der Ordner unsichtbar. Der Fall wird protokolliert, führt aber nicht zu einem Fehler.
\item \textbf{Ordner ohne gültiges Marker-Metadatum werden ignoriert.} Fehlt die Organisations-ID, bleibt der Ordner unsichtbar; der Fall wird protokolliert, führt aber nicht zu einem Fehler.
\end{enumerate}
Die dritte Regel ist eine Sicherheitsmaßnahme: Ein fehlendes Metadatum führt zum Ausschluss, nicht zu einer Vermutung.
+7 -15
View File
@@ -3,19 +3,13 @@
\subsection{Abstimmung der Typfilterung über einen Clickdummy}
Das Oberflächenkonzept des Dokumentenbereichs stammt bis auf einen Punkt aus der eigenen Ausarbeitung: Für die Typfilterung existierte kein Vorbild in Houston, und da \emph{Hanna Ebner} die führende Entscheidungsinstanz für die Oberfläche der Anwendung ist, wurde das Aussehen dieser Filterleiste mit ihr abgestimmt. Als Referenz setzte sie ihren Vorschlag am 22.~Juli 2026 als lauffähigen Clickdummy in einem eigenen Branch des Houston-Repositories um und verlinkte ihn am Feature.
Der Clickdummy verwendet die bestehenden Komponenten und Stile der Anwendung, wodurch Fragen zu Abständen, Schriftgrößen oder Farben durch das vorhandene Stylesheet beantwortet werden. Interaktionen wie das Ein- und Ausklappen von Filtern lassen sich ausprobieren statt aus einer statischen Abbildung erschlossen werden.
Er ist damit eine gestalterische Vorgabe für ein einzelnes Bedienelement, keine Zuarbeit zur Umsetzung: Die Implementierung der Filterleiste — Markup, Zustandshaltung, Abfrageparameter und serverseitige Auswertung (Abschnitt~\ref{sec:filter-pagination}) — lag wie die des übrigen Dokumentenbereichs vollständig in meiner Hand.
Das Oberflächenkonzept stammt bis auf einen Punkt aus der eigenen Ausarbeitung: Für die Typfilterung existierte kein Vorbild in Houston, und da \emph{Hanna Ebner} die führende Entscheidungsinstanz für die Oberfläche ist, wurde die Filterleiste mit ihr abgestimmt. Als Referenz setzte sie ihren Vorschlag am 22.~Juli 2026 als lauffähigen Clickdummy in einem eigenen Branch des Houston-Repositories um und verlinkte ihn am Feature. Er ist eine gestalterische Vorgabe für ein einzelnes Bedienelement, keine Zuarbeit zur Umsetzung: Die Implementierung der Filterleiste — Markup, Zustandshaltung, Abfrageparameter und serverseitige Auswertung (Abschnitt~\ref{sec:filter-pagination}) — lag wie die des übrigen Dokumentenbereichs vollständig in meiner Hand.
\subsection{Flache Liste statt navigierbarer Hierarchie}
Der Dokumentenbereich stellt trotz seiner Bezeichnung als „Document Explorer" keine navigierbare Ordnerhierarchie dar. Der Benutzer sieht eine flache Liste aller Dokumente; die Typzugehörigkeit wird über Icons und Filter ausgedrückt.
Der Dokumentenbereich stellt trotz der Bezeichnung „Document Explorer" keine navigierbare Ordnerhierarchie dar; der Benutzer sieht eine flache Liste aller Dokumente, die Typzugehörigkeit wird über Icons und Filter ausgedrückt. Bei einer Hierarchie müsste ein Kunde die Kategorie kennen und sich dorthin durchklicken, während die flache Liste unmittelbares Suchen und Filtern erlaubt. Bei nur zwei Ebenen mit sieben festen Kategorien stünde der Navigationsaufwand in keinem Verhältnis zum Nutzen.
Ein Kunde sucht in der Regel ein bestimmtes Dokument. Bei einer Hierarchie müsste er zunächst die Kategorie kennen und sich dorthin durchklicken. Die flache Liste erlaubt unmittelbares Suchen und Filtern. Da die Hierarchie nur zwei Ebenen mit sieben festen Kategorien umfasst, stünde der Navigationsaufwand in keinem Verhältnis zum Nutzen.
Die ursprüngliche Feature-Beschreibung sah Dokumentkacheln vor. Die Darstellung wurde auf Zeilen umgestellt — eine Entscheidung von \emph{Hanna Ebner}, die als Entscheidungsinstanz für die Oberfläche meine abweichende Einschätzung überwog. Sie ist im Ergebnis die tragfähigere: Eine Zeile bietet Platz für Icon, Name, Auswahlbox und Aktionsschaltflächen, fügt sich in die Tabellendarstellung der übrigen Houston-Seiten ein (NFA-4) und lässt sich um Spalten erweitern, ohne den Aufbau zu verändern.
Die ursprüngliche Feature-Beschreibung sah Dokumentkacheln vor. Die Darstellung wurde auf Zeilen umgestellt — eine Entscheidung von \emph{Hanna Ebner}, die meine abweichende Einschätzung überwog und sich als tragfähiger erwies: Eine Zeile bietet Platz für Icon, Name, Auswahlbox und Aktionsschaltflächen, fügt sich in die Tabellendarstellung der übrigen Houston-Seiten ein (NFA-4) und lässt sich um Spalten erweitern, ohne den Aufbau zu verändern.
\subsection{Aufbau der Seite}
@@ -23,8 +17,8 @@ Die Seite gliedert sich von oben nach unten in vier Bereiche (Abbildung~\ref{fig
\begin{enumerate}
\item Eine \textbf{Suchleiste} am oberen Rand, über die nach dem Dokumentnamen gesucht wird.
\item Darunter eine Reihe von \textbf{Filterelementen}, je eines pro Dokumententyp, mit denen sich Typen ein- und ausblenden lassen.
\item Die \textbf{Dokumentenliste} als Tabelle. Jede Zeile enthält das Typ-Icon, den Dokumentnamen sowie die Aktionen Herunterladen, Teilen und — bei PDF-Dateien — Vorschau. Eine Auswahlbox am Zeilenanfang dient der Mehrfachauswahl für den ZIP-Download.
\item Darunter \textbf{Filterelemente}, je eines pro Dokumententyp, mit denen sich Typen ein- und ausblenden lassen.
\item Die \textbf{Dokumentenliste} als Tabelle. Jede Zeile enthält Typ-Icon, Dokumentnamen sowie die Aktionen Herunterladen, Teilen und — bei PDF-Dateien — Vorschau. Eine Auswahlbox am Zeilenanfang dient der Mehrfachauswahl für den ZIP-Download.
\item Am unteren Rand die \textbf{Blätterelemente} zum Seitenwechsel sowie die Auswahl der Seitengröße.
\end{enumerate}
@@ -33,8 +27,6 @@ Suche und Typfilter wirken zusammen und schränken die Liste gemeinsam ein
\subsection{Konsistenz zur bestehenden Anwendung}
Eine durchgängige Vorgabe war, dass sich der Dokumentenbereich wie die übrigen Houston-Seiten bedienen lässt (NFA-4).
Eine durchgängige Vorgabe war, dass sich der Dokumentenbereich wie die übrigen Houston-Seiten bedienen lässt (NFA-4). Wie genau das zu verstehen ist, zeigte sich erst im Abnahmetest: Die Suchleiste blendete nach einer Eingabe eine Schaltfläche zum Leeren ein — eine Funktion, die es auf den übrigen Seiten nicht gibt. Der Unterschied wurde als Fehler gemeldet (siehe Abschnitt~\ref{sec:acceptance-testing}) und verdeutlicht, dass eine Konsistenzanforderung am Vergleich mit dem Bestand geprüft werden muss.
Wie genau diese Vorgabe zu verstehen ist, zeigte sich erst im Abnahmetest: Die Suchleiste blendete nach einer Eingabe eine Schaltfläche zum Leeren ein — eine sinnvolle Funktion, die es auf den übrigen Seiten nicht gibt. Der Unterschied wurde als Fehler gemeldet (siehe Abschnitt~\ref{sec:acceptance-testing}). Das Beispiel verdeutlicht, dass eine Konsistenzanforderung am Vergleich mit dem Bestand geprüft werden muss.
Ein Freigabelink, der auf ein bestimmtes Dokument verweist, muss auch funktionieren, wenn dieses nicht auf der ersten Seite liegt. Der Link setzt daher beim Weiterleiten die passenden Abfrageparameter, sodass die richtige Seite geladen und an die entsprechende Stelle gesprungen wird (Abbildung~\ref{fig:shot-share-target} im Anhang).
Ein Freigabelink auf ein bestimmtes Dokument muss auch funktionieren, wenn dieses nicht auf der ersten Seite liegt. Der Link setzt daher beim Weiterleiten die passenden Abfrageparameter, sodass die richtige Seite geladen und an die entsprechende Stelle gesprungen wird (Abbildung~\ref{fig:shot-share-target} im Anhang).