added docs

This commit is contained in:
Linus109
2025-12-15 16:59:00 +01:00
parent cc1af29e02
commit 5af6cffa9c
4 changed files with 616 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
@startuml "Backend Klassendiagramm"
skinparam packageStyle rectangle
skinparam classAttributeIconSize 0
skinparam classFontSize 11
skinparam defaultFontSize 10
top to bottom direction
title Backend Architektur - Klassendiagramm
package "Controller Layer" #ADD8E6 {
class AuthController {
' +login()
' +register()
' +refresh()
' +logout()
}
class ChatController {
' +sendMessage()
' +confirmEvent()
' +rejectEvent()
' +getConversations()
}
class EventController {
' +create()
' +getAll()
' +getByDateRange()
' +update()
' +delete()
}
class AuthMiddleware {
' +authenticate()
}
}
package "Service Layer" #90EE90 {
package "Interfaces" {
interface AIProvider {
' +processMessage()
}
interface UserRepository {
' +findById()
' +findByEmail()
' +create()
}
interface EventRepository {
' +findById()
' +findByUserId()
' +findByDateRange()
' +create()
' +update()
' +delete()
}
interface ChatRepository {
' +getHistory()
' +create()
}
}
class AuthService {
' -userRepo: UserRepository
' +login()
' +register()
}
class ChatService {
' -chatRepo: ChatRepository
' -eventRepo: EventRepository
' -aiProvider: AIProvider
' +processMessage()
' +confirmEvent()
}
class EventService {
' -eventRepo: EventRepository
' +create()
' +getByDateRange()
' +update()
' +delete()
}
}
package "AI Layer" #FFA07A {
class ClaudeAdapter implements AIProvider {
' -apiKey: string
' +processMessage()
}
}
package "Data Access Layer" #FFD700 {
class MongoUserRepository implements UserRepository {
' -model: UserModel
}
class MongoEventRepository implements EventRepository {
' -model: EventModel
}
class MongoChatRepository implements ChatRepository {
' -model: ChatModel
}
}
package "Models" #D3D3D3 {
class User <<Entity>> {
' +id: string
' +email: string
' +displayName: string
}
class CalendarEvent <<Entity>> {
' +id: string
' +userId: string
' +title: string
' +startTime: Date
' +endTime: Date
' +note?: string
}
class ChatMessage <<Entity>> {
' +id: string
' +sender: string
' +content: string
' +proposedEvent?: ProposedEvent
}
}
package "Utils" #DDA0DD {
class JWT {
' +signToken()
' +verifyToken()
}
class Password {
' +hash()
' +compare()
}
}
' Controller -> Service
AuthController --> AuthService
ChatController --> ChatService
EventController --> EventService
AuthMiddleware --> JWT
' Service -> Interfaces (intern)
AuthService --> UserRepository
ChatService --> ChatRepository
ChatService --> EventRepository
ChatService --> AIProvider
EventService --> EventRepository
' Auth uses Utils
AuthService --> JWT
AuthService --> Password
@enduml

135
docs/component-diagram.puml Normal file
View File

@@ -0,0 +1,135 @@
@startuml "System Komponenten"
skinparam componentStyle uml2
skinparam packageStyle rectangle
skinparam defaultFontSize 10
top to bottom direction
title Monorepo - System Komponenten
' ===== FRONTEND =====
package "apps/client (Expo React Native)" #87CEEB {
package "Screens (app/)" {
[Login/Register] as AuthScreens
[Calendar View] as CalendarScreen
[Chat View] as ChatScreen
[Event Detail] as EventDetail
}
package "Services" {
[API Client] as ApiClient
[Auth Service] as ClientAuth
[Event Service] as ClientEvent
[Chat Service] as ClientChat
}
package "Components" {
[EventCard] as EventCard
[ChatBubble] as ChatBubble
[ConfirmDialog] as ConfirmDialog
}
package "Stores" {
[Auth Store] as AuthStore
[Events Store] as EventsStore
}
}
' ===== SHARED =====
package "packages/shared" #DDA0DD {
[Models] as SharedModels
[DTOs] as SharedDTOs
}
' ===== BACKEND =====
package "apps/server (Express.js)" #98FB98 {
package "Controller Layer" {
[Routes] as Routes
[Controllers] as Controllers
[Middleware] as Middleware
}
package "Service Layer" {
[Interfaces] as Interfaces
[AuthService] as AuthSvc
[ChatService] as ChatSvc
[EventService] as EventSvc
}
package "AI Layer" {
[ClaudeAdapter] as Claude
}
package "Data Access Layer" {
[Repositories] as Repos
[Mongoose Schemas] as Schemas
}
package "Utils" {
[JWT] as JWTUtil
[Password] as PwdUtil
}
}
' ===== EXTERNAL =====
database "MongoDB" as MongoDB
cloud "Claude API" as ClaudeAPI
' ===== CONNECTIONS =====
' Frontend internal
AuthScreens --> ClientAuth
CalendarScreen --> ClientEvent
ChatScreen --> ClientChat
EventDetail --> ClientEvent
ClientAuth --> ApiClient
ClientEvent --> ApiClient
ClientChat --> ApiClient
ApiClient --> AuthStore
ClientEvent --> EventsStore
' Frontend -> Shared
ApiClient ..> SharedDTOs
ApiClient ..> SharedModels
' Frontend -> Backend
ApiClient --> Routes : HTTP/REST
' Backend: Controller Layer
Routes --> Middleware
Routes --> Controllers
' Backend: Controller -> Service
Controllers --> AuthSvc
Controllers --> ChatSvc
Controllers --> EventSvc
' Backend: Service -> Interfaces
AuthSvc --> Interfaces
ChatSvc --> Interfaces
EventSvc --> Interfaces
' Backend: AI & Data Access implement Interfaces
Claude ..|> Interfaces
Repos ..|> Interfaces
' Backend: Service -> Utils
AuthSvc --> JWTUtil
AuthSvc --> PwdUtil
Middleware --> JWTUtil
' Backend: Data Access
Repos --> Schemas
' Backend -> Shared
Repos ..> SharedModels
Controllers ..> SharedDTOs
' Backend -> External
Schemas --> MongoDB
Claude --> ClaudeAPI
@enduml

View File

@@ -0,0 +1,86 @@
@startuml "Frontend Klassendiagramm"
skinparam packageStyle rectangle
skinparam classAttributeIconSize 0
skinparam classFontSize 10
skinparam defaultFontSize 9
skinparam wrapWidth 100
skinparam nodesep 30
skinparam ranksep 30
top to bottom direction
title Frontend (Expo React Native)
' ===== SCREENS =====
package "Screens" #87CEEB {
class LoginScreen
class RegisterScreen
class CalendarScreen
class ChatScreen
class EventDetailScreen
class NoteScreen
}
' ===== COMPONENTS =====
package "Components" #FFA07A {
class EventCard
class ChatBubble
class EventConfirmDialog
class MonthSelector
}
' ===== SERVICES =====
package "Services" #90EE90 {
class ApiClient {
+get()
+post()
+put()
+delete()
}
class AuthService
class EventService
class ChatService
}
' ===== STORES =====
package "Stores" #FFD700 {
class AuthStore {
' +user
' +token
}
class EventsStore {
' +events
}
}
' ===== MODELS =====
package "Models (shared)" #D3D3D3 {
class User
class CalendarEvent
class ChatMessage
}
' ===== RELATIONSHIPS =====
' Screens -> Services
LoginScreen --> AuthService
CalendarScreen --> EventService
ChatScreen --> ChatService
NoteScreen --> EventService
' Screens -> Components
CalendarScreen --> EventCard
ChatScreen --> ChatBubble
ChatScreen --> EventConfirmDialog
' Services -> ApiClient
AuthService --> ApiClient
EventService --> ApiClient
ChatService --> ApiClient
' Services -> Stores
AuthService --> AuthStore
EventService --> EventsStore
@enduml

View File

@@ -0,0 +1,231 @@
\documentclass[a4paper,11pt]{article}
\usepackage[
a4paper,
top=2cm,
bottom=2cm,
left=2cm,
right=2cm,
marginparwidth=1.75cm
]{geometry}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage{parskip} % spacing and indent of paragraphs
\usepackage{setspace} % line spacing
\usepackage{graphicx}
\usepackage{fontspec} % needed to use system fonts
\usepackage{cite}
\usepackage{hyperref} % adds clickable links
\usepackage{float} % to show figures where i want them
\usepackage{natbib} % quote styling (activates citep)
\usepackage{enumitem} % list spacing
\bibliographystyle{apalike}
\graphicspath{ {./res} {./} }
\setmainfont{ITC Officina Sans Std Book}
\renewcommand{\baselinestretch}{1.15} % linespace
\newcommand{\q}[1]{``#1''} % short hand quotation marks
\begin{document}
% Sollte erst am Ende auskommentiert werden um die letzten 'overfull' hboxes zu
% beseitigen
%\tolerance=500
\title{Technisches brainstorm}
\author{Linus Waldowsky}
\date{\today}
\maketitle
\tableofcontents
\section{CalChat}
Bei dem Projekt CalChat handelt es sich um eine Kalender-Mobile-App mit
KI-Unterstützung. Das Besondere an der Sache ist, dass die Kalender-Events
größtenteils über ein Chatinterface mit Hilfe eines KI-Chatbots erstellt werden
sollen.
CalChat wird als Fullstack Typescript Applikation aufgesetzt.
\section{Technologien}
\begin{table}[H]
\centering
\begin{tabular}{|l|l|l|}
\hline
\textbf{Bereich} & \textbf{Technologie} & \textbf{Zweck} \\
\hline
Frontend & React Native & Mobile UI Framework \\
& Expo & Entwicklungsplattform \\
& Expo-Router & Dateibasiertes Routing \\
& Tailwind / Nativewind & Styling \\
\hline
Backend & Express.js & Web-App Framework \\
& MongoDB & Datenbank \\
& Mongoose & ODM \\
& Claude (Anthropic) & KI / LLM \\
& JWT & Authentifizierung \\
\hline
Geplant & iCalendar & Event-Export \\
\hline
\end{tabular}
\caption{Technologie-Stack}
\end{table}
\subsection{Frontend}
Das Frontend wird \textbf{React Native} in Kombination mit dem Framework
\textbf{Expo} nutzen. Expo bietet u.a. einer eigenen Standard-Bibliothek von
nativen Modulen. Außerdem vereinfach es die Entwicklung plattformübergreifender
Apps (IOS, Android und sogar Web) nochmal deutlich.
Expo's Routing-Framework, genannt \textbf{Expo-Router}, ist von Next.js
inspiriert und verwendet ein dateibasiertes Routing (ähnlich wie Next.js). Bei
diesem System wird bei jeder im app-Ordner erstellten Datei automatisch eine
neue Route in der Anwendung generiert.
Das Styling für die App übernimmt, neben dem bereits eingebauten Styling über
CSS, \textbf{Tailwind}. Tailwind ist ein CSS Framework, welches hauptsächlich
aus einer großen Anzahl an vorbereiteten CSS-Klassen besteht, aus denen jedes
Design zusammengesetzt werden kann. \textbf{Nativewind} macht diese Klassen in
React Native nutzbar.
\subsection{Backend}
\textbf{Express.js} dient als Web-App Framework. Es ist leichtgewichtig, auf
Node.js basierend und bietet ein minimales Grundgerüst, das nach Bedarf
erweitert werden kann.
Die Daten werden in \textbf{MongoDB}, einer dokumentenorientierten
NoSQL-Datenbank gespeichert. Statt starrer Tabellen arbeitet MongoDB mit
JSON-ähnlichen Dokumenten, was flexible Schemas und eine natürliche Integration
mit JavaScript ermöglicht.
\textbf{Mongoose} übernimmt die Kommunikation mit MongoDB. Als ODM (Object
Document Mapper) stellt es Schema-Definitionen, Validierung und
Typkonvertierung bereit.
Der wichtigste Teil der App ist die KI-Integration über \textbf{Claude}
(Anthropic). Dieses LLM verarbeitet natürlichsprachliche Eingaben der Nutzer und
generiert daraus strukturierte Event-Vorschläge.
Die Authentifizierung läuft über \textbf{JSON Web Tokens} (JWT). Der Vorteil:
zustandslose Sessions, bei denen der Server keine Session-Daten speichern muss.
Geplant ist außerdem die Unterstützung des \textbf{iCalendar}-Formats (ICAL)
für den Export von Kalender-Events.
\section{Architektur}
\subsection{Frontend}
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{{Frontend Klassendiagramm}.png}
\caption{Frontend Klassendiagramm}
\end{figure}
Das Frontend ist in vier Bereiche gegliedert. Die Screens bilden die
Hauptansichten der App: Login, Kalenderübersicht, Chat, Event-Details und
Notizen. Die Services kapseln die Kommunikation mit dem Backend. Ein zentraler
API Client übernimmt alle HTTP-Anfragen, während spezialisierte Services (Auth,
Event, Chat) die jeweilige Fachlogik bereitstellen. Die Components sind
wiederverwendbare UI-Bausteine wie EventCard, ChatBubble oder der
EventConfirmDialog. In den Stores wird der Anwendungszustand verwaltet. Der Auth
Store speichert User und Token, der Events Store die Kalender-Events.
\subsection{Shared Bereich}
Im Shared-Paket (\texttt{@caldav/shared}) befinden sich TypeScript-Typen und
Interfaces, die sowohl vom Frontend als auch vom Backend verwendet werden. Dazu
gehören vor allem die Datenmodelle für User, CalendarEvent (inkl. optionalem
Notiz-Feld) und ChatMessage.
\subsection{Backend}
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{{Backend Klassendiagramm}.png}
\caption{Backend Klassendiagramm}
\end{figure}
\subsubsection{Controller Layer}
Der Controller Layer bildet die Schnittstelle zwischen Frontend und
Backend-Logik. Die Routes definieren die API-Endpunkte, die Controller
verarbeiten die eingehenden Requests und reichen diese an die Services weiter.
Eine Auth Middleware prüft bei geschützten Routen den JWT-Token.
\subsubsection{Service Layer}
Der Service Layer enthält die Geschäftslogik der Anwendung. Er definiert
Interfaces für den Zugriff auf Datenbank und KI, die von den darunterliegenden
Schichten implementiert werden. Der AuthService kümmert sich um Login und
Token-Erstellung, der EventService um das Erstellen, Bearbeiten und Löschen von
Events. Der ChatService verarbeitet Nachrichten, kommuniziert mit der KI und
generiert Event-Vorschläge.
\subsubsection{AI Layer}
Der AI Layer implementiert das AIProvider-Interface aus dem Service Layer. Der
ClaudeAdapter kapselt die Kommunikation mit der Claude API und übersetzt
natürlichsprachliche Eingaben in strukturierte Event-Daten.
\subsubsection{Data Access Layer}
Der Data Access Layer implementiert die Repository-Interfaces aus dem Service
Layer. Die MongoDB-Repositories übernehmen alle Datenbankoperationen über
Mongoose. So bleibt die Geschäftslogik von der konkreten Datenbank entkoppelt.
\subsubsection{Models}
Die Models definieren die Datenstrukturen, die von allen Schichten verwendet
werden. Gemeinsame Models (User, CalendarEvent, ChatMessage) liegen im
Shared-Paket. Backend-spezifische Models, die z.B. zusätzliche Datenbankfelder
enthalten, liegen im Server und erweitern teilweise die Shared-Models.
\section{Funktionsumfang für das MVP}
\subsection{Must-Haves}
\begin{itemize}[noitemsep]
\item \textbf{Chat-Interface mit KI-Assistent}: Texteingabe reicht für den
Anfang. Die KI kann Events hinzufügen, bearbeiten und löschen.
\item \textbf{Kalender-Übersicht}: Visuelle Darstellung aller Events.
\item \textbf{Manuelle Event-Verwaltung}: Events auch ohne KI hinzufügen,
bearbeiten und löschen.
\item \textbf{Übersicht beendeter Events}: Abgeschlossene Events einsehen.
\item \textbf{Erinnerungsfunktion}: Einfache Benachrichtigungen.
\item \textbf{Notizen}: Eine Notiz pro Event.
\item \textbf{Wiederkehrende Events}: Events mit Wiederholungsintervall.
\end{itemize}
\subsection{Nice-to-Haves}
\begin{itemize}[noitemsep]
\item \textbf{iCalendar-Import/Export}: Events im standardisierten Format
exportieren und aus diesem Format importieren.
\item \textbf{Mehrere Kalender}: Events in verschiedene Kalender einordnen.
\item \textbf{CalDAV-Synchronisation}: Anbindung an externe
Kalender-Dienste.
\end{itemize}
\section{Aktueller Entwicklungsstand}
Das Projekt ist als Monorepo mit npm Workspaces aufgesetzt. Die drei Pakete
(\texttt{apps/client}, \texttt{apps/server}, \texttt{packages/shared}) teilen
sich gemeinsame Abhängigkeiten. Client und Server können Types aus dem
Shared-Paket importieren.
Im Frontend läuft eine Expo-App mit React Native und Nativewind für das
Styling. Das dateibasierte Routing über Expo-Router ist eingerichtet. Der
Kalender- und der Chat-Screen sind bereits teilweise implementiert.
Das Backend besteht aus einem Express.js-Grundgerüst, das auf Port 3000 läuft.
Im Shared-Paket liegt die Struktur für gemeinsame TypeScript-Typen bereit.
\end{document}