NeahNew/NOTIFICATION_AND_WIDGET_ANALYSIS.md
2026-01-06 13:02:07 +01:00

549 lines
16 KiB
Markdown

# 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 `<NotificationBadge />` 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<void>,
fetchNotificationCount: () => Promise<void>,
markAsRead: (notificationId: string) => Promise<boolean>,
markAllAsRead: () => Promise<boolean>
}
```
### 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<string, any>
- `NotificationCount`: Count interface
- `total`: number
- `unread`: number
- `sources`: Record<string, { total: number, unread: number }>
---
## 🎨 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*