From 34f18638821b5b9a44b61914fa3ba4fe348b267f Mon Sep 17 00:00:00 2001 From: 0qln <0qln@proton.me> Date: Tue, 25 Aug 2026 19:04:44 +0200 Subject: [PATCH] initial scaffold: structure, build setup, chapter stubs, diagrams --- .biber.conf | 4 + .envrc | 3 + .gitignore | 4 + .latexmkrc | 4 + README.md | 58 +++++ appendix/appendix-code.tex | 10 + appendix/appendix-diagrams.tex | 1 + appendix/appendix-screenshots.tex | 1 + appendix/appendix-tables.tex | 2 + appendix/appendix.tex | 17 ++ chapters/closure/evaluation.tex | 4 + chapters/closure/outlook.tex | 6 + chapters/closure/reflection.tex | 5 + chapters/closure/target-comparison.tex | 4 + chapters/company/econ-localization.tex | 1 + chapters/company/products-and-services.tex | 1 + chapters/company/worksimple.tex | 1 + chapters/conception/authorization.tex | 13 ++ chapters/conception/document-types.tex | 7 + chapters/conception/lookup-decision.tex | 13 ++ chapters/conception/lookup-research.tex | 8 + chapters/conception/s3-layout.tex | 14 ++ chapters/conception/ui-concept.tex | 5 + chapters/execution/architecture.tex | 12 + chapters/execution/document-explorer.tex | 5 + chapters/execution/downloads.tex | 13 ++ chapters/execution/filter-pagination.tex | 6 + chapters/execution/folder-management.tex | 8 + chapters/execution/pdf-preview.tex | 6 + chapters/execution/race-conditions.tex | 15 ++ chapters/execution/s3-client.tex | 5 + chapters/execution/search.tex | 6 + chapters/execution/type-icons.tex | 5 + chapters/execution/url-files.tex | 5 + chapters/overview/initial-situation.tex | 5 + chapters/overview/participants.tex | 4 + chapters/overview/project-description.tex | 4 + chapters/overview/project-scope.tex | 7 + chapters/overview/system-landscape.tex | 12 + chapters/overview/target-situation.tex | 4 + chapters/planning/backlog.tex | 14 ++ chapters/planning/feature-analysis.tex | 7 + chapters/planning/infrastructure.tex | 15 ++ chapters/planning/onboarding.tex | 5 + chapters/planning/requirements.tex | 5 + chapters/planning/schedule.tex | 4 + chapters/qa/acceptance-testing.tex | 5 + chapters/qa/code-reviews.tex | 7 + chapters/qa/releases.tex | 5 + chapters/qa/test-strategy.tex | 4 + chapters/qa/unit-tests.tex | 6 + figures/diagrams/ado-workflow.mmd | 10 + figures/diagrams/auth-sequence.mmd | 18 ++ figures/diagrams/gantt-plan.mmd | 18 ++ figures/diagrams/lookup-flow.mmd | 10 + figures/diagrams/module-components.mmd | 29 +++ figures/diagrams/race-condition-a.mmd | 15 ++ figures/diagrams/s3-layout.mmd | 9 + figures/diagrams/system-context.mmd | 18 ++ figures/diagrams/timeline-infra.mmd | 10 + figures/diagrams/zip-stream.mmd | 15 ++ figures/itc/IT-Center_Dortmund_Logo.svg.png | Bin 0 -> 5245 bytes frontmatter/abstract.tex | 4 + frontmatter/acknowledgments.tex | 4 + frontmatter/usage-of-ai.tex | 10 + main.tex | 102 ++++++++ pidi-thesis.cls | 246 ++++++++++++++++++++ references.bib | 92 ++++++++ shell.nix | 47 ++++ 69 files changed, 1042 insertions(+) create mode 100644 .biber.conf create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 .latexmkrc create mode 100644 README.md create mode 100644 appendix/appendix-code.tex create mode 100644 appendix/appendix-diagrams.tex create mode 100644 appendix/appendix-screenshots.tex create mode 100644 appendix/appendix-tables.tex create mode 100644 appendix/appendix.tex create mode 100644 chapters/closure/evaluation.tex create mode 100644 chapters/closure/outlook.tex create mode 100644 chapters/closure/reflection.tex create mode 100644 chapters/closure/target-comparison.tex create mode 100644 chapters/company/econ-localization.tex create mode 100644 chapters/company/products-and-services.tex create mode 100644 chapters/company/worksimple.tex create mode 100644 chapters/conception/authorization.tex create mode 100644 chapters/conception/document-types.tex create mode 100644 chapters/conception/lookup-decision.tex create mode 100644 chapters/conception/lookup-research.tex create mode 100644 chapters/conception/s3-layout.tex create mode 100644 chapters/conception/ui-concept.tex create mode 100644 chapters/execution/architecture.tex create mode 100644 chapters/execution/document-explorer.tex create mode 100644 chapters/execution/downloads.tex create mode 100644 chapters/execution/filter-pagination.tex create mode 100644 chapters/execution/folder-management.tex create mode 100644 chapters/execution/pdf-preview.tex create mode 100644 chapters/execution/race-conditions.tex create mode 100644 chapters/execution/s3-client.tex create mode 100644 chapters/execution/search.tex create mode 100644 chapters/execution/type-icons.tex create mode 100644 chapters/execution/url-files.tex create mode 100644 chapters/overview/initial-situation.tex create mode 100644 chapters/overview/participants.tex create mode 100644 chapters/overview/project-description.tex create mode 100644 chapters/overview/project-scope.tex create mode 100644 chapters/overview/system-landscape.tex create mode 100644 chapters/overview/target-situation.tex create mode 100644 chapters/planning/backlog.tex create mode 100644 chapters/planning/feature-analysis.tex create mode 100644 chapters/planning/infrastructure.tex create mode 100644 chapters/planning/onboarding.tex create mode 100644 chapters/planning/requirements.tex create mode 100644 chapters/planning/schedule.tex create mode 100644 chapters/qa/acceptance-testing.tex create mode 100644 chapters/qa/code-reviews.tex create mode 100644 chapters/qa/releases.tex create mode 100644 chapters/qa/test-strategy.tex create mode 100644 chapters/qa/unit-tests.tex create mode 100644 figures/diagrams/ado-workflow.mmd create mode 100644 figures/diagrams/auth-sequence.mmd create mode 100644 figures/diagrams/gantt-plan.mmd create mode 100644 figures/diagrams/lookup-flow.mmd create mode 100644 figures/diagrams/module-components.mmd create mode 100644 figures/diagrams/race-condition-a.mmd create mode 100644 figures/diagrams/s3-layout.mmd create mode 100644 figures/diagrams/system-context.mmd create mode 100644 figures/diagrams/timeline-infra.mmd create mode 100644 figures/diagrams/zip-stream.mmd create mode 100644 figures/itc/IT-Center_Dortmund_Logo.svg.png create mode 100644 frontmatter/abstract.tex create mode 100644 frontmatter/acknowledgments.tex create mode 100644 frontmatter/usage-of-ai.tex create mode 100644 main.tex create mode 100644 pidi-thesis.cls create mode 100644 references.bib create mode 100644 shell.nix diff --git a/.biber.conf b/.biber.conf new file mode 100644 index 0000000..0680dba --- /dev/null +++ b/.biber.conf @@ -0,0 +1,4 @@ + + out + out + diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..d84c52c --- /dev/null +++ b/.envrc @@ -0,0 +1,3 @@ +use nix + +export VIMTEX_OUTPUT_DIRECTORY="out" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..faf7b4f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +out +latexout +latex.out +.direnv diff --git a/.latexmkrc b/.latexmkrc new file mode 100644 index 0000000..a6cf24a --- /dev/null +++ b/.latexmkrc @@ -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'; diff --git a/README.md b/README.md new file mode 100644 index 0000000..a0f513b --- /dev/null +++ b/README.md @@ -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 + +` PidI 3 .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//*.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 +``` diff --git a/appendix/appendix-code.tex b/appendix/appendix-code.tex new file mode 100644 index 0000000..7ffae9b --- /dev/null +++ b/appendix/appendix-code.tex @@ -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 diff --git a/appendix/appendix-diagrams.tex b/appendix/appendix-diagrams.tex new file mode 100644 index 0000000..15ab173 --- /dev/null +++ b/appendix/appendix-diagrams.tex @@ -0,0 +1 @@ +% TODO: eingebundene Diagramme (falls nicht inline in Kapiteln) diff --git a/appendix/appendix-screenshots.tex b/appendix/appendix-screenshots.tex new file mode 100644 index 0000000..bbfe415 --- /dev/null +++ b/appendix/appendix-screenshots.tex @@ -0,0 +1 @@ +% TODO: Screenshots der fertigen Documents-Seite (Liste, Filter, Suche, PDF-Modal, ZIP-Auswahl) diff --git a/appendix/appendix-tables.tex b/appendix/appendix-tables.tex new file mode 100644 index 0000000..7ecd1db --- /dev/null +++ b/appendix/appendix-tables.tex @@ -0,0 +1,2 @@ +% TODO: Zeitplan Soll/Ist, Backlog (PBI-Tabelle), PR-Übersicht, +% Anforderungsmatrix, Dokumententypen↔Ordner↔Icon, Lookup-Trade-offs, Beteiligte diff --git a/appendix/appendix.tex b/appendix/appendix.tex new file mode 100644 index 0000000..acd38d0 --- /dev/null +++ b/appendix/appendix.tex @@ -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} diff --git a/chapters/closure/evaluation.tex b/chapters/closure/evaluation.tex new file mode 100644 index 0000000..8405f56 --- /dev/null +++ b/chapters/closure/evaluation.tex @@ -0,0 +1,4 @@ +\section{Zielerreichung} +\label{sec:evaluation} + +% TODO diff --git a/chapters/closure/outlook.tex b/chapters/closure/outlook.tex new file mode 100644 index 0000000..8a442e7 --- /dev/null +++ b/chapters/closure/outlook.tex @@ -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 diff --git a/chapters/closure/reflection.tex b/chapters/closure/reflection.tex new file mode 100644 index 0000000..3708ef0 --- /dev/null +++ b/chapters/closure/reflection.tex @@ -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) diff --git a/chapters/closure/target-comparison.tex b/chapters/closure/target-comparison.tex new file mode 100644 index 0000000..562cb9f --- /dev/null +++ b/chapters/closure/target-comparison.tex @@ -0,0 +1,4 @@ +\section{Soll-Ist-Vergleich} +\label{sec:target-comparison} + +% TODO: Tabelle Soll-Ist (Zeitplan, Features) diff --git a/chapters/company/econ-localization.tex b/chapters/company/econ-localization.tex new file mode 100644 index 0000000..a66c6f9 --- /dev/null +++ b/chapters/company/econ-localization.tex @@ -0,0 +1 @@ +% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren diff --git a/chapters/company/products-and-services.tex b/chapters/company/products-and-services.tex new file mode 100644 index 0000000..a66c6f9 --- /dev/null +++ b/chapters/company/products-and-services.tex @@ -0,0 +1 @@ +% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren diff --git a/chapters/company/worksimple.tex b/chapters/company/worksimple.tex new file mode 100644 index 0000000..a66c6f9 --- /dev/null +++ b/chapters/company/worksimple.tex @@ -0,0 +1 @@ +% TODO: Kapitel aus PidI 2 übernehmen und auf PidI 3 aktualisieren diff --git a/chapters/conception/authorization.tex b/chapters/conception/authorization.tex new file mode 100644 index 0000000..63b7423 --- /dev/null +++ b/chapters/conception/authorization.tex @@ -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} diff --git a/chapters/conception/document-types.tex b/chapters/conception/document-types.tex new file mode 100644 index 0000000..919bc8c --- /dev/null +++ b/chapters/conception/document-types.tex @@ -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 diff --git a/chapters/conception/lookup-decision.tex b/chapters/conception/lookup-decision.tex new file mode 100644 index 0000000..29cd0e7 --- /dev/null +++ b/chapters/conception/lookup-decision.tex @@ -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} diff --git a/chapters/conception/lookup-research.tex b/chapters/conception/lookup-research.tex new file mode 100644 index 0000000..4317894 --- /dev/null +++ b/chapters/conception/lookup-research.tex @@ -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 diff --git a/chapters/conception/s3-layout.tex b/chapters/conception/s3-layout.tex new file mode 100644 index 0000000..a2f09a5 --- /dev/null +++ b/chapters/conception/s3-layout.tex @@ -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} diff --git a/chapters/conception/ui-concept.tex b/chapters/conception/ui-concept.tex new file mode 100644 index 0000000..7ecdd93 --- /dev/null +++ b/chapters/conception/ui-concept.tex @@ -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 diff --git a/chapters/execution/architecture.tex b/chapters/execution/architecture.tex new file mode 100644 index 0000000..a673dad --- /dev/null +++ b/chapters/execution/architecture.tex @@ -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} diff --git a/chapters/execution/document-explorer.tex b/chapters/execution/document-explorer.tex new file mode 100644 index 0000000..b1ecd74 --- /dev/null +++ b/chapters/execution/document-explorer.tex @@ -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} diff --git a/chapters/execution/downloads.tex b/chapters/execution/downloads.tex new file mode 100644 index 0000000..509c561 --- /dev/null +++ b/chapters/execution/downloads.tex @@ -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} diff --git a/chapters/execution/filter-pagination.tex b/chapters/execution/filter-pagination.tex new file mode 100644 index 0000000..e4f2550 --- /dev/null +++ b/chapters/execution/filter-pagination.tex @@ -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} diff --git a/chapters/execution/folder-management.tex b/chapters/execution/folder-management.tex new file mode 100644 index 0000000..213c6fb --- /dev/null +++ b/chapters/execution/folder-management.tex @@ -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} diff --git a/chapters/execution/pdf-preview.tex b/chapters/execution/pdf-preview.tex new file mode 100644 index 0000000..4b38385 --- /dev/null +++ b/chapters/execution/pdf-preview.tex @@ -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} diff --git a/chapters/execution/race-conditions.tex b/chapters/execution/race-conditions.tex new file mode 100644 index 0000000..071c8fd --- /dev/null +++ b/chapters/execution/race-conditions.tex @@ -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} diff --git a/chapters/execution/s3-client.tex b/chapters/execution/s3-client.tex new file mode 100644 index 0000000..ff7f07e --- /dev/null +++ b/chapters/execution/s3-client.tex @@ -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} diff --git a/chapters/execution/search.tex b/chapters/execution/search.tex new file mode 100644 index 0000000..31c6927 --- /dev/null +++ b/chapters/execution/search.tex @@ -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} diff --git a/chapters/execution/type-icons.tex b/chapters/execution/type-icons.tex new file mode 100644 index 0000000..a0a17e2 --- /dev/null +++ b/chapters/execution/type-icons.tex @@ -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} diff --git a/chapters/execution/url-files.tex b/chapters/execution/url-files.tex new file mode 100644 index 0000000..2d3ca93 --- /dev/null +++ b/chapters/execution/url-files.tex @@ -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} diff --git a/chapters/overview/initial-situation.tex b/chapters/overview/initial-situation.tex new file mode 100644 index 0000000..eda7156 --- /dev/null +++ b/chapters/overview/initial-situation.tex @@ -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. diff --git a/chapters/overview/participants.tex b/chapters/overview/participants.tex new file mode 100644 index 0000000..3fd5465 --- /dev/null +++ b/chapters/overview/participants.tex @@ -0,0 +1,4 @@ +\section{Beteiligte und Rollen} +\label{sec:participants} + +% TODO: Tabelle aus note-1787657238720 (Beteiligte) diff --git a/chapters/overview/project-description.tex b/chapters/overview/project-description.tex new file mode 100644 index 0000000..5f6ef68 --- /dev/null +++ b/chapters/overview/project-description.tex @@ -0,0 +1,4 @@ +\section{Projektbeschreibung} +\label{sec:project-description} + +% TODO diff --git a/chapters/overview/project-scope.tex b/chapters/overview/project-scope.tex new file mode 100644 index 0000000..eee8da3 --- /dev/null +++ b/chapters/overview/project-scope.tex @@ -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) diff --git a/chapters/overview/system-landscape.tex b/chapters/overview/system-landscape.tex new file mode 100644 index 0000000..5f8a746 --- /dev/null +++ b/chapters/overview/system-landscape.tex @@ -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} diff --git a/chapters/overview/target-situation.tex b/chapters/overview/target-situation.tex new file mode 100644 index 0000000..4b60f7e --- /dev/null +++ b/chapters/overview/target-situation.tex @@ -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 diff --git a/chapters/planning/backlog.tex b/chapters/planning/backlog.tex new file mode 100644 index 0000000..b6ecaeb --- /dev/null +++ b/chapters/planning/backlog.tex @@ -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} diff --git a/chapters/planning/feature-analysis.tex b/chapters/planning/feature-analysis.tex new file mode 100644 index 0000000..2e4b1d6 --- /dev/null +++ b/chapters/planning/feature-analysis.tex @@ -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 +% - ... diff --git a/chapters/planning/infrastructure.tex b/chapters/planning/infrastructure.tex new file mode 100644 index 0000000..8958388 --- /dev/null +++ b/chapters/planning/infrastructure.tex @@ -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} diff --git a/chapters/planning/onboarding.tex b/chapters/planning/onboarding.tex new file mode 100644 index 0000000..8c85a3b --- /dev/null +++ b/chapters/planning/onboarding.tex @@ -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 diff --git a/chapters/planning/requirements.tex b/chapters/planning/requirements.tex new file mode 100644 index 0000000..d701af1 --- /dev/null +++ b/chapters/planning/requirements.tex @@ -0,0 +1,5 @@ +\section{Anforderungserhebung} +\label{sec:requirements} + +% TODO: Funktionale und nichtfunktionale Anforderungen aus den PBI-ACs +% Tabelle: Anforderungsmatrix (funktional / nichtfunktional → PBI) diff --git a/chapters/planning/schedule.tex b/chapters/planning/schedule.tex new file mode 100644 index 0000000..29c7bd6 --- /dev/null +++ b/chapters/planning/schedule.tex @@ -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 diff --git a/chapters/qa/acceptance-testing.tex b/chapters/qa/acceptance-testing.tex new file mode 100644 index 0000000..561ff1d --- /dev/null +++ b/chapters/qa/acceptance-testing.tex @@ -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 diff --git a/chapters/qa/code-reviews.tex b/chapters/qa/code-reviews.tex new file mode 100644 index 0000000..b0680af --- /dev/null +++ b/chapters/qa/code-reviews.tex @@ -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 diff --git a/chapters/qa/releases.tex b/chapters/qa/releases.tex new file mode 100644 index 0000000..7674c5f --- /dev/null +++ b/chapters/qa/releases.tex @@ -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 diff --git a/chapters/qa/test-strategy.tex b/chapters/qa/test-strategy.tex new file mode 100644 index 0000000..2bc2dc9 --- /dev/null +++ b/chapters/qa/test-strategy.tex @@ -0,0 +1,4 @@ +\section{Teststrategie} +\label{sec:test-strategy} + +% TODO: Unit-Tests mit gemocktem IAmazonS3, Abnahmetests durch Maria-Lena Andersz diff --git a/chapters/qa/unit-tests.tex b/chapters/qa/unit-tests.tex new file mode 100644 index 0000000..f2075a1 --- /dev/null +++ b/chapters/qa/unit-tests.tex @@ -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} diff --git a/figures/diagrams/ado-workflow.mmd b/figures/diagrams/ado-workflow.mmd new file mode 100644 index 0000000..fef3165 --- /dev/null +++ b/figures/diagrams/ado-workflow.mmd @@ -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 diff --git a/figures/diagrams/auth-sequence.mmd b/figures/diagrams/auth-sequence.mmd new file mode 100644 index 0000000..a7d7dde --- /dev/null +++ b/figures/diagrams/auth-sequence.mmd @@ -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 diff --git a/figures/diagrams/gantt-plan.mmd b/figures/diagrams/gantt-plan.mmd new file mode 100644 index 0000000..076517d --- /dev/null +++ b/figures/diagrams/gantt-plan.mmd @@ -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 diff --git a/figures/diagrams/lookup-flow.mmd b/figures/diagrams/lookup-flow.mmd new file mode 100644 index 0000000..a2dd7ae --- /dev/null +++ b/figures/diagrams/lookup-flow.mmd @@ -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] diff --git a/figures/diagrams/module-components.mmd b/figures/diagrams/module-components.mmd new file mode 100644 index 0000000..22f65b0 --- /dev/null +++ b/figures/diagrams/module-components.mmd @@ -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 diff --git a/figures/diagrams/race-condition-a.mmd b/figures/diagrams/race-condition-a.mmd new file mode 100644 index 0000000..301570c --- /dev/null +++ b/figures/diagrams/race-condition-a.mmd @@ -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 diff --git a/figures/diagrams/s3-layout.mmd b/figures/diagrams/s3-layout.mmd new file mode 100644 index 0000000..47ec228 --- /dev/null +++ b/figures/diagrams/s3-layout.mmd @@ -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] diff --git a/figures/diagrams/system-context.mmd b/figures/diagrams/system-context.mmd new file mode 100644 index 0000000..095c3d8 --- /dev/null +++ b/figures/diagrams/system-context.mmd @@ -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 diff --git a/figures/diagrams/timeline-infra.mmd b/figures/diagrams/timeline-infra.mmd new file mode 100644 index 0000000..234d839 --- /dev/null +++ b/figures/diagrams/timeline-infra.mmd @@ -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 diff --git a/figures/diagrams/zip-stream.mmd b/figures/diagrams/zip-stream.mmd new file mode 100644 index 0000000..6b0af7a --- /dev/null +++ b/figures/diagrams/zip-stream.mmd @@ -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) diff --git a/figures/itc/IT-Center_Dortmund_Logo.svg.png b/figures/itc/IT-Center_Dortmund_Logo.svg.png new file mode 100644 index 0000000000000000000000000000000000000000..98efa2e169fb9a4b172d95e1253dd053bc1c73f4 GIT binary patch literal 5245 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 literal 0 HcmV?d00001 diff --git a/frontmatter/abstract.tex b/frontmatter/abstract.tex new file mode 100644 index 0000000..a8f3ea8 --- /dev/null +++ b/frontmatter/abstract.tex @@ -0,0 +1,4 @@ +% \chapter*{Kurzfassung} +% \addcontentsline{toc}{chapter}{Kurzfassung} +% TODO +% \clearpage diff --git a/frontmatter/acknowledgments.tex b/frontmatter/acknowledgments.tex new file mode 100644 index 0000000..291bc1b --- /dev/null +++ b/frontmatter/acknowledgments.tex @@ -0,0 +1,4 @@ +% \chapter*{Danksagung} +% \addcontentsline{toc}{chapter}{Danksagung} +% TODO +% \clearpage diff --git a/frontmatter/usage-of-ai.tex b/frontmatter/usage-of-ai.tex new file mode 100644 index 0000000..7df3ae2 --- /dev/null +++ b/frontmatter/usage-of-ai.tex @@ -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 diff --git a/main.tex b/main.tex new file mode 100644 index 0000000..95ba8b4 --- /dev/null +++ b/main.tex @@ -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} diff --git a/pidi-thesis.cls b/pidi-thesis.cls new file mode 100644 index 0000000..3ca30bb --- /dev/null +++ b/pidi-thesis.cls @@ -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 +} diff --git a/references.bib b/references.bib new file mode 100644 index 0000000..c55a17a --- /dev/null +++ b/references.bib @@ -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} +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..2b506e3 --- /dev/null +++ b/shell.nix @@ -0,0 +1,47 @@ +with import {}; 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" + ''; + }