feat: write template
This commit is contained in:
commit
a0a6d2cf84
98 files changed
+6609
No files matched your search
@@ -0,0 +1,20 @@
|
||||
// Doc6: Was sind die Anforderungen an eine Kurzfassung?
|
||||
//
|
||||
// 1. Die Kurzfassung ist Bestandteil von Teil 2 des IPA-Berichts.
|
||||
// 2. Es werden die Kerninformationen wiedergegeben, weder mehr noch weniger.
|
||||
// 3. Die Kurzfassung beschränkt sich auf eine A4-Seite und enthält keine Grafik.
|
||||
// 4. Die Kurzfassung weist eine klare Struktur auf und beinhaltet 3 bis 4 Kapitel.
|
||||
// 5. Die Ausrichtung auf die Zielgruppe ist gewährleistet.
|
||||
// 6. Die Kurzfassung endet sinnvoll, bspw. mit einer Schlussfolgerung oder einer
|
||||
// Empfehlung.
|
||||
// 7. Die Kurzfassung ist objektiv und verzichtet auf die Schilderung persönlicher
|
||||
// Erfahrungen.
|
||||
|
||||
|
||||
= Kurzfassung
|
||||
== Ausgangssituation
|
||||
== Umsetzung
|
||||
== Ergebnis
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": acronym
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
|
||||
= Einführung
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// Der folgende Teil klärt die Rahmenbedingungen der IPA wie die Einführung in die Firma, das Projekt und die Aufgabenstellung.
|
||||
//
|
||||
// == Die Firma
|
||||
//
|
||||
// Der Webauftritt des Bundesamtes für Informatik und Telekommunikation (#acronym("BIT", "Bundesamt für Informatik und Telekommunikation")) beschreibt das BIT Folgendermassen:
|
||||
//
|
||||
// #wrap-content(
|
||||
// box(inset: (left: 1em, bottom: 1em), width: 19em, figure(
|
||||
// image("../../02_Grafiken/placeholder.png"),
|
||||
// caption: [Campus Eichenweg 1 & 3 in Zollikofen],
|
||||
// )),
|
||||
// align: top + right,
|
||||
// )[
|
||||
//
|
||||
// #quote()[
|
||||
// Das BIT ist der grösste IT-Leistungserbringer der Bundesverwaltung.
|
||||
// Es stellt rund 50 000 Arbeitsplatzsysteme zur Verfügung, entwickelt zusammen mit den Verwaltungseinheiten massgeschneiderte,
|
||||
// sichere sowie benutzerfreundliche IT-Lösungen und betreibt über 1000 Fachanwendungen mehrheitlich in eigenen, modernen Rechenzentren.
|
||||
// ]@bit
|
||||
// ]
|
||||
//
|
||||
// == Arbeitsbereich
|
||||
//
|
||||
// Beschreibung des eigenen Arbeitsbereichs, des Teams und der bisherigen
|
||||
// Tätigkeiten im Betrieb.
|
||||
//
|
||||
// == Projekt
|
||||
//
|
||||
// Kurzbeschreibung des Projekts und Verweis auf die Aufgabenstellung.
|
||||
// Weitere Informationen können der Aufgabenstellung entnommen werden.
|
||||
@@ -0,0 +1,4 @@
|
||||
== Studie IST- und SOLL-Zustand
|
||||
|
||||
=== IST-Zustand
|
||||
=== SOLL-Zustand
|
||||
@@ -0,0 +1,62 @@
|
||||
== Ziele <chap-ziele>
|
||||
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// Dieses Kapitel beschreibt die Projektvorgehensziele sowie die Produktziele die Erfüllt werden müssen, damit das Projekt erfolgreich ist.
|
||||
//
|
||||
// === Produktziele
|
||||
// // Beispiele von Kategorien:
|
||||
// // • Finanzziele, Kosten/Nutzen/Wirtschaftlichkeit
|
||||
// // • Leistung, Effizienz, Durchlaufzeit
|
||||
// // • Qualität, Fehlerreduktion
|
||||
// // • Kunden-/ Anwenderzufriedenheit, Service Public
|
||||
// // • Sicherheit, Zuverlässigkeit
|
||||
// // • Rechtliche Konformität
|
||||
// // • Flexibilität
|
||||
// // • Ausbaubarkeit
|
||||
// // • Wartbarkeit
|
||||
// // • Nachhaltigkeit
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, 1fr, auto),
|
||||
// [Nr.], [Ziel ], [Messgrösse], [Gewicht \ (M/S/K) #footnote[M = Muss, S = Soll, K = Kann]],
|
||||
//
|
||||
// [1], [Bsp.], [ Bsp.], [M],
|
||||
// ),
|
||||
// caption: [Projektvorgehensziele],
|
||||
// )
|
||||
//
|
||||
// === Projektvorgehensziele
|
||||
// // Beispiele von Kategorien:
|
||||
// // • Projektkosten (Budget)
|
||||
// // • Termine
|
||||
// // • Meilensteine
|
||||
// // • Methodik
|
||||
// // • Kommunikation
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, 1fr, auto),
|
||||
// [Nr.], [Projektziel], [Messgrösse], [Gewicht \ (M/S/K)],
|
||||
//
|
||||
// //--- Projektkosten ---
|
||||
// [1],
|
||||
// [Das Projekt bleibt innerhalb des vorgegebenen Zeitbudgets der Probe-IPA.],
|
||||
// [Es werden maximal 90h für das Projekt aufgewendet.],
|
||||
// [M],
|
||||
//
|
||||
// // --- Meilensteine ---
|
||||
// [2],
|
||||
// [Alle definierten Meilensteine werden Eingehalten.],
|
||||
// [Die Meilensteine (Beschrieben in @chap-zeitplan) werden erreicht.],
|
||||
// [M],
|
||||
//
|
||||
// // --- Methodik ---
|
||||
// [3],
|
||||
// [Das Projekt wird nach der Projektdurführungsmethode in @chap-projektmethode durchgeführt.],
|
||||
// [Das Projekt wird nach der Projektdurführungsmethode in @chap-projektmethode durchgeführt.],
|
||||
// [S],
|
||||
// ),
|
||||
// caption: [Projektvorgehensziele],
|
||||
// )
|
||||
@@ -0,0 +1,21 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": requirements
|
||||
== Anforderungen
|
||||
|
||||
#lorem(200)
|
||||
|
||||
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (2.5em, 1fr, 2.5em, 1fr, auto, auto),
|
||||
// [ID],
|
||||
// [Anforderung],
|
||||
// [Art #footnote[Art = Anforderungsart: F = Funktional, Q = Qualität]],
|
||||
// [Abnahmekriterium],
|
||||
// [W#footnote[ Wichtigkeit: 5 = muss zwingend umgesetzt werden; 4 = sehr wichtig, 3 = wichtig, 2 = normal, 1 = nicht wichtig]],
|
||||
// [D#footnote[ Dringlichkeit: 5 = muss sofort umgesetzt werden, 4 = sehr dringend, 3 = dringend, 2 = normal, 1 = nicht dringend]],
|
||||
//
|
||||
// requirements.id(), [Titel], [F], [Beschreibung], [5], [5],
|
||||
// ),
|
||||
//
|
||||
// caption: [Anforderungen],
|
||||
// )
|
||||
@@ -0,0 +1,57 @@
|
||||
== Lösungsvarianten
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// In diesem Kapitel werden zwei Varianten zur Umsetzung der Applikation
|
||||
// analysiert und bewertet. Anschliessend wird mit Hilfe dieser Informationen
|
||||
// die beste Variante für die Umsetzung gewählt.
|
||||
//
|
||||
// === Variante 1: <variante-1>
|
||||
//
|
||||
// Beschreibung der ersten Lösungsvariante.
|
||||
//
|
||||
// === Variante 2: <variante-2>
|
||||
//
|
||||
// Beschreibung der zweiten Lösungsvariante.
|
||||
//
|
||||
// === Bewertung der Varianten
|
||||
//
|
||||
// Beim Bewerten der Varianten werden folgende Kriterien beachtet:
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, auto),
|
||||
// [Name], [Begründung], [Gewichtung],
|
||||
// [Kriterium 1], [Begründung für das Kriterium.], [1],
|
||||
// [Kriterium 2], [Begründung für das Kriterium.], [1],
|
||||
// [Kriterium 3], [Begründung für das Kriterium.], [1],
|
||||
// ),
|
||||
// caption: [Übersicht der Bewertungskriterien für den Variantenentscheid],
|
||||
// )
|
||||
//
|
||||
// ==== Variante 1
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, auto, auto, 1fr),
|
||||
// [Kriterium], [Bewertung \ x/10], [Gewich-\ tung], [Begründung],
|
||||
// [Kriterium 1], [8], [1], [Begründung der Bewertung.],
|
||||
// table.footer([Summe:], [8]),
|
||||
// ),
|
||||
// caption: [Auswertung der Variante 1],
|
||||
// )
|
||||
//
|
||||
// ==== Variante 2
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, auto, auto, 1fr),
|
||||
// [Kriterium], [Bewertung \ x/10], [Gewich-\ tung], [Begründung],
|
||||
// [Kriterium 1], [7], [1], [Begründung der Bewertung.],
|
||||
// table.footer([Summe:], [7]),
|
||||
// ),
|
||||
// caption: [Auswertung der Variante 2],
|
||||
// )
|
||||
//
|
||||
// === Variantenentscheid <variantenentscheid>
|
||||
//
|
||||
// Die Applikation wird mit #link(<variante-1>, [Variante 1]) umgesetzt,
|
||||
// da die Bewertung im Vergleich zu #link(<variante-2>, [Variante 2]) höher ausfällt.
|
||||
@@ -0,0 +1,78 @@
|
||||
== Schutzbedarfsanalyse
|
||||
//
|
||||
// Die Schutzbedarfsanalyse dient dazu,
|
||||
// den notwendigen Umfang an Sicherheitsmassnahmen zu bestimmen.
|
||||
// Sie stellt sicher, dass die Vertraulichkeit, Integrität und Verfügbarkeit der Applikationen und der Daten gewährleistet werden.
|
||||
// Sie basiert auf der "IKT Beurteilung des Schutzbedarfs". @schutzbedarf
|
||||
//
|
||||
// Anfang 2025 wurde eine neue Version (5.1) dieser Beurteilung erstellt.
|
||||
// Diese ist in den zehn verfügbaren Tagen der IPA zu umfangreich.
|
||||
// Deshalb kann für diese IPA die alte Version (4.6) der Schutzbedarfsanalyse verwendet werden. @alte-schutzbedarfsanalyse
|
||||
//
|
||||
// === Einstufung
|
||||
//
|
||||
// Wird in der Einstufung erhöter Schutzbedarf festgestellt, so muss ein ISDS-Konzept erarbeitet werden.
|
||||
// Erhöter Schutzbedarf liegt vor, sobald eines der Felder
|
||||
// aus dem Bereich der Vertraulichkeit als #text(fill: red, "rot") gekennzeichnet wird
|
||||
// oder wenn mehr als zwei Kriterien in den Bereichen Verfügbarkeit, Integrität oder Nachvollziehbarkeit als #text(fill: red, "rot") gekennzeichnet werden.
|
||||
//
|
||||
// Folgende Tabelle ist ein Auszug aus der Einstufung mithilfe des vorgegebenen Dokuments.
|
||||
// Die gesamte Einstufung ist im Anhang ersichtlich.
|
||||
//
|
||||
// #let good(c) = { table.cell(fill: green.lighten(70%), c) }
|
||||
// #let bad(c) = { table.cell(fill: red.lighten(70%), c) }
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: 3,
|
||||
// table.header([Kategorie], [Frage], [Antwort]),
|
||||
//
|
||||
// table.cell(rowspan: 3, [Vertraulichkeit]),
|
||||
// [Sollen [mit diesem Schutzobjekt] Personendaten nach der Datenschutzgesetzgebung bearbeitet werden? Wenn ja, ergibt sich daraus ein hohes Risiko für die Grundrechte der betroffenen Personen?],
|
||||
// good([Keine Personendaten]),
|
||||
//
|
||||
// // [Vertraulichkeit],
|
||||
// [Sollen [mit diesem Schutzobjekt] klassifizierte Informationen nach der Informationsschutzverordnung (ISchV) bearbeitet werden? Wenn ja, Informationen aus welchen Klassifizierungsstufen (vgl. Art. 5 bis 7 ISchV) sind betroffen?],
|
||||
// good([Klassifizierung: Intern]),
|
||||
//
|
||||
// // [Vertraulichkeit],
|
||||
// [Sollen [mit diesem Schutzobjekt] Informationen oder Daten bearbeitet werden, die aus einem sonstigen Grund (spezielle Gesetzgebungen) besonders geschützt werden müssen? Wenn ja, wie hoch sind die Schutzanforderungen?],
|
||||
// good([Keine erhöhten Anforderungen an die Vertraulichkeit]),
|
||||
//
|
||||
// table.cell(rowspan: 3, [Verfügbarkeit]),
|
||||
// [Max. zulässige Ausfalldauer?],
|
||||
// good([Ausfalldauer max. 8 Std.]),
|
||||
//
|
||||
// // [Verfügbarkeit],
|
||||
// [Servicezeiten?],
|
||||
// good([Servicezeiten Standard (11/5)]),
|
||||
//
|
||||
// // [Verfügbarkeit],
|
||||
// [IT Service Continuity Management (ITSCM) relevant [für dieses Schutzobjekt] als Teil des Business Continuity Management (BCM) für geschäftskritische Prozesse?],
|
||||
// good([ITSCM / BCM nicht notwendig]),
|
||||
//
|
||||
// table.cell(rowspan: 2, [Integrität]),
|
||||
// [Muss die Echtheit, Korrektheit und/oder Unversehrtheit der Daten nachgewiesen werden können?],
|
||||
// good([Keine speziellen Anforderungen]),
|
||||
//
|
||||
// // [Integrität],
|
||||
// [Müssen bestimmte Arbeitsvorgänge nachgewiesen werden können?],
|
||||
// good([Keine speziellen Anforderungen]),
|
||||
//
|
||||
// [RINA-Relevanz],
|
||||
// [Ist dieses Schutzobjekt durch nachrichtendienstliche Ausspähung (oder ähnliche) erheblich gefährdet und/oder werden dafür sensitive Beschaffungen notwendig?],
|
||||
// good([Nein - Nicht RINA-relevant]),
|
||||
// ),
|
||||
// caption: [Einstufung Schutzbedarf],
|
||||
// )
|
||||
//
|
||||
// Die Kommentare zu den jeweiligen Kategorien sind im Anhang ersichtlich.
|
||||
//
|
||||
// === Entscheid ISDS-Konzept
|
||||
//
|
||||
// In der Einstufung wurden keine erhöhten Anforderungen festgestellt.
|
||||
// Da alle Felder grün sind, ist das Ergebnis der Schutzbedarfsanalyse "kein erhöter Schutzbedarf notwendig" und es muss kein ISDS-Konzept erstellt werden.
|
||||
//
|
||||
// === Massnahmen
|
||||
//
|
||||
//
|
||||
@@ -0,0 +1,58 @@
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
#import "@local/chfoit-ipa:0.0.0": palette
|
||||
|
||||
#let risiko(lvl) = {
|
||||
if lvl >= 3 {
|
||||
return table.cell(fill: palette.red.at("300"))[Sehr Hoch]
|
||||
}
|
||||
if lvl >= 2 {
|
||||
return table.cell(fill: palette.orange.at("300"))[Hoch]
|
||||
}
|
||||
if lvl >= 1 {
|
||||
return table.cell(fill: palette.yellow.at("300"))[Mittel]
|
||||
}
|
||||
return table.cell(fill: palette.green.at("300"))[Tief]
|
||||
}
|
||||
|
||||
== Risiko Analyse
|
||||
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// === Risiken
|
||||
//
|
||||
// Folgende Risiken sind in der Probe-IPA relevant:
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, 1fr, auto, auto),
|
||||
// [Nr.], [Beschreibung], [Auswirkung], [E #footnote[Eintretenswahrscheinlichkeit]], [A #footnote[Auswirkungsgrad]],
|
||||
//
|
||||
// // [1], [Ausfall vom Arbeitsgerät], [Entwicklung nicht mehr möglich], risiko(0), risiko(3),
|
||||
// ),
|
||||
// caption: [Risiken],
|
||||
// )<fig-risks>
|
||||
//
|
||||
// Um diese Risiken zu mindern, werden Folgende Massnahmen ergriffen:
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, auto, 1fr, auto, auto),
|
||||
// [Nr.], [Risiko Nr.], [Beschreibung], [E Danach], [A Danach],
|
||||
//
|
||||
// // [1], [1], [Ausweichen auf Warp-Devspaces], risiko(0), risiko(1),
|
||||
// ),
|
||||
// caption: [Massnahmen um Risiken zu mindern],
|
||||
// )
|
||||
// === Auswertung
|
||||
//
|
||||
// #wrap-content(
|
||||
// figure(
|
||||
// image("../../../02_Grafiken/risiko_matrix.pdf"),
|
||||
// caption: [Risikomatrix],
|
||||
// ),
|
||||
// [
|
||||
//
|
||||
// ],
|
||||
// align: top + right,
|
||||
// column-gutter: 2em,
|
||||
// )
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
#pagebreak(weak: true)
|
||||
== Projektauftrag
|
||||
|
||||
|
||||
// Bei justin steht:
|
||||
|
||||
Basierend auf den Erkenntnissen der Studie und den Variantenentscheiden wird das Projekt in
|
||||
die nächste Phase übergeben.
|
||||
|
||||
_Das Projekt wurde am \<datum> durch den Auftraggeber \<Auftraggeber> mündlich
|
||||
freigegeben._
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Auf der Grundlage des Projektinitialisierungsauftrags gibt der Auftraggeber die Ressourcen für die Phase Initialisierung frei.
|
||||
// Er beauftragt den Projektleiter mit der Durchführung der Phase Initialisierung.
|
||||
//
|
||||
// Die Phase Initialisierung wird aus Projektmanagementsicht stets klassisch abgewickelt.
|
||||
// Dennoch können auch agile Werkzeuge zum Einsatz kommen.
|
||||
//
|
||||
// Die Studie wird erarbeitet.
|
||||
// - Die Arbeiten starten mit einer ersten Standortbestimmung, Zielen und groben Anforderungen.
|
||||
// - Die Lösungsvarianten werden erarbeitet. Die Beschreibung der Lösungsvarianten erfolgt so detailliert,
|
||||
// dass sie nachvollziehbar und transparent bewertet werden können.
|
||||
// - Unter anderem werden auch die Projekt- und Betriebsrisiken ermittelt.
|
||||
// - Parallel zur Studie werden die Rechtsgrundlagenanalyse und die Schutzbedarfsanalyse
|
||||
// erarbeitet und in die Entscheidung einbezogen.
|
||||
// - Zusätzlich wird festgelegt und nachvollziehbar dokumentiert, wie im Rahmen jeder Lösungsvariante
|
||||
// weiter vorgegangen wird: entweder klassisch oder agil.
|
||||
// - Der Entscheid Weiteres Vorgehen wird getroffen.
|
||||
//
|
||||
// Für die allfällige Beschaffung eines Produkts bzw. eines Systems wird parallel
|
||||
// zur Studie eine Beschaffungsanalyse durchgeführt.
|
||||
//
|
||||
// Das für die Lösungsentstehung passende Szenario wird ausgewählt und bei Bedarf individualisiert.
|
||||
//
|
||||
// Auf der Basis der gewählten Variante und des Vorgehens werden der Projektmanagementplan
|
||||
// und der Durchführungsauftrag erarbeitet und mit den Strategien, Vorgaben und übergeordneten
|
||||
// Zielen der Stammorganisation abgeglichen. Die Stakeholderinteressen werden
|
||||
// analysiert und Zielkonflikte bereinigt.
|
||||
//
|
||||
// Bei anvisierter agiler Vorgehensweise wird festgelegt, ob der optionale Entscheid
|
||||
// Releasefreigabe treffen im Projekt als erforderlich vorgeschrieben ist.
|
||||
//
|
||||
// Der Entscheid Durchführungsfreigabe wird getroffen und der Durchführungsauftrag unterschrieben.
|
||||
// Die Freigabe erfolgt durch die Stammorganisation und den Auftraggeber.
|
||||
|
||||
= Initialisierung
|
||||
|
||||
In diesem Kapitel sind die Arbeitsergebnisse der Initialisierungsphase.
|
||||
|
||||
#include "./01_Studie.typ"
|
||||
#include "./02_Ziele.typ"
|
||||
#include "./03_Anforderungen.typ"
|
||||
#include "./04_Varianten.typ"
|
||||
#include "./05_Schutzbedarfsanalyse.typ"
|
||||
#include "./06_Risikoanalyse.typ"
|
||||
#include "./07_Projektauftrag.typ"
|
||||
@@ -0,0 +1,23 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": usecase
|
||||
|
||||
== Anwendungsfälle
|
||||
|
||||
// Zweck: Er dient dazu, funktionale Anforderungen aus der Perspektive des Nutzers zu definieren und sicherzustellen,
|
||||
// dass das System die Erwartungen der Stakeholder erfült.
|
||||
// Bestandteile: Ein Anwendungsfall besteht in der Regel aus einer:
|
||||
// - Spezifikation (textliche Beschreibung der Schritte)
|
||||
// - und einem Diagramm (grafische Übersicht der Akteure und Beziehungen).
|
||||
// Abgrenzung: Im Gegensatz zu einer User Story, die nur kurz den Nutzerwunsch beschreibt,
|
||||
// geht ein Use Case detailliert auf Abläufe, Vorbedingungen und Fehlerfälle ein.
|
||||
#usecase(
|
||||
name: "Beispiel",
|
||||
actors: ("a", "b", "c"),
|
||||
diagramm: [basdhf dsfsadfh],
|
||||
precondition: [bsp.],
|
||||
process: [
|
||||
bsp.
|
||||
],
|
||||
acceptanceCriteria: (
|
||||
"bla bla bla",
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
Die Benutzerschnittstelle besteht aus den folgenden Seiten:
|
||||
|
||||
// This template can be used to generate new Mockups.
|
||||
= Template
|
||||
|
||||
Das Template kann benützt werden um die wichtigsten Elemente bereits zur Verfügung zu haben.
|
||||
|
||||
#figure(
|
||||
image("../../../02_Grafiken/mockup_template.pdf"),
|
||||
caption: [Template für Mockups],
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
#import "@local/chfoit-ipa:0.0.0": acronym, term
|
||||
|
||||
#pagebreak(weak: true)
|
||||
== Anwendungsarchitektur
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// #figure(
|
||||
// image("../../../02_Grafiken/placeholder.png", height: 25em),
|
||||
// caption: [Architekturskizze],
|
||||
// )<fig-architekturskizze>
|
||||
//
|
||||
// === Technologien
|
||||
//
|
||||
// ==== Frontend
|
||||
// #wrap-content(
|
||||
// figure(
|
||||
// image("../../../02_Grafiken/frontend_logo.png", height: 4em),
|
||||
// caption: [Frontend-Technologie],
|
||||
// ),
|
||||
// [
|
||||
// // Beschreibung der Frontend-Technologien.
|
||||
// ],
|
||||
// align: top + right,
|
||||
// column-gutter: 2em,
|
||||
// )
|
||||
//
|
||||
// ==== Backend
|
||||
// #wrap-content(
|
||||
// figure(
|
||||
// image("../../../02_Grafiken/backend_logo.png", height: 4em),
|
||||
// caption: [Backend-Technologie],
|
||||
// ),
|
||||
// [
|
||||
// // Beschreibung der Backend-Technologien.
|
||||
// ],
|
||||
// align: top + right,
|
||||
// column-gutter: 2em,
|
||||
// )
|
||||
//
|
||||
// === Datenbank
|
||||
//
|
||||
// #wrap-content(
|
||||
// figure(
|
||||
// image("../../../02_Grafiken/db_logo.png", height: 4em),
|
||||
// caption: [Datenbank-Technologie],
|
||||
// ),
|
||||
// [
|
||||
// // Beschreibung der Datenbank-Technologien.
|
||||
// ],
|
||||
// align: top + right,
|
||||
// column-gutter: 2em,
|
||||
// )
|
||||
@@ -0,0 +1,11 @@
|
||||
== Rollenkonzept
|
||||
|
||||
#figure(
|
||||
image("../../../02_Grafiken/placeholder.png", width: 80%),
|
||||
|
||||
caption: [Rollen- und Zugriffdiagram],
|
||||
) <fig-rolle_diagram>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
== Daten Schema
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// #figure(
|
||||
// image("../../../02_Grafiken/placeholder.png", width: 80%),
|
||||
// caption: [Datenbankdiagramm],
|
||||
// )<fig-datenbankdiagramm>
|
||||
@@ -0,0 +1,8 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": oasviz
|
||||
== API Spezifikation
|
||||
|
||||
#{
|
||||
set heading(offset: 2)
|
||||
oasviz.render(yaml("swagger.yaml"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": term, test
|
||||
|
||||
== Testkonzept
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// Das Testkonzept beschreibt die Testziele, Testobjekte, Testarten, Testinfrastruktur sowie Testorganisation. Es umfasst ebenfalls die Testplanung und die Testfallbeschreibungen. Für jeden Testfall wird eine detaillierte Testfallbeschreibung erstellt. Diese stellt die Spezifikati-on des Tests dar. Die Testplanung legt den logischen und zeitlichen Ablauf der Tests fest. Das Testkonzept bildet die Grundlage, auf der die Testorganisation und die Testinfrastruktur bereitgestellt und die Tests durchgeführt werden. Tauchen neue Erkenntnisse auf, wird das Testkonzept nachgeführt. @hermes-online
|
||||
//
|
||||
// === Testziele
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, 1fr, auto),
|
||||
// [Nr.], [Beschreibung], [Messgrösse], [Priorität #footnote[Priorität: M = Muss / 1 = hoch, 2 = mittel, 3 = tief]],
|
||||
// [01], [Benutzeroberflächentest Erfolgreich], [Anwendungsfälle reproduzierbar], [M],
|
||||
// [02], [Businesslogiktest Erfolgreich], [Datenprüfung korrekt], [1],
|
||||
// ),
|
||||
// )
|
||||
//
|
||||
//
|
||||
// === Teststrategien und Teststufen
|
||||
//
|
||||
// Im rahmen der Probe-IPA werden hauptsächlich
|
||||
// #term("Unit-Test", "Tests die als Code geschrieben werden und es zum Ziel haben einen einzelnen Komponenten (Unit) zu testen.")s und
|
||||
// #term("Akzeptanz-Test", "Testverfahren mit dem Hauptzweck die Funktionalität einer Software aus der Sicht des Endbenutzers zu überprüfen.")s
|
||||
// durchgeführt.
|
||||
//
|
||||
// Die Unit-Tests haben zum ziel die einzelnen Komponente zu testen. Dabei wird eine Fokus auf die Geschäftslogik gelegt.
|
||||
// Im Frontend sowie im Backend #term("Backend", "Die Komponente der Applikation, die auf dem Server läuft und dem Frontend die Daten zur verfügung stellt und die eingaben des Frontends prüft.")
|
||||
// ist die #term("Testabdeckung", "Verhältniss von Codedezeilen die existieren zu Codedezeilen die wärend dem Testen durchlaufen wurden.") mindestens *60%*.
|
||||
//
|
||||
// Die Akzeptanz-Tests haben zum Ziel, die gesamte Applikation zu testen. Sie werden am ende der Umsetzungsphase manuell getestet um diese abzuschliessen.
|
||||
// Um die Umsetzungsphase abzuschliessen müssen alle Akzeptanz-Test funktionieren.
|
||||
//
|
||||
// === Mängelklassifizierung
|
||||
//
|
||||
// Die festgestellten Mängel, bzw. die nicht erfüllten Anforderungen (Erwartungen), werden in Klassen von 1 bis 4 eingestuft.
|
||||
// Die Klasse 0 findet nur dann Verwendung, wenn ein einwand-freies Ergebnis gesondert ausgewiesen werden soll:
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, auto, 1fr),
|
||||
// [Nr.], [Mängelklassen], [Beschreibung],
|
||||
// text(fill: green)[0],
|
||||
// text(fill: green)[mängelfrei],
|
||||
// [Einwandfrei und
|
||||
// anforderungsgerecht],
|
||||
//
|
||||
// [1],
|
||||
// [belangloser Mangel],
|
||||
// [Verwendung möglich, Brauchbarkeit
|
||||
// ist vorhanden, Mängel sollte dennoch nicht vorkommen],
|
||||
//
|
||||
// [2],
|
||||
// [leichter Mangel],
|
||||
// [Verwendung möglich, Brauchbarkeit
|
||||
// ist nur wenig beeinträchtigt],
|
||||
//
|
||||
// [3],
|
||||
// [schwerer Mangel],
|
||||
// [Verwendung ist noch möglich,
|
||||
// Brauchbarkeit ist stark verringert],
|
||||
//
|
||||
// text(fill: red)[4],
|
||||
// text(fill: red)[kritischer Mangel],
|
||||
// [
|
||||
// Unbrauchbar; \
|
||||
//
|
||||
// Wesentliche Funktionalität ist nicht gegeben; \
|
||||
//
|
||||
// Betrieb ist nicht verantwortbar (z.B. sicherheitsspezifisch)
|
||||
// ],
|
||||
// ),
|
||||
// caption: [Mängelklassen],
|
||||
// )
|
||||
//
|
||||
// Die Klassifizierung spiegelt die Folgenschwere und den Aufwand zur Behebung der möglich feststellbaren Mängel. Die Zuordnung der festgestellten Mängel zu einer Mängelklasse gibt
|
||||
// grob auch die Priorität vor, in welcher Reihenfolge die Behebung der Mängel angegangen werden soll.
|
||||
//
|
||||
// Wird eine Mängelklasse zwischen 1-3 erreicht, kann das System/Produkt unter Vorbehalt abgenommen werden. Zur Behebung der Mängel sind jedoch Massnahmen zu definieren. Eine Nachprüfung ist zwingend.
|
||||
//
|
||||
// Werden hingegen Mängel der Klasse 4 festgestellt, kann das System/Produkt nicht abge-nommen werden und der Auftragnehmer muss umgehend Massnahmen treffen, um diese Mängel zu beheben.
|
||||
// Der Auftragnehmer hat zudem die erneute Abnahme zu veranlassen.
|
||||
// @hermes-online
|
||||
//
|
||||
//
|
||||
=== Testfälle
|
||||
|
||||
Die Testfälle sind auf Grund der Anwendungsfälle beschrieben. Es wird vorausgesetzt, dass jeweils die Passenden Daten schon vorliegen.
|
||||
Die hier aufgeführten Testfälle begrenzen sich auf die Akzeptanz-Tests. Die unit tests werden im code definiert.
|
||||
|
||||
|
||||
|
||||
#test.case(
|
||||
requirement: [Usecase 1],
|
||||
description: [Foo Bar],
|
||||
precondition: [
|
||||
- bla bla
|
||||
],
|
||||
steps: [
|
||||
],
|
||||
result: [
|
||||
],
|
||||
)
|
||||
|
||||
// === Beurteilung zur Testabdeckung
|
||||
//
|
||||
// Die Testabdeckung bei den Unit-Tests ist gut angesetzt. 60% ist viel und trotz dem realistisch.
|
||||
// Hingegen die Akzeptanz-Tests haben nur Testfälle zum "Happy Case". Das währe in einer Grösseren und Kritischeren
|
||||
// Applikation sicherlich ungünstig. Im Rahmen der Probe-IPA ist dies aber in Ordnung, da auch auf die Zeitlichen Ressourcen geachtet
|
||||
// werden muss. Mehr Akzeptanz-Tests würden den Zeitrahmen sprengen.
|
||||
//
|
||||
// === Testorganisation und Zuständigkeiten
|
||||
//
|
||||
// Die Tests finden auf dem Entwickler gerät statt jeweils auf dem sauberen #footnote[sauber im sinne von keine Änderung seit dem letzten commit] Entwicklungsbranch statt.
|
||||
//
|
||||
// Die tests werden vom Kandidaten selbst durchgeführt und Protokolliert.
|
||||
@@ -0,0 +1,10 @@
|
||||
== Phasenfreigabe
|
||||
|
||||
// Bei justin steht:
|
||||
//
|
||||
Basierend auf den Erkenntnissen wird das Projekt in
|
||||
die nächste Phase übergeben.
|
||||
|
||||
_Die Phase wurde am \<datum> durch den Auftraggeber \<name> mündlich
|
||||
freigegeben._
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Die in der Phase Initialisierung gewählte Variante wird konkretisiert. Die Ergebnisse werden so detailliert
|
||||
// erarbeitet, dass die Projektbeteiligten die Lösung auf einer verlässlichen Grundlage
|
||||
// planen, offerieren und realisieren können.
|
||||
|
||||
= Konzept
|
||||
// In diesem Kapitel, wird die in der Initialisierung gewählte Variante konkretisiert.
|
||||
// Die Ergebnisse werden so detailliert erarbeitet, dass alle Projektbeteiligten die
|
||||
// Lösung auf einer verlässlichen Grundlage planen, offerieren und realisieren können.
|
||||
//
|
||||
// Hierzu werden zunächst die Use Cases und Mockups zur Definition der Anforderungen erarbeitet.
|
||||
// Darauf aufbauend werden die technische Architektur, das Rollenkonzept sowie das Datenschema und die API-Spezifikationen festgelegt.
|
||||
// Ausserdem, wird ein Testkonzept zur Sicherstellung der einhaltung des eben genannten erarbeitet.
|
||||
|
||||
#include "./01_Usecases.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./02_Mockups.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./03_Architektur.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./04_Rollenkonzept.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./05_Datenschema.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./06_APISpec.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./07_Testkonzept.typ"
|
||||
|
||||
#pagebreak(weak: true)
|
||||
#include "./08_Phasenfreigabe.typ"
|
||||
|
||||
|
||||
@@ -0,0 +1,630 @@
|
||||
# yaml-language-server: $schema=https://raw.githubusercontent.com/OAI/OpenAPI-Specification/refs/heads/main/_archive_/schemas/v3.0/schema.yaml
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: Example App Backend API
|
||||
version: "1.0.0"
|
||||
description: API for the Example App backend service.
|
||||
servers:
|
||||
- url: http://localhost:8080
|
||||
description: Local development server
|
||||
components:
|
||||
securitySchemes:
|
||||
cookieAuth:
|
||||
type: apiKey
|
||||
in: cookie
|
||||
name: auth
|
||||
description: Cookie-based authentication
|
||||
schemas:
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
description: Categorization of the error for programmatic handling.
|
||||
enum:
|
||||
- AUTHENTICATION_ERROR
|
||||
- AUTHORIZATION_ERROR
|
||||
- VALIDATION_ERROR
|
||||
- BAD_REQUEST_ERROR
|
||||
- NOT_FOUND_ERROR
|
||||
- SERVER_ERROR
|
||||
- UNKNOWN_ERROR
|
||||
example: AUTHENTICATION_ERROR
|
||||
key:
|
||||
description: A unique error code or identifier for specific error cases.
|
||||
type: string
|
||||
maxLength: 200
|
||||
example: example key
|
||||
message:
|
||||
type: string
|
||||
description: A human-readable message explaining the error.
|
||||
maxLength: 200
|
||||
example: example message
|
||||
details:
|
||||
type: object
|
||||
description: Additional context or metadata regarding the error (e.g.,
|
||||
specific field validation failures).
|
||||
x-go-type-skip-optional-pointer: true
|
||||
x-go-type: any
|
||||
additionalProperties: true
|
||||
example: {}
|
||||
required:
|
||||
- type
|
||||
- key
|
||||
- message
|
||||
description: Schema representing Error.
|
||||
example: {}
|
||||
UUID:
|
||||
type: string
|
||||
format: uuid
|
||||
x-go-type: uuid.UUID
|
||||
x-go-type-import:
|
||||
path: github.com/google/uuid
|
||||
name: uuid
|
||||
description: Schema representing UUID.
|
||||
example: example
|
||||
User:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: Id of the user.
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/UUID"
|
||||
name:
|
||||
type: string
|
||||
description: Full name or display name of the user.
|
||||
example: "Example User"
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
description: Schema representing User.
|
||||
example: {}
|
||||
Claims:
|
||||
type: object
|
||||
properties:
|
||||
iss:
|
||||
type: string
|
||||
description: The issuer of the token.
|
||||
example: "example-app-backend"
|
||||
sub:
|
||||
description: The subject of the token (User ID).
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/UUID"
|
||||
iat:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Issued At timestamp (Unix epoch).
|
||||
example: 1
|
||||
exp:
|
||||
type: integer
|
||||
format: int64
|
||||
description: Expiration timestamp (Unix epoch).
|
||||
example: 1
|
||||
required:
|
||||
- iss
|
||||
- sub
|
||||
- iat
|
||||
- exp
|
||||
|
||||
description: Schema representing Claims.
|
||||
example: {}
|
||||
Scan:
|
||||
type: object
|
||||
properties:
|
||||
isbn:
|
||||
type: string
|
||||
x-go-name: ISBN
|
||||
description: The International Standard Book Number.
|
||||
example: 978-3-16-148410-0
|
||||
required:
|
||||
- isbn
|
||||
|
||||
description: Schema representing Scan.
|
||||
example: {}
|
||||
Book:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: User facing id of the book.
|
||||
example: 1
|
||||
title:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 200
|
||||
description: The title of the book.
|
||||
example: example title
|
||||
authors:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 500
|
||||
description: A comma-separated list or string of book authors.
|
||||
example: example authors
|
||||
description:
|
||||
type: string
|
||||
minLength: 0
|
||||
maxLength: 2048
|
||||
description: A brief summary or synopsis of the book.
|
||||
example: example description
|
||||
lentBy:
|
||||
description: The user who has lent the book from the library.
|
||||
Undefined if the boook is not lent.
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/User"
|
||||
coverUrl:
|
||||
type: string
|
||||
format: url
|
||||
description: Link to the book's cover image.
|
||||
example: example cover_url
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- authors
|
||||
|
||||
description: Schema representing Book.
|
||||
example: {}
|
||||
BookDetails:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/Book"
|
||||
- type: object
|
||||
properties:
|
||||
isbn:
|
||||
type: string
|
||||
x-go-name: ISBN
|
||||
minLength: 9
|
||||
maxLength: 20
|
||||
description: The ISBN of the book.
|
||||
example: example isbn
|
||||
publisher:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 200
|
||||
description: The entity that published the book.
|
||||
example: example publisher
|
||||
publishedAt:
|
||||
type: integer
|
||||
multipleOf: 1
|
||||
minimum: 0
|
||||
description: The publication year or timestamp.
|
||||
example: 1
|
||||
owner:
|
||||
description: The user who owns the bool. Undefined if the boook is
|
||||
public.
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/User"
|
||||
required:
|
||||
- isbn
|
||||
- publisher
|
||||
- publishedAt
|
||||
example: {}
|
||||
description: Schema representing BookDetails.
|
||||
BookRequest:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 200
|
||||
description: "The title of the book. (ctx: schema.BookRequest.properties.title)"
|
||||
example: example title
|
||||
authors:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 500
|
||||
description: "A comma-separated list or string of book authors. (ctx: schema.BookRequest.properties.authors)"
|
||||
example: example authors
|
||||
isbn:
|
||||
type: string
|
||||
x-go-name: ISBN
|
||||
minLength: 9
|
||||
maxLength: 20
|
||||
description: "The ISBN of the book. (ctx: schema.BookRequest.properties.isbn)"
|
||||
example: example isbn
|
||||
description:
|
||||
type: string
|
||||
minLength: 0
|
||||
maxLength: 2048
|
||||
description: "A brief summary or synopsis of the book. (ctx: schema.BookRequest.properties.description)"
|
||||
example: example description
|
||||
publisher:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 200
|
||||
description: "The entity that published the book. (ctx: schema.BookRequest.properties.publisher)"
|
||||
example: example publisher
|
||||
publishedAt:
|
||||
type: integer
|
||||
multipleOf: 1
|
||||
minimum: 0
|
||||
description: "The publication year or timestamp. (ctx: schema.BookRequest.properties.publishedAt)"
|
||||
example: 1
|
||||
public:
|
||||
type: boolean
|
||||
description: Whether the book is publicly owened or owned by the
|
||||
creating user.
|
||||
|
||||
example: true
|
||||
coverUrl:
|
||||
type: string
|
||||
format: url
|
||||
minLength: 0
|
||||
maxLength: 1024
|
||||
description: "Link to the book's cover image. (ctx: schema.BookRequest.properties.coverUrl)"
|
||||
example: example cover_url
|
||||
required:
|
||||
- title
|
||||
- authors
|
||||
- isbn
|
||||
- publisher
|
||||
- publishedAt
|
||||
- public
|
||||
|
||||
description: Schema representing BookRequest.
|
||||
example: {}
|
||||
Lending:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
description: The uuid of the user, who has lent the book
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/UUID"
|
||||
startedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The ID of the user borrowing the book.
|
||||
example: example startedAt
|
||||
returnedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Timestamp when the book was returned. Undefined if still
|
||||
out.
|
||||
example: example returnedAt
|
||||
required:
|
||||
- user
|
||||
- startedAt
|
||||
|
||||
description: Schema representing Lending.
|
||||
example: {}
|
||||
responses:
|
||||
Error400:
|
||||
description: Bad request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
Error401:
|
||||
description: Unauthorized – missing or invalid auth cookie
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
Error403:
|
||||
description: Forbidden – this is probably not your book
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
Error404:
|
||||
description: Not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
Error500:
|
||||
description: Server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
security:
|
||||
- cookieAuth: []
|
||||
|
||||
paths:
|
||||
/auth/login:
|
||||
post:
|
||||
summary: Login a user and receive an authentication cookie
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UUID"
|
||||
description: Request body for POST /auth/login
|
||||
responses:
|
||||
"200":
|
||||
description: Successful login, authentication cookie set
|
||||
headers:
|
||||
Set-Cookie:
|
||||
schema:
|
||||
type: string
|
||||
example: auth=eyJhbGci...; Path=/; HttpOnly
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Claims"
|
||||
"400":
|
||||
description: Invalid request payload
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
"401":
|
||||
description: Authentication failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
security: []
|
||||
tags:
|
||||
- Auth
|
||||
operationId: post_auth_login
|
||||
description: Log in a user and receive an authentication cookie
|
||||
/auth/logout:
|
||||
post:
|
||||
summary: Logout the current user
|
||||
responses:
|
||||
"204":
|
||||
description: Successful logout and the cookie was removed
|
||||
headers:
|
||||
Set-Cookie:
|
||||
description: >
|
||||
Sets the auth cookie to an empty value and expires it immediately by
|
||||
setting Max-Age to 0. The token gets invalidated.
|
||||
schema:
|
||||
type: string
|
||||
example: auth=; Path=/; HttpOnly; Max-Age=0
|
||||
"401":
|
||||
description: Authentication failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Auth
|
||||
operationId: post_auth_logout
|
||||
description: Logout the current user
|
||||
/auth:
|
||||
get:
|
||||
summary: Retrieve the claims for the currently authenticated user
|
||||
responses:
|
||||
"200":
|
||||
description: Claims of the authenticated user
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Claims"
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
security: []
|
||||
tags:
|
||||
- Auth
|
||||
operationId: get_auth
|
||||
description: Retrieve the claims for the currently authenticated user
|
||||
|
||||
/auth/users:
|
||||
get:
|
||||
summary: List all users
|
||||
responses:
|
||||
"200":
|
||||
description: Array of user objects
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/User"
|
||||
example: []
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
security: []
|
||||
tags:
|
||||
- Auth
|
||||
operationId: get_auth_users
|
||||
description: List all users
|
||||
/books:
|
||||
get:
|
||||
summary: Get all books
|
||||
responses:
|
||||
"200":
|
||||
description: Array of books
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Book"
|
||||
example: []
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
security: [] #no security needed
|
||||
|
||||
tags:
|
||||
- Books
|
||||
operationId: get_books
|
||||
description: Get all books
|
||||
post:
|
||||
summary: Register a new book
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BookRequest"
|
||||
|
||||
description: Request body for POST /books
|
||||
responses:
|
||||
"200":
|
||||
description: The new book
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Book"
|
||||
"400":
|
||||
$ref: "#/components/responses/Error400"
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Books
|
||||
operationId: post_books
|
||||
description: Register a new book
|
||||
/books/{bookID}:
|
||||
parameters:
|
||||
- name: bookID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
|
||||
description: Parameter bookID for /books/{bookID}
|
||||
get:
|
||||
summary: Get the details of a book
|
||||
responses:
|
||||
"200":
|
||||
description: BookDetails
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BookDetails"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
security: [] #no security needed
|
||||
|
||||
tags:
|
||||
- Books
|
||||
operationId: get_books_bookID
|
||||
description: Get the details of a book
|
||||
put:
|
||||
summary: Update a book
|
||||
description: |
|
||||
The field lentBy will be ignored. If you want to lend a book, please use the corresponding route.
|
||||
The field owner will only be obeyed if you own the book and set it to null / undefined.
|
||||
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BookRequest"
|
||||
|
||||
description: Request body for PUT /books/{bookID}
|
||||
responses:
|
||||
"200":
|
||||
description: The new book
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BookDetails"
|
||||
"400":
|
||||
$ref: "#/components/responses/Error400"
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"403":
|
||||
$ref: "#/components/responses/Error403"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Books
|
||||
operationId: put_books_bookID
|
||||
delete:
|
||||
summary: Delete a book
|
||||
responses:
|
||||
"204":
|
||||
description: Book deleted successfully
|
||||
"403":
|
||||
$ref: "#/components/responses/Error403"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Books
|
||||
operationId: delete_books_bookID
|
||||
description: Delete a book
|
||||
/books/{bookID}/lending:
|
||||
parameters:
|
||||
- name: bookID
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
description: Parameter bookID for /books/{bookID}/lending
|
||||
post:
|
||||
summary: Lend a book
|
||||
responses:
|
||||
"204":
|
||||
description: The book is successfully lent
|
||||
"400":
|
||||
description: Bad request - The book is most likely already lent
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Lending
|
||||
operationId: post_books_bookID_lending
|
||||
description: Lend a book
|
||||
delete:
|
||||
summary: End a lending (return a book)
|
||||
responses:
|
||||
"204":
|
||||
description: The lending is successfully ended.
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"403":
|
||||
description: Forbidden – you do not have an open lending
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Lending
|
||||
operationId: delete_books_bookID_lending
|
||||
description: End a lending (return a book)
|
||||
/lookup:
|
||||
post:
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Scan"
|
||||
|
||||
description: Request body for POST /lookup
|
||||
responses:
|
||||
"200":
|
||||
description: Looked up book
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BookRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Error401"
|
||||
"404":
|
||||
$ref: "#/components/responses/Error404"
|
||||
"500":
|
||||
$ref: "#/components/responses/Error500"
|
||||
tags:
|
||||
- Lookup
|
||||
operationId: post_lookup
|
||||
description: POST operation for /lookup
|
||||
@@ -0,0 +1,47 @@
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
#import "@local/chfoit-ipa:0.0.0": term
|
||||
#import "@preview/fletcher:0.5.1": diagram, edge, node
|
||||
|
||||
== Backend
|
||||
|
||||
#lorem(200)
|
||||
|
||||
// Beispiel:
|
||||
//
|
||||
//#wrap-content(
|
||||
// box(inset: (right: 1em, bottom: -4em), width: 16em, figure(
|
||||
// image("../../../02_Grafiken/placeholder.png"),
|
||||
// caption: [Übersicht über die Backend-Verzeichnisstruktur],
|
||||
// )),
|
||||
// align: top + left,
|
||||
// )[
|
||||
// === Unterteilung
|
||||
//
|
||||
// Beschreibung der Verzeichnisstruktur und der Unterteilung des Backends.
|
||||
// Die Struktur folgt den etablierten Konventionen des verwendeten
|
||||
// Backend-Frameworks.
|
||||
// ]
|
||||
//
|
||||
// === Konfiguration
|
||||
//
|
||||
// Das Backend kann über verschiedene Wege konfiguriert werden, z. B. über
|
||||
// Umgebungsvariablen oder eine Konfigurationsdatei. Sensible Werte wie
|
||||
// Zugangsdaten oder Secrets dürfen niemals im Quellcode oder in der
|
||||
// Dokumentation abgelegt werden.
|
||||
//
|
||||
// ==== Umgebungsvariablen
|
||||
//
|
||||
// In @fig-env-config sind die verfügbaren Umgebungsvariablen aufgelistet.
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (auto, 1fr, 1fr),
|
||||
// [Name], [Standard Wert], [Beschreibung],
|
||||
// [APP_PORT], [8080], [Port, auf dem das Backend läuft],
|
||||
// [APP_LOG_LEVEL], [info], [DEBUG, INFO, WARN oder ERROR],
|
||||
// [APP_DB_DSN],
|
||||
// [host=localhost user=postgres password=password dbname=app port=5432 sslmode=disable],
|
||||
// [Data Source Name / Connection string für die Datenbank],
|
||||
// ),
|
||||
// caption: [Übersicht der Umgebungsvariablen],
|
||||
// )<fig-env-config>
|
||||
@@ -0,0 +1,37 @@
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
#import "@local/chfoit-ipa:0.0.0": acronym
|
||||
#import "@preview/fletcher:0.5.1": diagram, edge, node
|
||||
|
||||
|
||||
== Frontend
|
||||
|
||||
|
||||
#lorem(200)
|
||||
|
||||
//
|
||||
// #wrap-content(
|
||||
// box(width: 20em, inset: (right: 1em, bottom: -4em), figure(
|
||||
// image("../../../02_Grafiken/placeholder.png"),
|
||||
// caption: [Übersicht über die Frontend-Verzeichnisstruktur],
|
||||
// )),
|
||||
//
|
||||
// align: top + left,
|
||||
// )[
|
||||
// === Unterteilung
|
||||
//
|
||||
// Das Frontend ist in wiederverwendbare Komponenten, Seiten (Routen) und
|
||||
// geteilte Services bzw. Interfaces unterteilt.
|
||||
//
|
||||
// ==== Komponenten
|
||||
// Im Verzeichnis `components` befinden sich wiederverwendbare
|
||||
// GUI-Komponenten.
|
||||
//
|
||||
// ==== Routen
|
||||
// Im Verzeichnis `routes` sind die Seiten der Applikation. Sie sind in
|
||||
// derselben hierarchischen Struktur wie die Routen der Applikation
|
||||
// abgelegt, damit es übersichtlich bleibt.
|
||||
//
|
||||
// ==== Shared
|
||||
// Im Verzeichnis `shared` befinden sich die über die Applikation geteilten
|
||||
// Interfaces, Services und Interceptors.
|
||||
// ]
|
||||
@@ -0,0 +1,40 @@
|
||||
#import "@local/chfoit-ipa:0.0.0": test
|
||||
#let testProtocol = test.protocoll
|
||||
|
||||
== Tests
|
||||
|
||||
// Beispiel:
|
||||
//
|
||||
//In diesem Abschnitt werden die Resultate der durchgeführten Tests protokolliert.
|
||||
//
|
||||
// === Unittests Backend
|
||||
//
|
||||
// #figure(table(
|
||||
// columns: (auto, auto, auto),
|
||||
// [Status], [Paket], [Abdeckung],
|
||||
// [ok], [backend/application], [93.6%],
|
||||
// [ok], [backend/auth], [84.5%],
|
||||
// [ok], [backend/user], [100.0%],
|
||||
// ))
|
||||
//
|
||||
// Die totale Testabdeckung beträgt: 69.7%
|
||||
//
|
||||
// === Unittests Frontend
|
||||
//
|
||||
// #figure(table(
|
||||
// columns: (auto, 1fr, auto),
|
||||
// [Status], [Paket], [Abdeckung #footnote[ der Statements]],
|
||||
// [ok], [src/app], [88.88%],
|
||||
// [ok], [src/app/shared/services], [46.53%],
|
||||
// [ok], [src/environments], [100%],
|
||||
// ))
|
||||
//
|
||||
// Die totale Testabdeckung beträgt: 64.37%
|
||||
//
|
||||
// === Akzeptanztests
|
||||
//
|
||||
// #let test = testProtocol.with(tester: "Max Mustermann", date: datetime(day: 1, month: 3, year: 2026))
|
||||
//
|
||||
// #test(case: "TC-1")[
|
||||
// Beschreibung des Akzeptanztestfalls.
|
||||
// ]
|
||||
@@ -0,0 +1,50 @@
|
||||
= Projektschlussbeurteilung
|
||||
|
||||
// == Vergleich Ist/Soll
|
||||
//
|
||||
// === Anforderungen
|
||||
//
|
||||
// #let ok = table.cell(fill: green.lighten(55%))[Erfüllt]
|
||||
// #let notOk = table.cell(fill: red.lighten(55%))[Nicht Erfüllt]
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (6.8em, 1fr, 2.5em, auto),
|
||||
// [ID],
|
||||
// [Anforderung],
|
||||
// [Art #footnote[Art = Anforderungsart: G = Geschäftsorganisation, F = Funktional, Q = Qualität, S = Sicherheit, M = Migration,
|
||||
// A = Architektur, B = Betrieb, K = Konformität (Gesetzgebung, Weisungswesen, Normen und Richtlinien)]],
|
||||
// [Erfüllungsstatus],
|
||||
//
|
||||
// [@req-a1], [Beschreibung der Anforderung], [F], ok,
|
||||
// ),
|
||||
// caption: [Erfüllung der Anforderungen],
|
||||
// )
|
||||
//
|
||||
// === Ziele
|
||||
//
|
||||
// In der Initialisierungsphase (@ziele) wurden Ziele definiert.
|
||||
//
|
||||
// #let ok = table.cell(fill: green.lighten(55%))[Erreicht]
|
||||
// #let notOk = table.cell(fill: red.lighten(55%))[Nicht Erreicht]
|
||||
//
|
||||
// ==== Produktziele
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (2em, 1fr, auto, 1fr),
|
||||
// [Nr.], [Ziel], [Erreicht], [Kommentar],
|
||||
// [1], [Beschreibung des Produktziels.], ok, [],
|
||||
// ),
|
||||
// caption: [Erfüllung der Produktziele],
|
||||
// )
|
||||
//
|
||||
// ==== Projektvorgehensziele
|
||||
//
|
||||
// #figure(
|
||||
// table(
|
||||
// columns: (2em, 1fr, auto, 1fr),
|
||||
// [Nr.], [Ziel], [Erreicht], [Kommentar],
|
||||
// [1], [Beschreibung des Projektvorgehensziels.], ok, [],
|
||||
// ),
|
||||
// caption: [Erfüllung der Projektvorgehensziele],
|
||||
// )
|
||||
@@ -0,0 +1,34 @@
|
||||
#import "@preview/wrap-it:0.1.1": wrap-content
|
||||
#import "@local/chfoit-ipa:0.0.0": acronym, term
|
||||
|
||||
= Realisierung
|
||||
|
||||
In diesem Teil wird auf die Umsetzung eingegangen.
|
||||
|
||||
#include "01_backend.typ"
|
||||
#include "02_frontend.typ"
|
||||
|
||||
|
||||
== Entwicklung
|
||||
|
||||
=== Abhängigkeiten
|
||||
|
||||
// Beschreibe die tools die zum entwickeln gebraucht werden.
|
||||
|
||||
=== Applikation starten
|
||||
|
||||
// Beschreibe folgendes:
|
||||
// - Herunterladen ders repository
|
||||
// - Starten der Applikation
|
||||
//
|
||||
// Am besten mit code bläcken
|
||||
#figure(
|
||||
```sh
|
||||
echo "example"
|
||||
```,
|
||||
caption: [Applikation starten],
|
||||
)
|
||||
=== Applikation stoppen
|
||||
|
||||
|
||||
#include "03_tests.typ"
|
||||
Whitespace-only changes.
@@ -0,0 +1,7 @@
|
||||
|
||||
#include "./01_Kurzfassung.typ"
|
||||
#include "./02_Einführung.typ"
|
||||
#include "./03_Initialisierung/index.typ"
|
||||
#include "./04_Konzept/index.typ"
|
||||
#include "./05_Realisierung/index.typ"
|
||||
#include "./06_Abschluss/index.typ"
|
||||
Reference in new issue
Block a user