added docs
This commit is contained in:
164
docs/architecture-class-diagram.puml
Normal file
164
docs/architecture-class-diagram.puml
Normal 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
135
docs/component-diagram.puml
Normal 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
|
||||
86
docs/frontend-class-diagram.puml
Normal file
86
docs/frontend-class-diagram.puml
Normal 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
|
||||
231
docs/technisches_brainstorm.tex
Normal file
231
docs/technisches_brainstorm.tex
Normal 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}
|
||||
Reference in New Issue
Block a user