# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **CalChat** is a calendar mobile app with AI support. The core concept is creating calendar events through a chat interface with an AI chatbot (Claude). Users can add, edit, and delete events via natural language conversation. This is a fullstack TypeScript monorepo with npm workspaces. ## Commands ### Root (monorepo) ```bash npm install # Install all dependencies for all workspaces ``` ### Client (apps/client) - Expo React Native app ```bash npm run start -w @caldav/client # Start Expo dev server npm run android -w @caldav/client # Start on Android npm run ios -w @caldav/client # Start on iOS npm run web -w @caldav/client # Start web version npm run lint -w @caldav/client # Run ESLint ``` ### Server (apps/server) - Express.js backend ```bash npm run dev -w @caldav/server # Start dev server with hot reload (tsx watch) npm run build -w @caldav/server # Compile TypeScript npm run start -w @caldav/server # Run compiled server (port 3000) ``` ## Technology Stack | Area | Technology | Purpose | |------|------------|---------| | Frontend | React Native | Mobile UI Framework | | | Expo | Development platform | | | Expo-Router | File-based routing | | | NativeWind | Tailwind CSS for React Native | | | Zustand | State management | | | FlashList | High-performance lists | | Backend | Express.js | Web framework | | | MongoDB | Database | | | Mongoose | ODM | | | Claude (Anthropic) | AI/LLM for chat | | | JWT | Authentication | | Planned | iCalendar | Event export/import | ## Architecture ### Workspace Structure ``` apps/client - @caldav/client - Expo React Native app apps/server - @caldav/server - Express.js backend packages/shared - @caldav/shared - Shared TypeScript types and models ``` ### Frontend Architecture (apps/client) ``` src/ ├── app/ # Expo-Router file-based routing │ ├── _layout.tsx # Root Stack layout │ ├── index.tsx # Entry redirect │ ├── login.tsx # Login screen │ ├── register.tsx # Registration screen │ ├── (tabs)/ # Tab navigation group │ │ ├── _layout.tsx # Tab bar configuration │ │ ├── chat.tsx # Chat screen (AI conversation) │ │ └── calendar.tsx # Calendar overview │ ├── event/ │ │ └── [id].tsx # Event detail screen (dynamic route) │ └── note/ │ └── [id].tsx # Note editor for event (dynamic route) ├── components/ │ ├── BaseBackground.tsx # Common screen wrapper │ ├── Header.tsx # Header component │ ├── EventCard.tsx # Event card for calendar display │ └── EventConfirmDialog.tsx # AI-proposed event confirmation modal ├── services/ │ ├── index.ts # Re-exports all services │ ├── ApiClient.ts # HTTP client (get, post, put, delete) │ ├── AuthService.ts # login(), register(), logout(), refresh() │ ├── EventService.ts # getAll(), getById(), getByDateRange(), create(), update(), delete() │ └── ChatService.ts # sendMessage(), confirmEvent(), rejectEvent(), getConversations(), getConversation() └── stores/ # Zustand state management ├── index.ts # Re-exports all stores ├── AuthStore.ts # user, token, isAuthenticated, login(), logout(), setToken() └── EventsStore.ts # events[], setEvents(), addEvent(), updateEvent(), deleteEvent() ``` **Routing:** Tab-based navigation with Chat and Calendar as main screens. Auth screens (login, register) outside tabs. Dynamic routes for event detail and note editing. ### Backend Architecture (apps/server) ``` src/ ├── app.ts # Entry point, DI setup, Express config ├── controllers/ # Request handlers │ ├── AuthController.ts # login(), register(), refresh(), logout() │ ├── ChatController.ts # sendMessage(), confirmEvent(), rejectEvent(), getConversations(), getConversation() │ └── EventController.ts # create(), getById(), getAll(), getByDateRange(), update(), delete() ├── middleware/ │ └── AuthMiddleware.ts # authenticate() - JWT validation ├── routes/ # API endpoint definitions │ ├── index.ts # Combines all routes under /api │ ├── auth.routes.ts # /api/auth/* │ ├── chat.routes.ts # /api/chat/* (protected) │ └── event.routes.ts # /api/events/* (protected) ├── services/ # Business logic │ ├── interfaces/ # DB-agnostic interfaces (for dependency injection) │ │ ├── AIProvider.ts # processMessage() │ │ ├── UserRepository.ts # + CreateUserData (server-internal DTO) │ │ ├── EventRepository.ts │ │ └── ChatRepository.ts │ ├── AuthService.ts │ ├── ChatService.ts │ └── EventService.ts ├── repositories/ # Data access (DB-specific implementations) │ ├── index.ts # Re-exports from ./mongo │ └── mongo/ # MongoDB implementation │ ├── models/ # Mongoose schemas │ │ ├── UserModel.ts │ │ ├── EventModel.ts │ │ └── ChatModel.ts │ ├── MongoUserRepository.ts │ ├── MongoEventRepository.ts │ └── MongoChatRepository.ts ├── ai/ │ └── ClaudeAdapter.ts # Implements AIProvider └── utils/ ├── jwt.ts # signToken(), verifyToken() └── password.ts # hash(), compare() ``` **API Endpoints:** - `POST /api/auth/login` - User login - `POST /api/auth/register` - User registration - `POST /api/auth/refresh` - Refresh JWT token - `POST /api/auth/logout` - User logout - `GET /api/events` - Get all events (protected) - `GET /api/events/range` - Get events by date range (protected) - `GET /api/events/:id` - Get single event (protected) - `POST /api/events` - Create event (protected) - `PUT /api/events/:id` - Update event (protected) - `DELETE /api/events/:id` - Delete event (protected) - `POST /api/chat/message` - Send message to AI (protected) - `POST /api/chat/confirm/:conversationId/:messageId` - Confirm proposed event (protected) - `POST /api/chat/reject/:conversationId/:messageId` - Reject proposed event (protected) - `GET /api/chat/conversations` - Get all conversations (protected) - `GET /api/chat/conversations/:id` - Get messages of a conversation with cursor-based pagination (protected) - `GET /health` - Health check ### Shared Package (packages/shared) ``` src/ ├── index.ts └── models/ ├── index.ts ├── User.ts # User, CreateUserDTO, LoginDTO, AuthResponse ├── CalendarEvent.ts # CalendarEvent, CreateEventDTO, UpdateEventDTO └── ChatMessage.ts # ChatMessage, Conversation, SendMessageDTO, CreateMessageDTO, # GetMessagesOptions, ChatResponse, ConversationSummary ``` **Key Types:** - `User`: id, email, displayName, passwordHash?, createdAt?, updatedAt? - `CalendarEvent`: id, userId, title, description?, startTime, endTime, note?, isRecurring?, recurrenceRule? - `ChatMessage`: id, conversationId, sender ('user' | 'assistant'), content, proposedEvent? - `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) ### Database Abstraction The repository pattern allows swapping databases: - **Interfaces** (`services/interfaces/`) are DB-agnostic - **Implementations** (`repositories/mongo/`) are DB-specific - To add MySQL: create `repositories/mysql/` with TypeORM entities ## MVP Feature Scope ### Must-Have - Chat interface with AI assistant (text input) for event management - Calendar overview - Manual event CRUD (without AI) - View completed events - Simple reminders - One note per event - Recurring events ### Nice-to-Have - iCalendar import/export - Multiple calendars - CalDAV synchronization with external services ## Development Environment ### MongoDB (Docker) ```bash cd apps/server/docker/mongo docker compose up -d # Start MongoDB + Mongo Express docker compose down # Stop services ``` - MongoDB: `localhost:27017` (root/mongoose) - Mongo Express UI: `localhost:8081` (admin/admin) ### Environment Variables Server requires `.env` file in `apps/server/`: ``` JWT_SECRET=your-secret-key JWT_EXPIRES_IN=1h MONGODB_URI=mongodb://root:mongoose@localhost:27017/calchat?authSource=admin ``` ## Current Implementation Status **Backend:** - **Implemented:** - `AuthController`: login(), register() with error handling - `AuthService`: login(), register() with password validation - `MongoUserRepository`: findByEmail(), create() - `utils/password`: hash(), compare() using bcrypt - `utils/jwt`: signToken() (verifyToken() pending) - `dotenv` integration for environment variables - **Stubbed (TODO):** - `AuthMiddleware.authenticate()`: Currently uses fake user for testing - `AuthController`: refresh(), logout() - `AuthService`: refreshToken() - All Chat and Event functionality - **Not started:** - `ChatController`, `ChatService`, `MongoChatRepository` - `EventController`, `EventService`, `MongoEventRepository` - `ClaudeAdapter` (AI integration) **Shared:** Types and DTOs defined and exported. **Frontend:** Skeleton complete with file-based routing structure: - Tab navigation (Chat, Calendar) implemented with basic UI - Calendar screen has month navigation and grid display (partially functional) - Chat screen has message list UI with FlashList (mock data only) - Auth screens (Login, Register), Event Detail, and Note screens exist as skeletons - Services (ApiClient, AuthService, EventService, ChatService) defined with `throw new Error('Not implemented')` - Zustand stores (AuthStore, EventsStore) defined with `throw new Error('Not implemented')` - Components (EventCard, EventConfirmDialog) exist as skeletons ## Documentation Detailed architecture diagrams are in `docs/`: - `api-routes.md` - API endpoint overview (German) - `technisches_brainstorm.tex` - Technical concept document (German) - `architecture-class-diagram.puml` - Backend class diagram - `frontend-class-diagram.puml` - Frontend class diagram - `component-diagram.puml` - System component overview