initial scaffold: structure, build setup, chapter stubs, diagrams

This commit is contained in:
2026-08-25 19:04:44 +02:00
parent ea69e2736e
commit 34f1863882
69 changed files with 1042 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
<config>
<output_directory>out</output_directory>
<input_directory>out</input_directory>
</config>
+3
View File
@@ -0,0 +1,3 @@
use nix
export VIMTEX_OUTPUT_DIRECTORY="out"
+4
View File
@@ -0,0 +1,4 @@
out
latexout
latex.out
.direnv
+4
View File
@@ -0,0 +1,4 @@
$pdf_mode = 4; # lualatex
$bibtex_use = 2; # biber
$out_dir = out;
$clean_ext .= ' %R.run.xml %R.bbl %R.bcf %R-blx.bib';
+58
View File
@@ -0,0 +1,58 @@
# PidI Thesis LaTeX Template
This template follows the specs:
- A4, margins: left/top **3 cm**, right/bottom **2.5 cm**.
- Page numbers bottom-center.
- Font: **Times Newer Roman 12 pt** (`times` class option, default).
- Line spacing **1.3**, justified text, paragraph spacing **6 pt**, emphasis **bold**.
- `\emph{}` is mapped to bold.
## File name for submission
`<Nachname> PidI 3 <Kurzform des Titels>.pdf`
## Build
```sh
direnv allow # einmalig — setzt Nix-Umgebung auf
latexmk # baut das PDF (LuaLaTeX + Biber, Ausgabe nach out/)
latexmk -c # aufräumen
```
Requires the Nix shell (`shell.nix`) — provides TeX Live, `latexmk`, `mermaid-cli`,
and Times Newer Roman (fonts are installed into `~/.local/share/fonts/` by the shell hook).
`minted` code listings require shell escape; `latexmk` handles this automatically via
`$pdf_mode = 4`.
## Rendering Mermaid diagrams
```sh
# render a single diagram
mmdc -i figures/diagrams/system-context.mmd -o figures/diagrams/system-context.pdf
# render all diagrams at once
for f in figures/diagrams/*.mmd; do
mmdc -i "$f" -o "${f%.mmd}.pdf"
done
```
Render before calling `latexmk` whenever a `.mmd` file changes. The generated `.pdf`
files are gitignored via `out` (only `out/` is ignored, so diagrams in `figures/` are
**not** ignored — commit them).
## Structure
```
main.tex entry point: metadata + \input all chapters
pidi-thesis.cls enforces the complete layout
frontmatter/ usage-of-ai, abstract, acknowledgments
chapters/<part>/*.tex one file per \section
appendix/ appendix.tex bundles tables/diagrams/screenshots/code
figures/code/ code excerpts as real files (no inline code in appendix)
figures/diagrams/ *.mmd source + rendered *.pdf
figures/screenshots/ screenshots
figures/worksimple/ company logos
figures/itc/ ITC logo
references.bib biblatex/biber sources
```
+10
View File
@@ -0,0 +1,10 @@
% TODO: Code-Ausschnitte — je in center-Umgebung mit \captionof{listing}{...} + \inputminted
% Reihenfolge gemäß Kapiteln:
% s3-settings-registration.cs, s3-documents-client.cs,
% documents-page-model.cs, document-view-model.cs, documents-table-body.cshtml,
% document-type-mapping.cs, document-types.resx,
% document-search.cs, pagination-continuation-token.cs,
% zip-download-action.cs, presigned-url.cs, url-file-parsing.cs,
% org-slug.cs, resolve-customer-prefix.cs, rename-customer-folder.cs,
% authorization-policy.cs, documents-service-tests.cs
+1
View File
@@ -0,0 +1 @@
% TODO: eingebundene Diagramme (falls nicht inline in Kapiteln)
+1
View File
@@ -0,0 +1 @@
% TODO: Screenshots der fertigen Documents-Seite (Liste, Filter, Suche, PDF-Modal, ZIP-Auswahl)
+2
View File
@@ -0,0 +1,2 @@
% TODO: Zeitplan Soll/Ist, Backlog (PBI-Tabelle), PR-Übersicht,
% Anforderungsmatrix, Dokumententypen↔Ordner↔Icon, Lookup-Trade-offs, Beteiligte
+17
View File
@@ -0,0 +1,17 @@
\section{Tabellen}
\input{appendix/appendix-tables}
\clearpage
\section{Diagramme}
\input{appendix/appendix-diagrams}
\clearpage
\section{Screenshots}
\input{appendix/appendix-screenshots}
\clearpage
\section{Code-Ausschnitte}
\input{appendix/appendix-code}
+4
View File
@@ -0,0 +1,4 @@
\section{Zielerreichung}
\label{sec:evaluation}
% TODO
+6
View File
@@ -0,0 +1,6 @@
\section{Ausblick}
\label{sec:outlook}
% TODO: PBI 10070 (Race Conditions), Search Integration (von AU noch nicht verfügbar),
% Dashboard-Kacheln (Security Assessments, zuletzt hinzugefügte Dokumente),
% Abrechnungsdaten
+5
View File
@@ -0,0 +1,5 @@
\section{Reflexion}
\label{sec:reflection}
% TODO: Lessons Learned — S3-Lookup-Entscheidung, Race Conditions als offenes Thema,
% Infrastruktur-Vorlauf unterschätzt (AU-Kommunikation 2026-07-22 bis 2026-08-07)
+4
View File
@@ -0,0 +1,4 @@
\section{Soll-Ist-Vergleich}
\label{sec:target-comparison}
% TODO: Tabelle Soll-Ist (Zeitplan, Features)
+1
View File
@@ -0,0 +1 @@
% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren
@@ -0,0 +1 @@
% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren
+1
View File
@@ -0,0 +1 @@
% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren
+13
View File
@@ -0,0 +1,13 @@
\section{Autorisierungskonzept}
\label{sec:authorization}
% TODO: App-Rolle Documents.Read (Entra ID), Claim efecte:company_id
% Menüpunkt nur sichtbar mit Rolle, Direktzugriff ohne Rolle → 403 (nicht 404)
% Sequence-Diagramm auth-sequence.pdf
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.9\textwidth]{figures/diagrams/auth-sequence.pdf}
% \caption{Autorisierungsablauf}
% \label{fig:auth-sequence}
% \end{figure}
+7
View File
@@ -0,0 +1,7 @@
\section{Dokumententypen und Icons}
\label{sec:document-types}
% TODO: 7 Typen hardcoded in Houston (PBI 9560/9549):
% Service-Protokoll, Abnahme Dokumente, SLA-Reports, Monitoring Reports,
% Security Assessments, Abrechnungsdaten, Vertragsunterlagen
% Typzuordnung über Unterordnername, Tabelle im Anhang
+13
View File
@@ -0,0 +1,13 @@
\section{Architekturentscheidung: O(1)-Fast-Path}
\label{sec:lookup-decision}
% TODO: PBI 10018 — metadatenbasierter Fast-Path
% ResolveCustomerPrefixAsync: Fast-Path → Kollisions-Fast-Path → O(n)-Fallback + Self-Healing-Rename
% Houston als führende Instanz für Ordnerbenennung
% \begin{figure}[H]
% \centering
% \includegraphics[width=\textwidth]{figures/diagrams/lookup-flow.pdf}
% \caption{Ablauf \texttt{ResolveCustomerPrefixAsync}}
% \label{fig:lookup-flow}
% \end{figure}
+8
View File
@@ -0,0 +1,8 @@
\section{Problem: Lookup des Kundenordners}
\label{sec:lookup-research}
% TODO: PBI 9857 — S3 kann nicht nach Metadaten-Tags suchen → lineares Scannen aller Top-Level-Prefixes
% Trade-off-Matrix der 6 Varianten (In-Memory Cache, Claim, Efecte-Feld, S3 SelectObject, Search Integration, Prefix im Namen)
% \cite{aws-s3-select}, \cite{storagegrid-search-integration}
% Tabelle~\ref{tab:lookup-tradeoffs} im Anhang
+14
View File
@@ -0,0 +1,14 @@
\section{Ablagekonzept im S3-Speicher}
\label{sec:s3-layout}
% TODO: Ordnerbaum (Feature 484):
% Bucket → Kundenordner [meta: efecte_org-id] → Typordner/ → Dokumente
% Typ = Unterordner, nicht Metadatum an der Datei
% Leere Ordner werden nicht angezeigt
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.75\textwidth]{figures/diagrams/s3-layout.pdf}
% \caption{S3-Ablagestruktur}
% \label{fig:s3-layout}
% \end{figure}
+5
View File
@@ -0,0 +1,5 @@
\section{UI-Konzept und Clickdummy}
\label{sec:ui-concept}
% TODO: Hanna Ebner, Branch Clickdummy_Dokumente (2026-07-22)
% Listenansicht, Typfilter oben als Buttons, flexible Tabellenspalten
+12
View File
@@ -0,0 +1,12 @@
\section{Architektur des Documents-Moduls}
\label{sec:architecture}
% TODO: Razor Page DocumentsPage.cshtml → DocumentsService → S3DocumentsClient
% Klassendiagramm module-components.pdf
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.9\textwidth]{figures/diagrams/module-components.pdf}
% \caption{Komponentenstruktur des Documents-Moduls}
% \label{fig:module-components}
% \end{figure}
+5
View File
@@ -0,0 +1,5 @@
\section{Document Explorer}
\label{sec:document-explorer}
% TODO: PBI 9295 — /documents Seite, ListObjectsV2, Empty State, Fehlerbehandlung
% Abbildung~\ref{fig:documents-page-model}, \ref{fig:document-view-model}, \ref{fig:documents-table-body}
+13
View File
@@ -0,0 +1,13 @@
\section{Dokumenten-Downloads}
\label{sec:downloads}
% TODO: PBI 9299 (Einzeldownload), PBI 9296 (ZIP-Download)
% Streaming: S3 GetObject → ZipArchive → HTTP Response Stream
% Abbildung~\ref{fig:zip-download-action}
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.9\textwidth]{figures/diagrams/zip-stream.pdf}
% \caption{ZIP-Download-Ablauf}
% \label{fig:zip-stream}
% \end{figure}
+6
View File
@@ -0,0 +1,6 @@
\section{Typfilter und Paginierung}
\label{sec:filter-pagination}
% TODO: PBI 9749 (Typfilter), PBI 9731 (Pagination)
% ContinuationToken statt Offset-Pagination
% Abbildung~\ref{fig:pagination-continuation-token}
+8
View File
@@ -0,0 +1,8 @@
\section{Ordnerstruktur und Kundenordner-Lookup}
\label{sec:folder-management}
% TODO: PBI 9560 (Ordneranlage beim ersten Seitenaufruf), PBI 10018 (O(1)-Lookup)
% OrgSlug: deterministische, S3-konforme Normalisierung des Efecte-Namens (Umlaute bleiben erhalten)
% IBM-Naming-Constraints: \cite{ibm-s3-naming}
% ResolveCustomerPrefixAsync, Self-Healing-Rename
% Abbildung~\ref{fig:org-slug}, \ref{fig:resolve-customer-prefix}, \ref{fig:rename-customer-folder}
+6
View File
@@ -0,0 +1,6 @@
\section{PDF-Modal-Vorschau und Share-Link-Previews}
\label{sec:pdf-preview}
% TODO: PBI 9300 (PDF-Modal), PBI 9294 (Share-Link-Previews)
% Pre-Signed URLs, zeitlich begrenzte Gültigkeit
% Abbildung~\ref{fig:presigned-url}
+15
View File
@@ -0,0 +1,15 @@
\section{Bekannte Grenze: Race Conditions im Lookup}
\label{sec:race-conditions}
% TODO: PBI 10070 — Houston läuft in mehreren Instanzen, In-Memory-Lock reicht nicht
% Szenario A: Datenverlust beim parallelen Rename (Rollback löscht Dokumente des Gewinners)
% Szenario B: Mandantenvermischung beim gleichzeitigen Anlegen gleicher Efecte-Namen
% Lösungsansätze: Rollback-Absicherung, Conditional Writes, verteiltes Lock, prozessuale Migration
% Timebox: 4–6 Stunden (Stephan Janßen)
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.9\textwidth]{figures/diagrams/race-condition-a.pdf}
% \caption{Race Condition Szenario A: Datenverlust beim parallelen Rename}
% \label{fig:race-condition-a}
% \end{figure}
+5
View File
@@ -0,0 +1,5 @@
\section{Anbindung des S3-Speichers}
\label{sec:s3-client}
% TODO: AWS SDK für .NET, IAmazonS3, keyed services in Program.cs, S3Settings (DEV/TEST/PROD Buckets)
% Abbildung~\ref{fig:s3-settings-registration}, \ref{fig:s3-documents-client}
+6
View File
@@ -0,0 +1,6 @@
\section{Serverseitige Suche}
\label{sec:search}
% TODO: PBI 9298 — Suchleiste, titelbasiert, Teiltreffer, serverseitiges Filtern
% S3-API bietet keine direkte Filterung → Houston-seitiger Filter
% Abbildung~\ref{fig:document-search}
+5
View File
@@ -0,0 +1,5 @@
\section{Dokumenttypen und Icons}
\label{sec:type-icons}
% TODO: PBI 9549 — Typ-Mapping aus Unterordner, .resx-Lokalisierung
% Abbildung~\ref{fig:document-type-mapping}, \ref{fig:document-types-resx}
+5
View File
@@ -0,0 +1,5 @@
\section{Support für URL-Dateien}
\label{sec:url-files}
% TODO: PBI 9301 — .url-Dateien parsen, Verlinkung beliebiger URLs (Teams, SharePoint)
% Abbildung~\ref{fig:url-file-parsing}
+5
View File
@@ -0,0 +1,5 @@
\section{Ausgangssituation}
\label{sec:initial-situation}
% TODO: Feature 484 lag 2,5 Jahre im Backlog (Nicole Kimmel, 2023-11-02).
% Bisher kein zentraler Dokumentenzugang für Kunden.
+4
View File
@@ -0,0 +1,4 @@
\section{Beteiligte und Rollen}
\label{sec:participants}
% TODO: Tabelle aus note-1787657238720 (Beteiligte)
@@ -0,0 +1,4 @@
\section{Projektbeschreibung}
\label{sec:project-description}
% TODO
+7
View File
@@ -0,0 +1,7 @@
\section{Projektabgrenzung}
\label{sec:project-scope}
% TODO: Out of Scope aus Feature 484:
% - Kunde kann Dokumente nicht bearbeiten
% - Keine neuen Ordner intern wild anlegen
% - Filestash ist externes Admin-UI (kein Houston-Eigenbau)
+12
View File
@@ -0,0 +1,12 @@
\section{Systemlandschaft}
\label{sec:system-landscape}
% TODO: Houston (ASP.NET Core, Razor Pages) — Efecte — Microsoft Entra ID — S3/StorageGRID — Filestash
% Diagramm:
% \begin{figure}[H]
% \centering
% \includegraphics[width=0.9\textwidth]{figures/diagrams/system-context.pdf}
% \caption{Systemkontext}
% \label{fig:system-context}
% \end{figure}
+4
View File
@@ -0,0 +1,4 @@
\section{Zielsituation}
\label{sec:target-situation}
% TODO: Feature 484 Rev 38 — Dokumentenbereich in Houston, 7 Dokumententypen, S3-Ablage, Filestash als Admin-UI
+14
View File
@@ -0,0 +1,14 @@
\section{Backlog-Schnitt und Schätzung}
\label{sec:backlog}
% TODO: 14 PBIs + 1 Bug unter Feature 484
% Prozess: DoR, DoD, Approval-Team, Sprints 15–17.2026
% Siehe Tabelle~\ref{tab:backlog} im Anhang
% Gantt:
% \begin{figure}[H]
% \centering
% \includegraphics[width=\textwidth]{figures/diagrams/gantt-plan.pdf}
% \caption{Zeitplanung über Sprints 15–17.2026}
% \label{fig:gantt}
% \end{figure}
+7
View File
@@ -0,0 +1,7 @@
\section{Feature-Analyse}
\label{sec:feature-analysis}
% TODO: 18.06.2026 — 4 Rückfragen von Linus an Thomas, Antworten im selben Ticket (Feature 484 Rev 17–32)
% - Autorisierung via Metadatum: ja
% - Filestash als externe Website (kein Custom-UI): ja
% - ...
+15
View File
@@ -0,0 +1,15 @@
\section{Infrastrukturbeschaffung}
\label{sec:infrastructure}
% TODO: Service Requests an Maschinenraum (2026-07-22), Provisionierung durch Advanced Unibyte,
% 3 Buckets (DEV/TEST/PROD), Credentials in Passbolt (2026-07-27)
% Anfrage S3 Select (2026-07-30), Aktivierung durch AU (2026-08-07)
% Search Integration: von AU nicht bereitgestellt (2026-08-17)
% Timeline-Diagramm:
% \begin{figure}[H]
% \centering
% \includegraphics[width=\textwidth]{figures/diagrams/timeline-infra.pdf}
% \caption{Chronologie der Infrastrukturbeschaffung}
% \label{fig:timeline-infra}
% \end{figure}
+5
View File
@@ -0,0 +1,5 @@
\section{Einarbeitung}
\label{sec:onboarding}
% TODO: S3-API, AWS SDK für .NET, StorageGRID-Dokumentation
% Quellen: note-1785344962361 (S3-Recherche mit Timo), note-1785413874041
+5
View File
@@ -0,0 +1,5 @@
\section{Anforderungserhebung}
\label{sec:requirements}
% TODO: Funktionale und nichtfunktionale Anforderungen aus den PBI-ACs
% Tabelle: Anforderungsmatrix (funktional / nichtfunktional → PBI)
+4
View File
@@ -0,0 +1,4 @@
\section{Zeit- und Aufwandsplanung}
\label{sec:schedule}
% TODO: Sprints 15–17.2026, Aufwandsschätzungen (Story Points), 24 Manntage / 192 h gesamt
+5
View File
@@ -0,0 +1,5 @@
\section{Abnahmetest}
\label{sec:acceptance-testing}
% TODO: Maria-Lena Andersz — Sichtbarkeitsproblem des Menüpunkts (2026-08-13)
% Rollenzuweisung klären, Bug 10134 (Suchfunktion), finale Abnahme 2026-08-24/25
+7
View File
@@ -0,0 +1,7 @@
\section{Code-Reviews}
\label{sec:code-reviews}
% TODO: 11 PRs (2154–2196), Reviewer: Timo Walter, Sarah Hinzmann, Robin Noack
% Reviewfunde: zentrale Auth über Program.cs, keyed Settings, 403 statt 404,
% Slug-Naming-Constraints (IBM-Doku), Fehlerbehandlung statt stiller leerer Seite
% Tabelle~\ref{tab:pull-requests} im Anhang
+5
View File
@@ -0,0 +1,5 @@
\section{Releases}
\label{sec:releases}
% TODO: DEV / TEST / PROD je eigener Bucket, Rollenvergabe vor Release
% PR 2196 noch aktiv bei Dokumentationsabgabe
+4
View File
@@ -0,0 +1,4 @@
\section{Teststrategie}
\label{sec:test-strategy}
% TODO: Unit-Tests mit gemocktem IAmazonS3, Abnahmetests durch Maria-Lena Andersz
+6
View File
@@ -0,0 +1,6 @@
\section{Unit-Tests}
\label{sec:unit-tests}
% TODO: DocumentsServiceTests — gemocktes IAmazonS3
% Pfade: Fast-Path, Fallback, Rename, Create, Kollision, Fehlerfall
% Abbildung~\ref{fig:documents-service-tests}
+10
View File
@@ -0,0 +1,10 @@
stateDiagram-v2
[*] --> New
New --> ToApprove : Linus reicht PBI ein
ToApprove --> Approved : Approval-Team
Approved --> Committed : Sprint-Planung
Committed --> DevCompleted : PR gemerged
DevCompleted --> TestCompleted : Abnahme bestanden
TestCompleted --> [*]
ToApprove --> Removed : Verworfen
Removed --> New : Wiederhergestellt
+18
View File
@@ -0,0 +1,18 @@
sequenceDiagram
participant B as Browser
participant H as Houston
participant AAD as Entra ID
participant S3 as S3-Speicher
B->>H: GET /documents
H->>H: Prüfe Claim Documents.Read
alt Keine Rolle
H-->>B: 403 Forbidden
else Rolle vorhanden
H->>H: Lese efecte:company_id aus Claim
H->>S3: ResolveCustomerPrefixAsync(orgId)
S3-->>H: Kundenordner-Prefix
H->>S3: ListObjectsV2(prefix)
S3-->>H: Objektliste
H-->>B: Documents-Seite
end
+18
View File
@@ -0,0 +1,18 @@
gantt
title Zeitplanung PidI 3 (Sprints 15–17.2026)
dateFormat YYYY-MM-DD
section Planung
Feature-Analyse :done, 2026-06-18, 1d
Anforderungen & Backlog :done, 2026-07-07, 5d
section Sprint 15.2026
Document Explorer :done, 2026-07-27, 5d
Icons & Suche :done, 2026-08-01, 12d
Downloads & PDF-Modal :done, 2026-08-15, 7d
section Sprint 16.2026
Typfilter & Pagination :done, 2026-08-18, 4d
Ordner-Lookup :active, 2026-08-17, 8d
section Sprint 17.2026
Race Conditions (10070) :2026-08-26, 5d
section Qualitätssicherung
Abnahmetest :done, 2026-08-13, 12d
Release :2026-08-26, 3d
+10
View File
@@ -0,0 +1,10 @@
flowchart TD
A[ResolveCustomerPrefixAsync\norgId, orgName] --> B{Fast-Path:\nGetObjectMetadata\nslug-name/}
B -->|Gefunden & ID passt| Z[✓ Fertig\n1 Request]
B -->|Nicht gefunden oder\nID passt nicht| C{Kollisions-Fast-Path:\nslug-name orgId /}
C -->|Gefunden| Z2[✓ Fertig\n2 Requests]
C -->|Nicht gefunden| D[Fallback: O-n\nListObjectsV2 alle\nTop-Level-Prefixes]
D -->|Ordner mit\npAssender ID gefunden| E[Rename auf\nkanonischen Namen]
E --> Z3[✓ Fertig\nnächster Lookup O-1]
D -->|Kein Ordner| F[Anlegen: Ordner +\nUnterstruktur 9560]
F --> Z4[✓ Fertig\nSeite leer]
+29
View File
@@ -0,0 +1,29 @@
classDiagram
class DocumentsPage {
+OnGetAsync()
+OnGetDownloadAsync()
+OnGetZipAsync()
}
class DocumentsService {
+ListDocumentsAsync(orgId, search, type, token)
+GetDownloadUrlAsync(orgId, key)
+GetZipStreamAsync(orgId, keys)
+ResolveCustomerPrefixAsync(orgId, orgName)
}
class S3DocumentsClient {
-IAmazonS3 _s3
+ListObjectsAsync(prefix, delimiter, token)
+GetObjectMetadataAsync(key)
+GetPresignedUrlAsync(key)
}
class OrgSlug {
+Slugify(name) string
}
class S3Settings {
+BucketName string
+ServiceUrl string
}
DocumentsPage --> DocumentsService
DocumentsService --> S3DocumentsClient
DocumentsService --> OrgSlug
S3DocumentsClient --> S3Settings
+15
View File
@@ -0,0 +1,15 @@
sequenceDiagram
participant A as Request A
participant S3 as S3-Speicher
participant B as Request B
Note over A,B: Ordner AltName/ mit 200 Objekten, Zielname: Kunde GmbH/
A->>S3: CanClaim(Kunde GmbH) → Missing → true
B->>S3: CanClaim(Kunde GmbH) → Missing → true
A->>S3: Kopiere 200 Objekte nach Kunde GmbH/
B->>S3: Kopiere Objekte #1–60 nach Kunde GmbH/
A->>S3: DeleteObjects(AltName/*) ✓
B->>S3: Kopie #61 → NoSuchKey ✗
B->>S3: catch: DeleteObjects(copiedKeys #1–60)
Note over S3: 60 Objekte aus Kunde GmbH/ gelöscht!
Note over S3: AltName/ existiert nicht mehr → Datenverlust
+9
View File
@@ -0,0 +1,9 @@
flowchart TD
B[(S3-Bucket\ndocuments-houston-prod)]
B --> KA["Kunde A/\n[meta: efecte_org-id=42]"]
B --> KB["Kunde B/\n[meta: efecte_org-id=77]"]
KA --> D1[doc1.pdf\nuntyped]
KA --> T1["Service-Protokoll/"]
KA --> T2["Vertragsunterlagen/"]
T1 --> D2[bericht-2026-07.pdf]
T2 --> D3[SLA-2026.pdf]
+18
View File
@@ -0,0 +1,18 @@
flowchart LR
subgraph Kunde
K[Kundenportal\nHouston]
end
subgraph WorkSimple
H[Houston\nASP.NET Core]
F[Filestash\nS3-Browser]
end
subgraph Infrastruktur
E[Efecte\nCMDB]
S3[(S3-Speicher\nStorageGRID)]
AAD[Microsoft\nEntra ID]
end
K -->|HTTPS| H
H -->|REST| E
H -->|AWS SDK| S3
H -->|OpenID Connect| AAD
F -->|S3-API| S3
+10
View File
@@ -0,0 +1,10 @@
%%{init: {'theme': 'base'}}%%
timeline
title Infrastrukturbeschaffung S3-Speicher
2026-07-22 : Service Request erstellt (Maschinenraum)
2026-07-23 : Request Alexander Wagner zugewiesen
2026-07-27 : 3 Buckets durch AU erstellt, Credentials in Passbolt
2026-07-30 : Anfrage S3 Select + Search Integration
2026-08-04 : Lennart Meinert kontaktiert AU
2026-08-07 : S3 Select für alle 3 Buckets aktiviert
2026-08-17 : Search Integration von AU abgelehnt
+15
View File
@@ -0,0 +1,15 @@
sequenceDiagram
participant B as Browser
participant P as PageModel
participant S as DocumentsService
participant S3 as S3-Speicher
B->>P: POST /documents?handler=Zip&keys=[...]
P->>S: GetZipStreamAsync(orgId, keys)
loop je Dokument
S->>S3: GetObjectAsync(key)
S3-->>S: Stream
S->>S: ZipArchive.CreateEntry + CopyToAsync
end
S-->>P: ZipStream
P-->>B: application/zip (streaming)
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

+4
View File
@@ -0,0 +1,4 @@
% \chapter*{Kurzfassung}
% \addcontentsline{toc}{chapter}{Kurzfassung}
% TODO
% \clearpage
+4
View File
@@ -0,0 +1,4 @@
% \chapter*{Danksagung}
% \addcontentsline{toc}{chapter}{Danksagung}
% TODO
% \clearpage
+10
View File
@@ -0,0 +1,10 @@
\chapter*{Nutzung von KI}
\addcontentsline{toc}{chapter}{Nutzung von KI}
Bei der Erstellung dieser Dokumentation wurde KI ausschließlich für die folgenden Bereiche verwendet:
\begin{itemize}
\item Erlernen von \LaTeX-Syntax und Suche von entsprechenden \LaTeX-Packages für diese Dokumentation
\item Formatierung und Umformulierung von Inhalt, der vom Autor verfasst wurde, in den Kapiteln \ref{chap:company}, \ref{chap:overview}, \ref{chap:planning}, \ref{chap:conception}, \ref{chap:execution}, \ref{chap:qa} und \ref{chap:closure}
\end{itemize}
\clearpage
+102
View File
@@ -0,0 +1,102 @@
\documentclass[times]{pidi-thesis}
% --- Bibliography
\usepackage[backend=biber,style=authoryear,sorting=nyt]{biblatex}
\addbibresource{references.bib}
% Language
\selectlanguage{ngerman}
% --- Metadata
\setthesismeta
{Houston Dokumente: Kundendokumente aus S3}
{Houston Dokumente}
{Linus Nagel}
{2024008}
{Bachelor of Science - IT und Software Systeme}
{ITC Dortmund}
{Informatik}
{WorkSimple GmbH}
{Sarah Hinzmann}
\setdates
{TODO -- TODO}
{TODO}
\begin{document}
\renewcommand{\companylogo}{figures/worksimple/Logo_Normal.png}
\renewcommand{\unilogo}{figures/itc/IT-Center_Dortmund_Logo.svg.png}
\renewcommand{\headerlogo}{figures/worksimple/Icon.png}
\frontmatterpages
\chapter{Vorstellung des Unternehmens}
\label{chap:company}
\input{chapters/company/worksimple}
\input{chapters/company/products-and-services}
\input{chapters/company/econ-localization}
\chapter{Projektüberblick}
\label{chap:overview}
\input{chapters/overview/project-description}
\input{chapters/overview/initial-situation}
\input{chapters/overview/system-landscape}
\input{chapters/overview/target-situation}
\input{chapters/overview/project-scope}
\input{chapters/overview/participants}
\chapter{Planung und Vorbereitung}
\label{chap:planning}
\input{chapters/planning/onboarding}
\input{chapters/planning/feature-analysis}
\input{chapters/planning/requirements}
\input{chapters/planning/backlog}
\input{chapters/planning/schedule}
\input{chapters/planning/infrastructure}
\chapter{Konzeption}
\label{chap:conception}
\input{chapters/conception/s3-layout}
\input{chapters/conception/authorization}
\input{chapters/conception/document-types}
\input{chapters/conception/ui-concept}
\input{chapters/conception/lookup-research}
\input{chapters/conception/lookup-decision}
\chapter{Umsetzung}
\label{chap:execution}
\input{chapters/execution/architecture}
\input{chapters/execution/s3-client}
\input{chapters/execution/document-explorer}
\input{chapters/execution/type-icons}
\input{chapters/execution/search}
\input{chapters/execution/filter-pagination}
\input{chapters/execution/downloads}
\input{chapters/execution/pdf-preview}
\input{chapters/execution/url-files}
\input{chapters/execution/folder-management}
\input{chapters/execution/race-conditions}
\chapter{Qualitätssicherung und Auslieferung}
\label{chap:qa}
\input{chapters/qa/test-strategy}
\input{chapters/qa/unit-tests}
\input{chapters/qa/code-reviews}
\input{chapters/qa/acceptance-testing}
\input{chapters/qa/releases}
\chapter{Projektabschluss}
\label{chap:closure}
\input{chapters/closure/target-comparison}
\input{chapters/closure/evaluation}
\input{chapters/closure/reflection}
\input{chapters/closure/outlook}
\appendix
\chapter{Anhang}
\input{appendix/appendix}
\printrefs
\end{document}
+246
View File
@@ -0,0 +1,246 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{pidi-thesis}[2025/09/03 v1.0 PidI Thesis Class]
\newif\if@times
\newif\if@calibri
\newif\if@arial
\@timestrue % default
\DeclareOption{times}{\@timestrue \@arialfalse \@calibrifalse}
\DeclareOption{calibri}{\@calibritrue \@arialfalse \@timesfalse}
\DeclareOption{arial}{\@arialtrue \@calibrifalse \@timesfalse}
% pass through unknown options to base class if needed
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}}
\ProcessOptions\relax
% size depends on font choice: Times (12pt) vs sans (11pt)
\if@times
\LoadClass[12pt,a4paper]{report}
\else
\LoadClass[11pt,a4paper]{report}
\fi
% --- Packages
\RequirePackage[a4paper,left=3cm,right=2.5cm,top=3cm,bottom=2.5cm,headsep=1cm,footskip=10mm,includehead,includefoot]{geometry}
\RequirePackage{float}
\RequirePackage{iftex}
\RequirePackage{microtype}
\RequirePackage{setspace}
\RequirePackage{graphicx}
\RequirePackage{booktabs}
\RequirePackage{tabularx}
\RequirePackage{caption}
\RequirePackage{titlesec}
\RequirePackage{enumitem}
\RequirePackage{fancyhdr}
\RequirePackage{hyperref}
\RequirePackage{xcolor}
\RequirePackage[ngerman,english]{babel}
\RequirePackage{csquotes}
\RequirePackage{transparent}
\RequirePackage[absolute,overlay]{textpos}
\RequirePackage{changepage}
\RequirePackage{listings}
\RequirePackage{minted}
\RequirePackage{pdfpages}
\RequirePackage{longtable}
\RequirePackage[htt]{hyphenat}
% Code highlighting
\usemintedstyle{default}
% Fonts: sans (Arial/Calibri) in 11pt, or Times New Roman 12pt
\ifPDFTeX
\if@times
\RequirePackage{newtxtext}
\else
\RequirePackage[scaled=0.95]{helvet}
\renewcommand{\familydefault}{\sfdefault}
\fi
\else
\RequirePackage{fontspec}
\if@times
\setmainfont{TimesNewerRoman-Regular.otf}[
BoldFont = TimesNewerRoman-Bold.otf,
ItalicFont = TimesNewerRoman-Italic.otf,
BoldItalicFont = TimesNewerRoman-BoldItalic.otf
]
\else
\if@calibri
\setmainfont{Calibri}
\else
\setmainfont{Arial}
\fi
\fi
\fi
% Line spacing
\setstretch{1.3}
% Paragraph spacing
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt}
% Headings: bold + clear visual hierarchy
\titleformat{\chapter}{\bfseries\LARGE}{\thechapter\quad}{0pt}{}
\titlespacing*{\chapter}{0pt}{*2}{*1}
\titleformat{\section}{\bfseries\Large}{\thesection\quad}{0pt}{}
\titlespacing*{\section}{0pt}{*1.5}{*0.8}
\titleformat{\subsection}{\bfseries\large}{\thesubsection\quad}{0pt}{}
\titlespacing*{\subsection}{0pt}{*1.2}{*0.6}
% Emphasis should be bold as per spec
\renewcommand{\emph}[1]{\textbf{#1}}
% Captions a bit tighter
\captionsetup{font=small,labelfont=bf}
% Lists tighter by default
\setlist{itemsep=3pt plus 1pt, topsep=6pt}
% Header & footer: page number bottom-center; optional header with short title
\pagestyle{fancy}
\fancyhf{} % clear
\fancyfoot[C]{\thepage}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
% Redefine 'plain' style to ensure chapter starting pages also use bottom-center numbering
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[C]{\thepage}
\renewcommand{\headrulewidth}{0pt}
\renewcommand{\footrulewidth}{0pt}
}
% Optional header content command; placed 1cm above text via headsep=1cm
\newcommand{\shorthead}{}
\fancyhead[L]{\shorthead}
\newcommand{\headerlogo}{}
\fancyhead[R]{\IfFileExists{\headerlogo}{\includegraphics[height=1em]{\headerlogo}}{}}
\renewcommand{\headrulewidth}{0.4pt}
% Hyperref setup
\hypersetup{
pdftitle={},
pdfauthor={},
colorlinks=true,
linkcolor=[rgb]{0.0,0.2,0.6},
citecolor=[rgb]{0.0,0.2,0.6},
urlcolor=[rgb]{0.0,0.2,0.6}
}
% --- Meta fields
\newcommand{\thesistitle}{}
\newcommand{\thesisshorttitle}{}
\newcommand{\authorname}{}
\newcommand{\matrikel}{}
\newcommand{\degree}{}
\newcommand{\institution}{}
\newcommand{\faculty}{}
\newcommand{\course}{Praktikum in der Industrie (PidI 3)}
\newcommand{\company}{}
\newcommand{\advisor}{}
\newcommand{\daterange}{}
\newcommand{\submissiondate}{}
\newcommand{\setthesismeta}[9]{%
\renewcommand{\thesistitle}{#1}%
\renewcommand{\thesisshorttitle}{#2}%
\renewcommand{\authorname}{#3}%
\renewcommand{\matrikel}{#4}%
\renewcommand{\degree}{#5}%
\renewcommand{\institution}{#6}%
\renewcommand{\faculty}{#7}%
\renewcommand{\company}{#8}%
\renewcommand{\advisor}{#9}%
}
\newcommand{\setdates}[2]{%
\renewcommand{\daterange}{#1}%
\renewcommand{\submissiondate}{#2}%
}
% Update header and pdf meta when title/author set
\AtBeginDocument{%
\renewcommand{\shorthead}{\thesisshorttitle}%
\hypersetup{pdftitle=\thesistitle, pdfauthor=\authorname}%
}
% Title page per spec, clean & simple
\newcommand{\companylogo}{}
\newcommand{\unilogo}{}
\newcommand{\maketitlepage}{%
\begin{titlepage}
\newcommand{\hlogo}{1.5cm}
\centering
{\bfseries\LARGE \thesistitle\par}
\vspace{2em}
{\Large \course\par}
\vspace{2em}
{\large \textbf{Autor/in:} \authorname \\
\textbf{Matrikelnummer:} \matrikel \par}
\vspace{1em}
{\large \textbf{Studiengang/Abschluss:} \degree \par}
\vspace{1em}
{\large \textbf{Hochschule:} \institution \\
\textbf{Fakultät/Bereich:} \faculty \par}
\vspace{1em}
{\large \textbf{Partnerunternehmen:} \company \\
\textbf{Betreuer/in im Unternehmen:} \advisor \par}
\vspace{2em}
\includegraphics[height=\hlogo]{\companylogo}
\hfill
\includegraphics[height=\hlogo]{\unilogo}
\vfill
{\large \textbf{Tätigkeitszeitraum:} \daterange \par}
\vspace{0.5em}
{\large \textbf{Abgabedatum:} \submissiondate \par}
\addcontentsline{toc}{chapter}{Titelseite}
\end{titlepage}
}
% Confirmation page (Bescheinigung)
\newcommand{\confirmationpage}{%
\chapter*{Bescheinigung}
Hiermit wird bestätigt, dass \textbf{\authorname} das Praktikum \textbf{\course} im Partnerunternehmen \textbf{\company} im Zeitraum \textbf{\daterange} selbständig durchgeführt hat. Es wurden mindestens \textbf{24 Manntage} an dem Projekt gearbeitet. Der Einsatz von KI beschränkt sich maximal auf die erlaubten Zwecke.
\vspace{4em}
\begin{tabularx}{\textwidth}{X X}
\hrulefill & \hrulefill \\
Ort, Datum & Unterschrift Betreuer/in \\
\end{tabularx}
\addcontentsline{toc}{chapter}{Bescheinigung}
\clearpage
}
% Abstract & declarations convenience
\newcommand{\frontmatterpages}{%
\pagenumbering{roman}
\maketitlepage
\renewcommand*\contentsname{Inhaltsangabe}
\tableofcontents
\addcontentsline{toc}{chapter}{Inhaltsangabe}
\confirmationpage
\input{frontmatter/usage-of-ai}
\input{frontmatter/abstract}
\input{frontmatter/acknowledgments}
\clearpage
\pagenumbering{arabic}
}
% Bibliography (biblatex expected)
\newcommand{\printrefs}{%
\clearpage
\addcontentsline{toc}{chapter}{Literaturverzeichnis}
\printbibliography
}
+92
View File
@@ -0,0 +1,92 @@
@comment{Quellen für PidI 3 — Houston Dokumente}
@online{aws-s3-select,
author = {{Amazon Web Services}},
title = {Selecting content from objects},
url = {https://docs.aws.amazon.com/AmazonS3/latest/userguide/selecting-content-from-objects.html},
urldate = {2026-08-25}
}
@online{aws-listobjectsv2,
author = {{Amazon Web Services}},
title = {ListObjectsV2},
url = {https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html},
urldate = {2026-08-25}
}
@online{aws-s3-naming,
author = {{Amazon Web Services}},
title = {Object key naming guidelines},
url = {https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html},
urldate = {2026-08-25}
}
@online{aws-conditional-writes,
author = {{Amazon Web Services}},
title = {Conditional requests for Amazon S3},
url = {https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-requests.html},
urldate = {2026-08-25}
}
@online{aws-presigned-urls,
author = {{Amazon Web Services}},
title = {Sharing objects with presigned URLs},
url = {https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html},
urldate = {2026-08-25}
}
@online{storagegrid-s3-select,
author = {{NetApp}},
title = {Use S3 Select Object Content},
url = {https://docs.netapp.com/us-en/storagegrid/s3/select-object-content.html},
urldate = {2026-08-25}
}
@online{storagegrid-search-integration,
author = {{NetApp}},
title = {Use the StorageGRID search integration service},
url = {https://docs.netapp.com/us-en/storagegrid-enable/product-feature-guides/storagegrid-search-integration-service.html},
urldate = {2026-08-25}
}
@online{ibm-s3-naming,
author = {{IBM}},
title = {Naming constraints for object storage},
url = {https://www.ibm.com/docs/en/ahts/4.4.x?topic=reference-naming-constraints},
urldate = {2026-08-25}
}
@online{filestash-s3,
author = {{Mickael Kerjean}},
title = {Filestash — S3 Browser},
url = {https://www.filestash.app/s3-browser.html},
urldate = {2026-08-25}
}
@online{dotnet-keyed-di,
author = {{Microsoft}},
title = {Keyed services in .NET dependency injection},
url = {https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#keyed-services},
urldate = {2026-08-25}
}
@online{dotnet-zip,
author = {{Microsoft}},
title = {ZipArchive Class},
url = {https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.ziparchive},
urldate = {2026-08-25}
}
@online{entra-app-roles,
author = {{Microsoft}},
title = {Add app roles to your application and receive them in the token},
url = {https://learn.microsoft.com/en-us/entra/identity-platform/howto-add-app-roles-in-apps},
urldate = {2026-08-25}
}
@online{razor-pages,
author = {{Microsoft}},
title = {Introduction to Razor Pages in ASP.NET Core},
url = {https://learn.microsoft.com/en-us/aspnet/core/razor-pages/},
urldate = {2026-08-25}
}
+47
View File
@@ -0,0 +1,47 @@
with import <nixpkgs> {}; let
fonts = [
times-newer-roman
];
# This is not reccocgnised by latexmk, so we will have to put our
# font files in ~/.local/share/fonts
# fontsConf = makeFontsConf {
# fontDirectories = fonts;
# };
# export FONTCONFIG_FILE="${fontsConf}"
in
mkShell {
nativeBuildInputs = fonts;
packages = [
latexrun
mermaid-cli
times-newer-roman
(texlive.withPackages (ps:
with ps; [
transparent
times
hyphenat
changepage
biblatex
listings
minted
upquote
biber
fontaxes
newtxtt
newtx
newtxsf
csquotes
enumitem
titlesec
latexmk
scheme-medium
textpos
]))
];
shellHook = ''
# install fonts
DEST=~/.local/share/fonts/TimesNewerRoman
mkdir -p $DEST
cp -r ${toString times-newer-roman}/share/fonts/opentype "$DEST"
'';
}