diff --git a/docs/architecture-class-diagram.puml b/docs/architecture-class-diagram.puml new file mode 100644 index 0000000..19fa1b9 --- /dev/null +++ b/docs/architecture-class-diagram.puml @@ -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 <> { + ' +id: string + ' +email: string + ' +displayName: string + } + + class CalendarEvent <> { + ' +id: string + ' +userId: string + ' +title: string + ' +startTime: Date + ' +endTime: Date + ' +note?: string + } + + class ChatMessage <> { + ' +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 diff --git a/docs/component-diagram.puml b/docs/component-diagram.puml new file mode 100644 index 0000000..bd74d95 --- /dev/null +++ b/docs/component-diagram.puml @@ -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 diff --git a/docs/frontend-class-diagram.puml b/docs/frontend-class-diagram.puml new file mode 100644 index 0000000..3e8230c --- /dev/null +++ b/docs/frontend-class-diagram.puml @@ -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 diff --git a/docs/technisches_brainstorm.tex b/docs/technisches_brainstorm.tex new file mode 100644 index 0000000..0d7266c --- /dev/null +++ b/docs/technisches_brainstorm.tex @@ -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}