feat: implement chat persistence with MongoDB

- Add full chat persistence to database (conversations and messages)
- Implement MongoChatRepository with cursor-based pagination
- Add getConversations/getConversation endpoints in ChatController
- Save user and assistant messages in ChatService.processMessage()
- Track respondedAction (confirm/reject) on proposed event messages
- Load existing messages on chat screen mount
- Add addMessages() bulk action and chatMessageToMessageData() helper to ChatStore
- Add RespondedAction type and UpdateMessageDTO to shared types
This commit is contained in:
2026-01-09 16:21:01 +01:00
parent d86b18173f
commit c897b6d680
11 changed files with 245 additions and 45 deletions

View File

@@ -91,7 +91,7 @@ src/
└── stores/ # Zustand state management
├── index.ts # Re-exports all stores
├── AuthStore.ts # user, token, isAuthenticated, login(), logout(), setToken()
├── ChatStore.ts # messages[], addMessage(), updateMessage(), clearMessages()
├── ChatStore.ts # messages[], addMessage(), addMessages(), updateMessage(), clearMessages(), chatMessageToMessageData()
└── EventsStore.ts # events[], setEvents(), addEvent(), updateEvent(), deleteEvent()
```
@@ -172,7 +172,7 @@ src/
│ ├── CalendarEvent.ts # CalendarEvent, CreateEventDTO, UpdateEventDTO, ExpandedEvent
│ ├── ChatMessage.ts # ChatMessage, Conversation, SendMessageDTO, CreateMessageDTO,
│ │ # GetMessagesOptions, ChatResponse, ConversationSummary,
│ │ # ProposedEventChange, EventAction
│ │ # ProposedEventChange, EventAction, RespondedAction, UpdateMessageDTO
│ └── Constants.ts # DAYS, MONTHS, Day, Month, DAY_INDEX, DAY_INDEX_TO_DAY,
│ # DAY_TO_GERMAN, DAY_TO_GERMAN_SHORT, MONTH_TO_GERMAN
└── utils/
@@ -184,12 +184,14 @@ src/
- `User`: id, email, displayName, passwordHash?, createdAt?, updatedAt?
- `CalendarEvent`: id, userId, title, description?, startTime, endTime, note?, isRecurring?, recurrenceRule?
- `ExpandedEvent`: Extends CalendarEvent with occurrenceStart, occurrenceEnd (for recurring event instances)
- `ChatMessage`: id, conversationId, sender ('user' | 'assistant'), content, proposedChange?
- `ChatMessage`: id, conversationId, sender ('user' | 'assistant'), content, proposedChange?, respondedAction?
- `ProposedEventChange`: action ('create' | 'update' | 'delete'), eventId?, event?, updates?
- `Conversation`: id, userId, createdAt?, updatedAt? (messages loaded separately via lazy loading)
- `CreateEventDTO`: Used for creating events AND for AI-proposed events
- `GetMessagesOptions`: Cursor-based pagination with `before?: string` and `limit?: number`
- `ConversationSummary`: id, lastMessage?, createdAt? (for conversation list)
- `UpdateMessageDTO`: respondedAction? (for marking messages as confirmed/rejected)
- `RespondedAction`: 'confirm' | 'reject' (tracks user response to proposed events)
- `Day`: "Monday" | "Tuesday" | ... | "Sunday"
- `Month`: "January" | "February" | ... | "December"
@@ -281,12 +283,14 @@ MONGODB_URI=mongodb://root:mongoose@localhost:27017/calchat?authSource=admin
- `EventService`: Full CRUD with recurring event expansion via recurrenceExpander
- `utils/eventFormatters`: getWeeksOverview(), getMonthOverview() with German localization
- `utils/recurrenceExpander`: expandRecurringEvents() using rrule library for RRULE parsing
- `ChatController`: getConversations(), getConversation() with cursor-based pagination support
- `ChatService`: getConversations(), getConversation(), processMessage() now persists user/assistant messages to DB, confirmEvent()/rejectEvent() update respondedAction and persist response messages
- `MongoChatRepository`: Full CRUD implemented (getConversationsByUser, createConversation, getMessages with cursor pagination, createMessage, updateMessage)
- `ChatRepository` interface: updateMessage() added for respondedAction tracking
- **Stubbed (TODO):**
- `AuthMiddleware.authenticate()`: Currently uses fake user for testing
- `AuthController`: refresh(), logout()
- `AuthService`: refreshToken()
- `ChatController`: getConversations(), getConversation()
- `MongoChatRepository`: Database persistence for chat
- **Not started:**
- `ClaudeAdapter` (AI integration - currently using test responses)
@@ -302,20 +306,22 @@ MONGODB_URI=mongodb://root:mongoose@localhost:27017/calchat?authSource=admin
- Tap-to-open modal overlay showing EventCards for selected day
- Supports events from adjacent months visible in grid
- Uses `useFocusEffect` for automatic reload on tab focus
- Chat screen functional with FlashList, message sending, and event confirm/reject
- Messages persisted via ChatStore (survives tab switches)
- Chat screen fully functional with FlashList, message sending, and event confirm/reject
- Messages persisted to database via ChatService and loaded on mount
- Tracks conversationId for message continuity across sessions
- ChatStore with addMessages() for bulk loading, chatMessageToMessageData() helper
- KeyboardAvoidingView for proper keyboard handling (iOS padding, Android height)
- Auto-scroll to end on new messages and keyboard show
- keyboardDismissMode="interactive" and keyboardShouldPersistTaps="handled"
- `ApiClient`: get(), post(), put(), delete() implemented
- `EventService`: getAll(), getById(), getByDateRange(), create(), update(), delete() - fully implemented
- `ChatService`: sendMessage(), confirmEvent(convId, msgId, action, event?, eventId?, updates?), rejectEvent() - supports create/update/delete actions
- `ChatService`: sendMessage(), confirmEvent(), rejectEvent(), getConversations(), getConversation() - fully implemented with cursor pagination
- `EventCardBase`: Shared base component with event layout (header, date/time/recurring icons, description) - used by both EventCard and ProposedEventCard
- `EventCard`: Uses EventCardBase + edit/delete buttons for calendar display
- `ProposedEventCard`: Uses EventCardBase + confirm/reject buttons for chat proposals (supports create/update/delete actions)
- `Themes.tsx`: Centralized color definitions including textPrimary, borderPrimary, eventIndicator, secondaryBg
- `EventsStore`: Zustand store with setEvents(), addEvent(), updateEvent(), deleteEvent() - stores ExpandedEvent[]
- `ChatStore`: Zustand store with addMessage(), updateMessage(), clearMessages() - persists messages across tab switches
- `ChatStore`: Zustand store with addMessage(), addMessages(), updateMessage(), clearMessages() - loads from server on mount and persists across tab switches
- Auth screens (Login, Register), Event Detail, and Note screens exist as skeletons
- AuthStore defined with `throw new Error('Not implemented')`