# Notification and Widget Update System - Complete File & Route Analysis ## πŸ“‹ Table of Contents 1. [Notification System](#notification-system) 2. [Widget Update System](#widget-update-system) 3. [API Routes](#api-routes) 4. [Components](#components) 5. [Services & Libraries](#services--libraries) 6. [Hooks](#hooks) 7. [Types](#types) --- ## πŸ”” Notification System ### API Routes #### 1. **GET `/api/notifications`** - **File**: `app/api/notifications/route.ts` - **Purpose**: Fetch paginated notifications for authenticated user - **Query Parameters**: - `page` (default: 1) - `limit` (default: 20, max: 100) - **Response**: ```json { "notifications": Notification[], "page": number, "limit": number, "total": number } ``` - **Cache**: 30 seconds client-side cache - **Authentication**: Required (session-based) #### 2. **GET `/api/notifications/count`** - **File**: `app/api/notifications/count/route.ts` - **Purpose**: Get notification count (total and unread) for authenticated user - **Response**: ```json { "total": number, "unread": number, "sources": { [source]: { "total": number, "unread": number } } } ``` - **Cache**: 10 seconds client-side cache - **Authentication**: Required #### 3. **POST `/api/notifications/[id]/read`** - **File**: `app/api/notifications/[id]/read/route.ts` - **Purpose**: Mark a specific notification as read - **Parameters**: - `id` (path parameter): Notification ID (format: `source-sourceId`) - **Response**: ```json { "success": boolean } ``` - **Authentication**: Required #### 4. **POST `/api/notifications/read-all`** - **File**: `app/api/notifications/read-all/route.ts` - **Purpose**: Mark all notifications as read for authenticated user - **Response**: ```json { "success": boolean } ``` - **Authentication**: Required #### 5. **GET `/api/debug/notifications`** - **File**: `app/api/debug/notifications/route.ts` - **Purpose**: Debug endpoint to test notification system - **Response**: Detailed debug information including: - Environment variables status - User information - Notification service test results - Performance metrics - **Authentication**: Required ### Services #### 1. **NotificationService** (Singleton) - **File**: `lib/services/notifications/notification-service.ts` - **Purpose**: Core notification aggregation service - **Features**: - Multi-source notification aggregation (adapter pattern) - Redis caching (30s for counts, 5min for lists) - Background refresh scheduling - Cache invalidation on read operations - Lock mechanism to prevent concurrent refreshes - **Methods**: - `getInstance()`: Get singleton instance - `getNotifications(userId, page, limit)`: Fetch notifications - `getNotificationCount(userId)`: Get notification counts - `markAsRead(userId, notificationId)`: Mark notification as read - `markAllAsRead(userId)`: Mark all as read - `invalidateCache(userId)`: Invalidate user caches - `scheduleBackgroundRefresh(userId)`: Schedule background refresh #### 2. **NotificationAdapter Interface** - **File**: `lib/services/notifications/notification-adapter.interface.ts` - **Purpose**: Interface for notification source adapters - **Methods**: - `getNotifications(userId, page?, limit?)`: Fetch notifications - `getNotificationCount(userId)`: Get counts - `markAsRead(userId, notificationId)`: Mark as read - `markAllAsRead(userId)`: Mark all as read - `isConfigured()`: Check if adapter is configured #### 3. **LeantimeAdapter** (Implementation) - **File**: `lib/services/notifications/leantime-adapter.ts` - **Purpose**: Leantime notification source adapter - **Features**: - Fetches notifications from Leantime API via JSON-RPC - Maps Leantime user IDs by email - Transforms Leantime notifications to unified format - Supports marking notifications as read - **Configuration**: - `LEANTIME_API_URL` environment variable - `LEANTIME_TOKEN` environment variable ### Components #### 1. **NotificationBadge** - **File**: `components/notification-badge.tsx` - **Purpose**: Notification bell icon with badge and dropdown - **Features**: - Displays unread count badge - Dropdown menu with recent notifications - Manual refresh button - Mark as read functionality - Mark all as read functionality - Source badges (e.g., "AgilitΓ©" for Leantime) - Links to source systems - Error handling and retry - **Used in**: `components/main-nav.tsx` #### 2. **MainNav** (Notification Integration) - **File**: `components/main-nav.tsx` - **Purpose**: Main navigation bar with notification badge - **Notification Features**: - Includes `` component - Browser notification permission handling - User status-based notification management ### Hooks #### 1. **useNotifications** - **File**: `hooks/use-notifications.ts` - **Purpose**: React hook for notification management - **Features**: - Automatic polling (60 seconds interval) - Rate limiting (5 seconds minimum between fetches) - Debounced count fetching (300ms) - Manual refresh support - Mount/unmount lifecycle management - Error handling - **Returns**: ```typescript { notifications: Notification[], notificationCount: NotificationCount, loading: boolean, error: string | null, fetchNotifications: (page?, limit?) => Promise, fetchNotificationCount: () => Promise, markAsRead: (notificationId: string) => Promise, markAllAsRead: () => Promise } ``` ### Types #### 1. **Notification Types** - **File**: `lib/types/notification.ts` - **Interfaces**: - `Notification`: Main notification interface - `id`: string (format: `source-sourceId`) - `source`: 'leantime' | 'nextcloud' | 'gitea' | 'dolibarr' | 'moodle' - `sourceId`: string - `type`: string - `title`: string - `message`: string - `link?`: string - `isRead`: boolean - `timestamp`: Date - `priority`: 'low' | 'normal' | 'high' - `user`: { id: string, name?: string } - `metadata?`: Record - `NotificationCount`: Count interface - `total`: number - `unread`: number - `sources`: Record --- ## 🎨 Widget Update System ### Dashboard Widgets The main dashboard (`app/page.tsx`) contains the following widgets: 1. **QuoteCard** - Daily quote widget 2. **Calendar** - Upcoming events widget 3. **News** - News articles widget 4. **Duties** - Tasks/Devoirs widget (Leantime) 5. **Email** - Email inbox widget 6. **Parole** - Chat messages widget (Rocket.Chat) ### Widget Components & Update Mechanisms #### 1. **Calendar Widget** - **Files**: - `components/calendar.tsx` (Main dashboard widget) - `components/calendar-widget.tsx` (Alternative implementation) - `components/calendar/calendar-widget.tsx` (Calendar-specific widget) - **Update Mechanism**: - **Manual Refresh**: Refresh button in header - **Auto Refresh**: Every 5 minutes (300000ms interval) - **API Endpoint**: `/api/calendars?refresh=true` - **Features**: - Fetches calendars with events - Filters upcoming events (today and future) - Sorts by date (oldest first) - Shows up to 7 events - Displays calendar color coding - **State Management**: - `useState` for events, loading, error - `useEffect` for initial fetch and interval setup #### 2. **News Widget** - **File**: `components/news.tsx` - **Update Mechanism**: - **Manual Refresh**: Refresh button in header - **Initial Load**: On component mount when authenticated - **API Endpoint**: `/api/news?limit=100` or `/api/news?refresh=true&limit=100` - **Features**: - Fetches up to 100 news articles - Displays article count - Click to open in new tab - Scrollable list (max-height: 400px) - **State Management**: - `useState` for news, loading, error, refreshing - `useEffect` for initial fetch on authentication #### 3. **Duties Widget (Tasks)** - **File**: `components/flow.tsx` - **Update Mechanism**: - **Manual Refresh**: Refresh button in header - **Initial Load**: On component mount - **API Endpoint**: `/api/leantime/tasks?refresh=true` - **Features**: - Fetches tasks from Leantime - Filters out completed tasks (status 5) - Sorts by due date (oldest first) - Shows up to 7 tasks - Displays task status badges - Links to Leantime ticket view - **State Management**: - `useState` for tasks, loading, error, refreshing - `useEffect` for initial fetch #### 4. **Email Widget** - **File**: `components/email.tsx` - **Update Mechanism**: - **Manual Refresh**: Refresh button in header - **Initial Load**: On component mount - **API Endpoint**: `/api/courrier?folder=INBOX&page=1&perPage=5` (+ `&refresh=true` for refresh) - **Features**: - Fetches 5 most recent emails from INBOX - Sorts by date (most recent first) - Shows read/unread status - Displays sender, subject, date - Link to full email view (`/courrier`) - **State Management**: - `useState` for emails, loading, error, mailUrl - `useEffect` for initial fetch #### 5. **Parole Widget (Chat Messages)** - **File**: `components/parole.tsx` - **Update Mechanism**: - **Manual Refresh**: Refresh button in header - **Auto Polling**: Every 30 seconds (30000ms interval) - **Initial Load**: On authentication - **API Endpoint**: `/api/rocket-chat/messages` (+ `?refresh=true` for refresh) - **Features**: - Fetches recent chat messages from Rocket.Chat - Displays sender avatar, name, message - Shows room/channel information - Click to navigate to full chat (`/parole`) - Authentication check with sign-in prompt - **State Management**: - `useState` for messages, loading, error, refreshing - `useEffect` for initial fetch and polling setup - Session status checking #### 6. **QuoteCard Widget** - **File**: `components/quote-card.tsx` - **Update Mechanism**: (To be verified - likely static or daily update) ### Widget Update Patterns #### Common Update Mechanisms: 1. **Manual Refresh**: - All widgets have a refresh button in their header - Triggers API call with `refresh=true` parameter - Shows loading/spinning state during refresh 2. **Auto Refresh/Polling**: - **Calendar**: 5 minutes interval - **Parole**: 30 seconds interval - Others: On component mount only 3. **Session-Based Loading**: - Widgets check authentication status - Only fetch data when `status === 'authenticated'` - Show loading state during authentication check 4. **Error Handling**: - All widgets display error messages - Retry buttons available - Graceful degradation (empty states) 5. **State Management**: - All widgets use React `useState` hooks - Loading states managed locally - Error states managed locally ### Related API Routes for Widgets #### Calendar - **GET `/api/calendars`**: Fetch calendars with events - **GET `/api/calendars/[id]/events`**: Fetch events for specific calendar - **GET `/api/calendars/[id]`**: Get calendar details #### News - **GET `/api/news`**: Fetch news articles - Query params: `limit`, `refresh` #### Tasks (Leantime) - **GET `/api/leantime/tasks`**: Fetch tasks - Query params: `refresh` #### Email (Courrier) - **GET `/api/courrier`**: Fetch emails - Query params: `folder`, `page`, `perPage`, `refresh` - **POST `/api/courrier/refresh`**: Force refresh email cache #### Chat (Rocket.Chat) - **GET `/api/rocket-chat/messages`**: Fetch messages - Query params: `refresh` --- ## πŸ“ Complete File Structure ### Notification Files ``` app/api/notifications/ β”œβ”€β”€ route.ts # GET /api/notifications β”œβ”€β”€ count/ β”‚ └── route.ts # GET /api/notifications/count β”œβ”€β”€ read-all/ β”‚ └── route.ts # POST /api/notifications/read-all └── [id]/ └── read/ └── route.ts # POST /api/notifications/[id]/read app/api/debug/ └── notifications/ └── route.ts # GET /api/debug/notifications lib/services/notifications/ β”œβ”€β”€ notification-service.ts # Core notification service β”œβ”€β”€ notification-adapter.interface.ts # Adapter interface └── leantime-adapter.ts # Leantime adapter implementation lib/types/ └── notification.ts # Notification type definitions hooks/ └── use-notifications.ts # React hook for notifications components/ β”œβ”€β”€ notification-badge.tsx # Notification UI component └── main-nav.tsx # Navigation with notification badge ``` ### Widget Files ``` app/ └── page.tsx # Main dashboard with widgets components/ β”œβ”€β”€ calendar.tsx # Calendar widget β”œβ”€β”€ calendar-widget.tsx # Alternative calendar widget β”œβ”€β”€ calendar/ β”‚ └── calendar-widget.tsx # Calendar-specific widget β”œβ”€β”€ news.tsx # News widget β”œβ”€β”€ flow.tsx # Duties/Tasks widget β”œβ”€β”€ email.tsx # Email widget β”œβ”€β”€ parole.tsx # Chat messages widget └── quote-card.tsx # Quote widget app/api/ β”œβ”€β”€ calendars/ β”‚ β”œβ”€β”€ route.ts # GET /api/calendars β”‚ └── [id]/ β”‚ └── events/ β”‚ └── route.ts # GET /api/calendars/[id]/events β”œβ”€β”€ news/ β”‚ └── route.ts # GET /api/news β”œβ”€β”€ leantime/ β”‚ └── tasks/ β”‚ └── route.ts # GET /api/leantime/tasks β”œβ”€β”€ courrier/ β”‚ β”œβ”€β”€ route.ts # GET /api/courrier β”‚ └── refresh/ β”‚ └── route.ts # POST /api/courrier/refresh └── rocket-chat/ └── messages/ └── route.ts # GET /api/rocket-chat/messages ``` --- ## πŸ”„ Update Flow Diagrams ### Notification Update Flow ``` User Action / Polling ↓ useNotifications Hook ↓ API Route (/api/notifications or /api/notifications/count) ↓ NotificationService.getInstance() ↓ Check Redis Cache β”œβ”€ Cache Hit β†’ Return cached data └─ Cache Miss β†’ Fetch from Adapters ↓ LeantimeAdapter (and other adapters) ↓ Transform & Aggregate ↓ Store in Redis Cache ↓ Return to API ↓ Return to Hook ↓ Update Component State ``` ### Widget Update Flow ``` Component Mount / User Click Refresh ↓ useEffect / onClick Handler ↓ fetch() API Call β”œβ”€ With refresh=true (manual) └─ Without refresh (initial) ↓ API Route Handler β”œβ”€ Check Cache (if applicable) β”œβ”€ Fetch from External Service └─ Return Data ↓ Update Component State β”œβ”€ setLoading(false) β”œβ”€ setData(response) └─ setError(null) ↓ Re-render Component ``` --- ## 🎯 Key Features Summary ### Notification System - βœ… Multi-source aggregation (adapter pattern) - βœ… Redis caching with TTL - βœ… Background refresh scheduling - βœ… Polling mechanism (60s interval) - βœ… Rate limiting (5s minimum) - βœ… Mark as read / Mark all as read - βœ… Cache invalidation on updates - βœ… Error handling and retry - βœ… Source badges and links ### Widget System - βœ… Manual refresh buttons - βœ… Auto-refresh/polling (widget-specific intervals) - βœ… Session-based loading - βœ… Error handling - βœ… Loading states - βœ… Empty states - βœ… Responsive design --- ## πŸ“ Notes 1. **Notification Sources**: Currently only Leantime adapter is implemented. Other adapters (Nextcloud, Gitea, Dolibarr, Moodle) are commented out in the service. 2. **Cache Strategy**: - Notification counts: 30 seconds TTL - Notification lists: 5 minutes TTL - Widget data: Varies by widget (some use API-level caching) 3. **Polling Intervals**: - Notifications: 60 seconds - Calendar widget: 5 minutes - Parole widget: 30 seconds - Other widgets: On mount only 4. **Authentication**: All notification and widget APIs require authentication via NextAuth session. 5. **Error Handling**: All components implement error states with retry mechanisms. --- ## πŸ” Debugging - Use `/api/debug/notifications` to test notification system - Check browser console for detailed logs (all components log extensively) - Check Redis cache keys: `notifications:count:{userId}`, `notifications:list:{userId}:{page}:{limit}` --- *Last Updated: Generated from codebase analysis*