\section{Architektur des Dokumentenmoduls} \label{sec:architecture} \subsection{Schichtung} Das Dokumentenmodul folgt der in Houston etablierten Schichtung (Abbildung~\ref{fig:module-components}). \begin{figure}[H] \centering \includegraphics[width=0.95\textwidth]{figures/diagrams/module-components.pdf} \caption{Komponenten des Dokumentenmoduls} \label{fig:module-components} \end{figure} Die oberste Schicht bilden drei Razor Pages: \texttt{Documents} für Liste, Suche, Filter und Blätterelemente, \texttt{Document/Download} für Downloads (einzeln und als ZIP) und \texttt{Document/Share} für Freigabelinks. Darunter liegt der \texttt{DocumentsService} als fachliche Schicht mit den Regeln des Ablagekonzepts (Kundenordner-Auflösung, Typableitung, Ausblendung technischer Einträge). Der \texttt{S3DocumentsClient} kapselt den Speicherzugriff und ist die einzige Stelle, an der \texttt{IAmazonS3} unmittelbar verwendet wird. \subsection{Eigene Typen statt Zeichenketten} \label{sec:newtype} Anfangs wurden Dokumentschlüssel als Zeichenketten durch die Schichten gereicht. Im Review des Downloads führte das zu wiederholten Rückfragen zur Pfadvalidierung, weil einer Zeichenkette nicht anzusehen ist, ob sie bereits geprüft wurde. Als Ausweg verpackte ich die Pfade nach dem \emph{Newtype-Pattern} in eigene \texttt{readonly record struct}-Typen \autocite{rust-newtype}, ergänzt um „parse, don’t validate“ \autocite{king-parse}: Wer einen \texttt{DocumentKey} entgegennimmt, muss die Gültigkeit nicht erneut prüfen. So entstanden \texttt{DocumentKey} für den vollständigen Pfad einschließlich Kundenordner (Listing~\ref{lst:document-key}) und \texttt{DocumentRelativePath} für den Anteil darunter, beide nur über eine prüfende Fabrikmethode erzeugbar; eine vergessene Prüfung führt so zu einem Übersetzungsfehler statt zu einer Sicherheitslücke. Nach demselben Muster entstanden \texttt{DocumentType}, \texttt{DocumentName}, \texttt{DocumentId} und \texttt{OrgSlug}. Zeichenketten werden einmal am Rand in diese Typen geparst; die weitere Verarbeitung arbeitet nur noch auf Typen. Der zugehörige Pull Request durchlief 23 Iterationen und bestand zu einem erheblichen Teil aus diesem Refactoring, das sich auszahlte, weil ZIP-Download, PDF-Vorschau und Freigabelinks dieselben Typen wiederverwenden konnten. \subsection{Zentrale Autorisierung} Die erste Fassung des Document Explorers prüfte die Berechtigung im PageModel. Im Review wies \emph{Hanna Ebner} darauf hin, dass die Autorisierung in Houston zentral in der Anwendungskonfiguration erfolgt und eine zusätzliche Prüfung an der Seite überflüssig ist. Eine seitenspezifische Prüfung ist zudem leicht zu übersehen, wenn weitere Seiten hinzukommen — genau das wäre bei \texttt{Download} und \texttt{Share} passiert. Die zentrale Registrierung stellt sicher, dass alle Routen derselben Richtlinie unterliegen. \subsection{Gestapelte Pull Requests} Die Pull Requests wurden verkettet: Der erste ging gegen den Hauptbranch, jeder darauf aufbauende gegen den Branch seines Vorgängers. So enthält jeder Pull Request genau die Änderungen seines Backlog Items, was die Reviewbarkeit erhöht. Der Preis zeigte sich beim Zusammenführen: Sobald ein Vorgänger übernommen war, musste der Nachfolger umgestellt werden, was in Azure DevOps die bereits abgegebenen Freigaben zurücksetzt. Bei der vorliegenden Zahl aufeinander aufbauender Items überwog der Gewinn an Reviewbarkeit diesen Aufwand deutlich.