feat: write template

This commit is contained in:
u80864958 committed 2026-09-18 16:36:52 +02:00
commit a0a6d2cf84
98 files changed
+6609

No files matched your search

@@ -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