feat: add CalDAV synchronization with automatic sync
- Add CaldavService with tsdav/ical.js for CalDAV server communication - Add CaldavController, CaldavRepository, and caldav routes - Add client-side CaldavConfigService with sync(), config CRUD - Add CalDAV settings UI with config load/save in settings screen - Sync on login, auto-login (AuthGuard), periodic timer (calendar), and sync button - Push single events to CalDAV on server-side create/update/delete - Push all events to CalDAV after chat event confirmation - Refactor ChatService to use EventService instead of direct EventRepository - Rename CalDav/calDav to Caldav/caldav for consistent naming - Add Radicale Docker setup for local CalDAV testing - Update PlantUML diagrams and CLAUDE.md with CalDAV architecture
This commit is contained in:
@@ -30,6 +30,8 @@ package "Controller Layer" #ADD8E6 {
|
||||
}
|
||||
|
||||
class EventController {
|
||||
' -pushToCaldav()
|
||||
' -deleteFromCaldav()
|
||||
' +create()
|
||||
' +getById()
|
||||
' +getAll()
|
||||
@@ -38,6 +40,15 @@ package "Controller Layer" #ADD8E6 {
|
||||
' +delete()
|
||||
}
|
||||
|
||||
class CaldavController {
|
||||
' +saveConfig()
|
||||
' +loadConfig()
|
||||
' +deleteConfig()
|
||||
' +pullEvents()
|
||||
' +pushEvents()
|
||||
' +pushEvent()
|
||||
}
|
||||
|
||||
class AuthMiddleware {
|
||||
' +authenticate()
|
||||
}
|
||||
@@ -59,9 +70,12 @@ package "Service Layer" #90EE90 {
|
||||
' +findById()
|
||||
' +findByUserId()
|
||||
' +findByDateRange()
|
||||
' +findByCaldavUUID()
|
||||
' +searchByTitle()
|
||||
' +create()
|
||||
' +update()
|
||||
' +delete()
|
||||
' +addExceptionDate()
|
||||
}
|
||||
|
||||
interface ChatRepository {
|
||||
@@ -69,6 +83,14 @@ package "Service Layer" #90EE90 {
|
||||
' +createConversation()
|
||||
' +getMessages()
|
||||
' +createMessage()
|
||||
' +updateProposalResponse()
|
||||
' +updateProposalEvent()
|
||||
}
|
||||
|
||||
interface CaldavRepository {
|
||||
' +findByUserId()
|
||||
' +createOrUpdate()
|
||||
' +deleteByUserId()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +102,7 @@ package "Service Layer" #90EE90 {
|
||||
|
||||
class ChatService {
|
||||
' -chatRepo: ChatRepository
|
||||
' -eventRepo: EventRepository
|
||||
' -eventService: EventService
|
||||
' -aiProvider: AIProvider
|
||||
' +processMessage()
|
||||
' +confirmEvent()
|
||||
@@ -95,13 +117,29 @@ package "Service Layer" #90EE90 {
|
||||
' +getById()
|
||||
' +getAll()
|
||||
' +getByDateRange()
|
||||
' +searchByTitle()
|
||||
' +findByCaldavUUID()
|
||||
' +update()
|
||||
' +delete()
|
||||
' +deleteRecurring()
|
||||
}
|
||||
|
||||
class CaldavService {
|
||||
' -caldavRepo: CaldavRepository
|
||||
' -eventService: EventService
|
||||
' +connect()
|
||||
' +pullEvents()
|
||||
' +pushEvent()
|
||||
' +pushAll()
|
||||
' +deleteEvent()
|
||||
' +getConfig()
|
||||
' +saveConfig()
|
||||
' +deleteConfig()
|
||||
}
|
||||
}
|
||||
|
||||
package "AI Implementations" #FFA07A {
|
||||
class ClaudeAdapter implements AIProvider {
|
||||
class GPTAdapter implements AIProvider {
|
||||
' -apiKey: string
|
||||
' +processMessage()
|
||||
}
|
||||
@@ -119,6 +157,10 @@ package "Data Access Implementations" #FFD700 {
|
||||
class MongoChatRepository implements ChatRepository {
|
||||
' -model: ChatModel
|
||||
}
|
||||
|
||||
class MongoCaldavRepository implements CaldavRepository {
|
||||
' -model: CaldavConfigModel
|
||||
}
|
||||
}
|
||||
|
||||
package "Models" #D3D3D3 {
|
||||
@@ -169,15 +211,20 @@ package "Utils" #DDA0DD {
|
||||
' Controller -> Service
|
||||
AuthController --> AuthService
|
||||
ChatController --> ChatService
|
||||
ChatController --> CaldavService
|
||||
EventController --> EventService
|
||||
EventController --> CaldavService
|
||||
CaldavController --> CaldavService
|
||||
AuthMiddleware --> JWT
|
||||
|
||||
' Service -> Interfaces (intern)
|
||||
AuthService --> UserRepository
|
||||
ChatService --> ChatRepository
|
||||
ChatService --> EventRepository
|
||||
ChatService --> EventService
|
||||
ChatService --> AIProvider
|
||||
EventService --> EventRepository
|
||||
CaldavService --> CaldavRepository
|
||||
CaldavService --> EventService
|
||||
|
||||
' Auth uses Utils
|
||||
AuthService --> JWT
|
||||
|
||||
@@ -16,6 +16,8 @@ package "apps/client (Expo React Native)" as ClientPkg #87CEEB {
|
||||
[Login/Register] as AuthScreens
|
||||
[Calendar View] as CalendarScreen
|
||||
[Chat View] as ChatScreen
|
||||
[Settings] as SettingsScreen
|
||||
[Edit Event] as EditEventScreen
|
||||
[Event Detail] as EventDetail
|
||||
[Note Editor] as NoteScreen
|
||||
}
|
||||
@@ -25,17 +27,20 @@ package "apps/client (Expo React Native)" as ClientPkg #87CEEB {
|
||||
[Auth Service] as ClientAuth
|
||||
[Event Service] as ClientEvent
|
||||
[Chat Service] as ClientChat
|
||||
[Caldav Config Service] as ClientCaldav
|
||||
}
|
||||
|
||||
package "Components" {
|
||||
[UI Components] as UIComponents
|
||||
[Event Cards] as EventCards
|
||||
[Auth Guard] as AuthGuard
|
||||
}
|
||||
|
||||
package "Stores" {
|
||||
[Auth Store] as AuthStore
|
||||
[Events Store] as EventsStore
|
||||
[Chat Store] as ChatStore
|
||||
[Theme Store] as ThemeStore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,10 +64,11 @@ package "apps/server (Express.js)" as ServerPkg #98FB98 {
|
||||
[AuthService] as AuthSvc
|
||||
[ChatService] as ChatSvc
|
||||
[EventService] as EventSvc
|
||||
[CaldavService] as CaldavSvc
|
||||
}
|
||||
|
||||
package "AI Implementations" {
|
||||
[ClaudeAdapter] as Claude
|
||||
[GPTAdapter] as GPT
|
||||
}
|
||||
|
||||
package "Data Access Implementations" {
|
||||
@@ -80,25 +86,35 @@ package "apps/server (Express.js)" as ServerPkg #98FB98 {
|
||||
|
||||
' ===== ROW 4: EXTERNAL =====
|
||||
database "MongoDB" as MongoDB
|
||||
cloud "Claude API" as ClaudeAPI
|
||||
cloud "OpenAI API" as OpenAIAPI
|
||||
cloud "CalDAV Server" as CaldavServer
|
||||
|
||||
' ===== CONNECTIONS =====
|
||||
|
||||
' Frontend: Screens -> Services
|
||||
AuthScreens --> ClientAuth
|
||||
CalendarScreen --> ClientEvent
|
||||
CalendarScreen --> ClientCaldav
|
||||
ChatScreen --> ClientChat
|
||||
SettingsScreen --> ClientCaldav
|
||||
EditEventScreen --> ClientEvent
|
||||
EventDetail --> ClientEvent
|
||||
NoteScreen --> ClientEvent
|
||||
|
||||
ClientAuth --> ApiClient
|
||||
ClientEvent --> ApiClient
|
||||
ClientChat --> ApiClient
|
||||
ClientCaldav --> ApiClient
|
||||
|
||||
ApiClient --> AuthStore
|
||||
ClientEvent --> EventsStore
|
||||
ClientChat --> ChatStore
|
||||
|
||||
' Frontend: Auth
|
||||
AuthGuard --> AuthStore
|
||||
AuthGuard --> ClientCaldav
|
||||
AuthScreens --> ClientCaldav
|
||||
|
||||
' Frontend: Screens -> Components
|
||||
CalendarScreen --> EventCards
|
||||
ChatScreen --> EventCards
|
||||
@@ -121,14 +137,20 @@ Routes --> Controllers
|
||||
Controllers --> AuthSvc
|
||||
Controllers --> ChatSvc
|
||||
Controllers --> EventSvc
|
||||
Controllers --> CaldavSvc
|
||||
|
||||
' Backend: Service -> Interfaces
|
||||
AuthSvc --> Interfaces
|
||||
ChatSvc --> Interfaces
|
||||
EventSvc --> Interfaces
|
||||
CaldavSvc --> Interfaces
|
||||
|
||||
' Backend: Service dependencies
|
||||
ChatSvc --> EventSvc
|
||||
CaldavSvc --> EventSvc
|
||||
|
||||
' Backend: AI & Data Access implement Interfaces
|
||||
Claude ..|> Interfaces
|
||||
GPT ..|> Interfaces
|
||||
Repos ..|> Interfaces
|
||||
|
||||
' Backend: Service -> Utils
|
||||
@@ -143,6 +165,7 @@ Repos --> Schemas
|
||||
|
||||
' Backend -> External
|
||||
Schemas --> MongoDB
|
||||
Claude --> ClaudeAPI
|
||||
GPT --> OpenAIAPI
|
||||
CaldavSvc --> CaldavServer
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -22,18 +22,26 @@ package "Screens" #87CEEB {
|
||||
class RegisterScreen
|
||||
class CalendarScreen
|
||||
class ChatScreen
|
||||
class SettingsScreen
|
||||
class EditEventScreen
|
||||
class EventDetailScreen
|
||||
class NoteScreen
|
||||
}
|
||||
|
||||
' ===== COMPONENTS =====
|
||||
package "Components" #FFA07A {
|
||||
class AuthGuard
|
||||
class BaseBackground
|
||||
class Header
|
||||
class BaseButton
|
||||
class CardBase
|
||||
class ModalBase
|
||||
class EventCardBase
|
||||
class EventCard
|
||||
class ProposedEventCard
|
||||
class EventConfirmDialog
|
||||
class DeleteEventModal
|
||||
class ChatBubble
|
||||
class TypingIndicator
|
||||
}
|
||||
|
||||
' ===== SERVICES =====
|
||||
@@ -64,6 +72,13 @@ package "Services" #90EE90 {
|
||||
+rejectEvent()
|
||||
+getConversations()
|
||||
+getConversation()
|
||||
+updateProposalEvent()
|
||||
}
|
||||
class CaldavConfigService {
|
||||
+getConfig()
|
||||
+saveConfig()
|
||||
+deleteConfig()
|
||||
+sync()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +86,10 @@ package "Services" #90EE90 {
|
||||
package "Stores" #FFD700 {
|
||||
class AuthStore {
|
||||
' +user
|
||||
' +token
|
||||
' +isAuthenticated
|
||||
' +login()
|
||||
' +logout()
|
||||
' +setToken()
|
||||
' +loadStoredUser()
|
||||
}
|
||||
class EventsStore {
|
||||
' +events
|
||||
@@ -86,10 +100,16 @@ package "Stores" #FFD700 {
|
||||
}
|
||||
class ChatStore {
|
||||
' +messages
|
||||
' +isWaitingForResponse
|
||||
' +addMessage()
|
||||
' +addMessages()
|
||||
' +updateMessage()
|
||||
' +clearMessages()
|
||||
}
|
||||
class ThemeStore {
|
||||
' +theme
|
||||
' +setTheme()
|
||||
}
|
||||
}
|
||||
|
||||
' ===== MODELS =====
|
||||
@@ -97,6 +117,7 @@ package "Models (shared)" #D3D3D3 {
|
||||
class User
|
||||
class CalendarEvent
|
||||
class ChatMessage
|
||||
class CaldavConfig
|
||||
}
|
||||
|
||||
' ===== RELATIONSHIPS =====
|
||||
@@ -104,24 +125,39 @@ package "Models (shared)" #D3D3D3 {
|
||||
' Screens -> Services
|
||||
LoginScreen --> AuthService
|
||||
CalendarScreen --> EventService
|
||||
CalendarScreen --> CaldavConfigService
|
||||
ChatScreen --> ChatService
|
||||
NoteScreen --> EventService
|
||||
EditEventScreen --> EventService
|
||||
EditEventScreen --> ChatService
|
||||
SettingsScreen --> CaldavConfigService
|
||||
|
||||
' Screens -> Components
|
||||
CalendarScreen --> EventCard
|
||||
ChatScreen --> ProposedEventCard
|
||||
ChatScreen --> EventConfirmDialog
|
||||
ChatScreen --> ChatBubble
|
||||
ChatScreen --> TypingIndicator
|
||||
EventCard --> EventCardBase
|
||||
ProposedEventCard --> EventCardBase
|
||||
EventCardBase --> CardBase
|
||||
ModalBase --> CardBase
|
||||
DeleteEventModal --> ModalBase
|
||||
|
||||
' Auth
|
||||
AuthGuard --> AuthStore
|
||||
AuthGuard --> CaldavConfigService
|
||||
LoginScreen --> CaldavConfigService
|
||||
|
||||
' Services -> ApiClient
|
||||
AuthService --> ApiClient
|
||||
EventService --> ApiClient
|
||||
ChatService --> ApiClient
|
||||
CaldavConfigService --> ApiClient
|
||||
|
||||
' Services/Screens -> Stores
|
||||
AuthService --> AuthStore
|
||||
EventService --> EventsStore
|
||||
CalendarScreen --> EventsStore
|
||||
ChatScreen --> ChatStore
|
||||
SettingsScreen --> ThemeStore
|
||||
|
||||
@enduml
|
||||
|
||||
Reference in New Issue
Block a user