This commit is contained in:
alma 2026-01-06 17:13:24 +01:00
parent d0a4e6fd8d
commit 1935fc1a1e
5 changed files with 870 additions and 7 deletions

342
LOG_FLOW_ANALYSIS.md Normal file
View File

@ -0,0 +1,342 @@
# Log Flow Analysis - Application Startup & Runtime
**Date**: 2026-01-01
**Log Source**: Application startup and initial page load
**Analysis Focus**: Flow patterns, errors, and system behavior
---
## 🔍 Executive Summary
**Overall Status**: 🟡 **MOSTLY HEALTHY** with one non-critical error
**Key Findings**:
1. ⚠️ **Syntax Error**: Non-critical error during startup (doesn't block execution)
2. ✅ **Session Management**: Working correctly (5 session callbacks during startup)
3. ✅ **Notification Service**: Initialized and functioning (100 total, 66 unread)
4. ✅ **External Services**: All connecting successfully
5. ⚠️ **No Mark-as-Read Activity**: No API calls to mark notifications as read
---
## 📊 Flow Breakdown
### Phase 1: Application Startup (Lines 1-33)
```
1. Next.js starts (1313ms)
2. Redis connection established ✅
3. Microsoft OAuth configuration loaded ✅
4. ⚠️ SyntaxError: Unexpected identifier 'http' (line 29)
5. Redis connection warmed up ✅
```
**Observations**:
- ✅ Startup is fast (1.3 seconds)
- ✅ Redis connection successful
- ⚠️ **Syntax Error** appears but doesn't block execution
- Error occurs between Redis warmup calls
**Syntax Error Details**:
```
SyntaxError: Unexpected identifier 'http'
at Object.Function [as get] (<anonymous>) {
digest: '2421336728'
}
```
**Analysis**:
- Error is in a route handler (Function.get)
- Likely related to a route file with syntax issue
- Doesn't crash the application
- May be related to dynamic route generation
**Recommendation**: Investigate route files for syntax errors, especially those using `http` in identifiers.
---
### Phase 2: Initial Session Creation (Lines 34-71)
```
1. Session callback triggered
2. Token validation ✅
3. User roles extracted ✅
4. Session created successfully ✅
```
**Session Details**:
- User ID: `203cbc91-61ab-47a2-95d2-b5e1159327d7`
- Email: `a.tmiri@clm.foundation`
- Roles: `['expression', 'entrepreneurship', 'admin', 'dataintelligence', 'mediation', 'mentors']`
- Tokens: Access token ✅, Refresh token ✅
**Status**: ✅ **HEALTHY**
---
### Phase 3: Rocket.Chat Integration (Lines 72-91)
```
1. Rocket.Chat base URL: https://parole.slm-lab.net ✅
2. Users list fetched (13 users) ✅
3. User found: aminetmiri ✅
4. Subscriptions filtered (1 room) ✅
5. Messages fetched (5 messages) ✅
6. Messages cached ✅
7. ⚠️ "No valid session or email found" (line 92)
```
**Observations**:
- ✅ Rocket.Chat integration working
- ✅ User authentication successful
- ✅ Messages retrieved and cached
- ⚠️ Warning message at line 92 (may be from another service)
**Status**: ✅ **HEALTHY** (warning is likely from a different service)
---
### Phase 4: Additional Session Callbacks (Lines 93-169)
```
1. Session callback #2 (lines 93-130)
2. Session callback #3 (lines 132-169)
```
**Pattern**: Multiple session callbacks during initial page load
**Frequency**: 3 session callbacks in ~40 lines of log
**Analysis**:
- Normal behavior for Next.js with multiple API routes
- Each `getServerSession()` call triggers session callback
- All callbacks successful ✅
**Status**: ✅ **NORMAL** (but verbose logging as discussed)
---
### Phase 5: Notification Service Initialization (Lines 170-246)
```
1. Notification service instance created ✅
2. Leantime adapter initialized ✅
3. Adapter registered ✅
4. getNotificationCount called ✅
5. Leantime API called ✅
6. Response received (200) ✅
7. Notifications parsed ✅
8. Count calculated: 100 total, 66 unread ✅
9. Counts cached ✅
```
**Notification Details**:
- **Total**: 100 notifications
- **Unread**: 66 notifications
- **Source**: Leantime
- **Status**: ✅ **WORKING CORRECTLY**
**Flow**:
```
[NOTIFICATION_SERVICE] → [LEANTIME_ADAPTER] → Leantime API → Parse → Cache
```
**Status**: ✅ **HEALTHY**
---
### Phase 6: Additional Operations (Lines 247-289)
```
1. IMAP pool status logged
2. Session callback #4 (lines 248-285)
3. Cached messages used
4. IMAP pool status logged again
```
**Observations**:
- ✅ IMAP connection pool healthy (0 active, max 20)
- ✅ Session callbacks continuing (normal)
- ✅ Caching working (messages from cache)
**Status**: ✅ **HEALTHY**
---
## 🔴 Issues Identified
### 1. Syntax Error (Line 29) ⚠️
**Error**:
```
SyntaxError: Unexpected identifier 'http'
at Object.Function [as get] (<anonymous>)
```
**Impact**:
- ⚠️ **Low**: Doesn't crash application
- ⚠️ **Unknown**: May affect specific route
- ⚠️ **Non-blocking**: Application continues normally
**Possible Causes**:
1. Route file with syntax error
2. Dynamic route generation issue
3. Template literal or string interpolation problem
4. Environment variable parsing issue
**Investigation Steps**:
1. Search codebase for routes using `http` as identifier
2. Check dynamic route files
3. Review route handlers for syntax errors
4. Check Next.js route generation
**Priority**: 🟡 **MEDIUM** - Should be fixed but not blocking
---
### 2. "No valid session or email found" (Line 92) ⚠️
**Message**: `No valid session or email found`
**Context**: Appears after Rocket.Chat operations
**Analysis**:
- May be from a different service/route
- Doesn't affect Rocket.Chat functionality
- Could be from email service or another API route
**Investigation**: Check which service logs this message
**Priority**: 🟡 **LOW** - Appears to be a warning, not an error
---
### 3. No Mark-as-Read Activity ⚠️
**Observation**: No `[NOTIFICATION_API]` log entries
**Expected**: Should see logs when user marks notifications as read
**Possible Reasons**:
1. User hasn't tested mark-as-read yet
2. API calls not reaching server
3. Client-side errors preventing API calls
**Status**: ⏳ **PENDING TESTING**
**Action**: Test mark-as-read functionality and check for new log entries
---
## ✅ Positive Observations
### 1. Fast Startup
- ✅ Application ready in 1.3 seconds
- ✅ All services initialized quickly
### 2. Session Management
- ✅ All session callbacks successful
- ✅ Token validation working
- ✅ User roles extracted correctly
### 3. Notification Service
- ✅ Service initialized correctly
- ✅ Leantime adapter working
- ✅ API calls successful
- ✅ Caching functioning
### 4. External Services
- ✅ Redis connected
- ✅ Rocket.Chat connected
- ✅ Leantime API responding
- ✅ IMAP pool healthy
---
## 📈 Performance Metrics
| Metric | Value | Status |
|--------|-------|--------|
| Startup Time | 1313ms | ✅ Good |
| Redis Connection | ✅ Success | ✅ Good |
| Session Callbacks | 5 during startup | ✅ Normal |
| Notification Count | 100 total, 66 unread | ✅ Working |
| Rocket.Chat | ✅ Connected | ✅ Good |
| IMAP Pool | 0/20 active | ✅ Healthy |
---
## 🔄 Flow Patterns
### Session Callback Pattern
```
Every getServerSession() call → Session callback → Token validation → Session created
```
**Frequency**: 5 times during startup (normal for multi-route page)
**Recommendation**: Conditional logging (as discussed in impact analysis)
---
### Notification Service Pattern
```
Service init → Adapter registration → API call → Parse → Cache
```
**Status**: ✅ Working correctly
---
## 🎯 Recommendations
### Immediate Actions
1. **Investigate Syntax Error** 🔴
- Search for route files with `http` identifier
- Check dynamic routes
- Fix syntax error
2. **Test Mark-as-Read** 🟡
- Mark a notification as read
- Check logs for `[NOTIFICATION_API]` entries
- Verify notification count updates
3. **Identify "No valid session" Source** 🟡
- Find which service logs this message
- Determine if it's an error or warning
- Fix if necessary
### Future Improvements
4. **Implement Conditional Session Logging** (as planned)
- Add `DEBUG_SESSION` flag
- Reduce production logging
- Keep error logging
5. **Add Error Monitoring**
- Track syntax errors
- Monitor route handler failures
- Alert on critical errors
---
## 📝 Summary
**Overall Assessment**: 🟢 **HEALTHY** with minor issues
**Critical Issues**: 0
**Warnings**: 2 (syntax error, "no valid session" message)
**Working Correctly**: ✅ All core functionality
**Next Steps**:
1. Fix syntax error (investigate route files)
2. Test mark-as-read functionality
3. Identify source of "no valid session" message
4. Proceed with conditional session logging (when ready)
---
**Generated**: 2026-01-01
**Status**: Ready for action items

194
NOTIFICATION_ISSUES_FIX.md Normal file
View File

@ -0,0 +1,194 @@
# Notification Issues - Analysis & Fixes
**Date**: 2026-01-01
**Issues Reported**:
1. Count shows 66 messages, but only 10 are displayed
2. "Mark all as read" fails
3. Count doesn't update after marking as read
---
## 🔍 Issue Analysis
### Issue 1: Count vs Display Discrepancy
**Symptom**:
- Badge shows: **66 unread notifications**
- Dropdown shows: **Only 10 notifications**
**Root Cause**:
1. **Count Logic**: `getNotificationCount()` calls `getNotifications(userId, 1, 100)` to count
- Gets first 100 notifications from Leantime
- Counts unread: 66
- This is correct for the first 100 notifications
2. **Display Logic**: `getNotifications()` is called with `limit: 20` (default)
- But only 10 are shown (possibly due to pagination or filtering)
- This is a display/pagination issue
**The Problem**:
- If Leantime has more than 100 notifications total, the count will be inaccurate
- The count only reflects the first 100 notifications
- Display shows fewer notifications than the count
**Solution**:
- ✅ Added warning log when count reaches 100 (may have more)
- ⚠️ Consider using a dedicated count API if Leantime provides one
- ⚠️ Consider fetching all notifications for accurate count (may be slow)
---
### Issue 2: Mark All As Read Fails
**Symptom**:
```
[NOTIFICATION_API] Mark all as read - Failed { userId: '...', duration: '197ms' }
```
**Root Cause**:
- Leantime API call is failing
- No detailed error logging to see why
**Solution Applied**:
- ✅ Added comprehensive error logging to `markAllAsRead()`:
- Logs user email and Leantime user ID
- Logs request body and API URL
- Logs response status and body
- Logs parsed response with error details
- Logs exceptions with stack traces
**Next Steps**:
1. Test mark-all-as-read again
2. Check logs for detailed error information
3. Verify Leantime API method name is correct
4. Check if Leantime API requires different parameters
---
## 🔧 Fixes Applied
### 1. Enhanced Error Logging in `markAllAsRead`
**File**: `lib/services/notifications/leantime-adapter.ts`
**Changes**:
- Added detailed logging at each step
- Logs request details (body, URL)
- Logs response details (status, body, parsed data)
- Logs errors with full context
- Logs success/failure status
**Expected Log Output**:
```
[LEANTIME_ADAPTER] markAllAsRead called for ...
[LEANTIME_ADAPTER] markAllAsRead - User email: ...
[LEANTIME_ADAPTER] markAllAsRead - Leantime user ID: ...
[LEANTIME_ADAPTER] markAllAsRead - Request body: {...}
[LEANTIME_ADAPTER] markAllAsRead - API URL: ...
[LEANTIME_ADAPTER] markAllAsRead - Response status: 200
[LEANTIME_ADAPTER] markAllAsRead - Response body: {...}
[LEANTIME_ADAPTER] markAllAsRead - Parsed response: {...}
[LEANTIME_ADAPTER] markAllAsRead - Success: true/false
```
---
### 2. Enhanced Count Logging
**File**: `lib/services/notifications/leantime-adapter.ts`
**Changes**:
- Added warning when count reaches 100 (may have more notifications)
- Added read count to logging
- Added note about potential inaccuracy
---
## 🎯 Next Steps
### Immediate Testing
1. **Test Mark All As Read**
- Click "Mark all as read"
- Check logs for detailed error information
- Look for `[LEANTIME_ADAPTER] markAllAsRead` entries
2. **Verify Count Accuracy**
- Check if Leantime has more than 100 notifications
- Verify count matches actual unread notifications
- Check if count updates after marking as read
### Potential Issues to Check
1. **Leantime API Method Name**
- Current: `leantime.rpc.Notifications.Notifications.markAllNotificationsAsRead`
- Verify this is the correct method name in Leantime API
2. **Leantime API Parameters**
- Current: `{ userId: leantimeUserId }`
- May need additional parameters
3. **Leantime API Response Format**
- Check if response format matches expected format
- May need to handle different response structures
---
## 📊 Expected Behavior After Fixes
### Mark All As Read
**Success Case**:
```
[NOTIFICATION_API] Mark all as read endpoint called
[NOTIFICATION_API] Mark all as read - Processing { userId: '...', timestamp: '...' }
[LEANTIME_ADAPTER] markAllAsRead called for ...
[LEANTIME_ADAPTER] markAllAsRead - Success: true
[NOTIFICATION_API] Mark all as read - Success { userId: '...', duration: 'Xms' }
[NOTIFICATION_SERVICE] Invalidated notification caches for user ...
```
**Failure Case** (with detailed error):
```
[NOTIFICATION_API] Mark all as read endpoint called
[LEANTIME_ADAPTER] markAllAsRead called for ...
[LEANTIME_ADAPTER] markAllAsRead - Response status: 400
[LEANTIME_ADAPTER] markAllAsRead - Response body: {"error": {...}}
[LEANTIME_ADAPTER] markAllAsRead - API Error: {...}
[NOTIFICATION_API] Mark all as read - Failed { userId: '...', duration: 'Xms' }
```
---
## 🔍 Debugging Checklist
When testing, check logs for:
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - User email:` (should show email)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Leantime user ID:` (should show ID)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Request body:` (should show JSON-RPC request)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Response status:` (should be 200 for success)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Response body:` (should show API response)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Parsed response:` (should show result/error)
- [ ] `[LEANTIME_ADAPTER] markAllAsRead - Success:` (should be true/false)
---
## 📝 Summary
**Fixes Applied**:
1. ✅ Enhanced error logging in `markAllAsRead`
2. ✅ Enhanced count logging with warnings
**Next Actions**:
1. Test mark-all-as-read functionality
2. Review detailed error logs
3. Fix Leantime API call based on error details
4. Verify count accuracy
**Status**: ⏳ **AWAITING TESTING** - Enhanced logging will reveal the root cause
---
**Generated**: 2026-01-01

288
Untitled Normal file
View File

@ -0,0 +1,288 @@
alma@central:~/nextgen/NeahNew$ sudo npm start
> neah@0.1.0 start
> next start
▲ Next.js 15.3.1
- Local: http://localhost:3000
- Network: http://172.16.0.102:3000
✓ Starting...
✓ Ready in 1313ms
Connecting to Redis using environment variables
Microsoft OAuth Configuration: {
tenantId: 'cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2',
authorizeUrl: 'https://login.microsoftonline.com/cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2/oauth2/v2.0/authorize',
tokenUrl: 'https://login.microsoftonline.com/cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2/oauth2/v2.0/token',
clientIdFirstChars: 'afaff...',
redirectUri: 'https://hub.slm-lab.net/ms'
}
Microsoft OAuth Configuration: {
tenantId: 'cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2',
authorizeUrl: 'https://login.microsoftonline.com/cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2/oauth2/v2.0/authorize',
tokenUrl: 'https://login.microsoftonline.com/cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2/oauth2/v2.0/token',
clientIdFirstChars: 'afaff...',
redirectUri: 'https://hub.slm-lab.net/ms'
}
Successfully connected to Redis
Redis connection warmed up
SyntaxError: Unexpected identifier 'http'
at Object.Function [as get] (<anonymous>) {
digest: '2421336728'
}
Redis connection warmed up
=== SESSION CALLBACK START ===
Token error: undefined
Has accessToken: true
Has refreshToken: true
Token role: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Token sub: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Token email: a.tmiri@clm.foundation
Token name: Amine TMIRI
Token username: aminetmiri
User roles for session: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Creating session user object...
Setting session tokens...
✅ Session created successfully
Session user id: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Session user email: a.tmiri@clm.foundation
Session user roles: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
=== SESSION CALLBACK END ===
Using Rocket.Chat base URL: https://parole.slm-lab.net
Users list response: { success: true, count: 13, usersCount: 13 }
Found Rocket.Chat user: { username: 'aminetmiri', id: 'a9HwLtHagiRnTWeS5' }
Filtered user subscriptions: {
userId: 'a9HwLtHagiRnTWeS5',
username: 'aminetmiri',
totalSubscriptions: 1,
subscriptionDetails: [
{
type: 'd',
name: 'Rocket.Cat',
rid: 'a9HwLtHagiRnTWeS5rocket.cat',
alert: true,
unread: 3,
userMentions: 0
}
]
}
Messages for room Rocket.Cat: { success: true, count: 5, hasMessages: true }
Messages data cached for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
No valid session or email found
=== SESSION CALLBACK START ===
Token error: undefined
Has accessToken: true
Has refreshToken: true
Token role: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Token sub: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Token email: a.tmiri@clm.foundation
Token name: Amine TMIRI
Token username: aminetmiri
User roles for session: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Creating session user object...
Setting session tokens...
✅ Session created successfully
Session user id: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Session user email: a.tmiri@clm.foundation
Session user roles: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
=== SESSION CALLBACK END ===
Using cached messages data for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
=== SESSION CALLBACK START ===
Token error: undefined
Has accessToken: true
Has refreshToken: true
Token role: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Token sub: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Token email: a.tmiri@clm.foundation
Token name: Amine TMIRI
Token username: aminetmiri
User roles for session: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Creating session user object...
Setting session tokens...
✅ Session created successfully
Session user id: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Session user email: a.tmiri@clm.foundation
Session user roles: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
=== SESSION CALLBACK END ===
[NOTIFICATION_SERVICE] Creating new notification service instance
[NOTIFICATION_SERVICE] Initializing notification service
[LEANTIME_ADAPTER] Initialized with API URL and token
[NOTIFICATION_SERVICE] Registered notification adapter: leantime
[NOTIFICATION_SERVICE] Registered adapters: [ 'leantime' ]
[NOTIFICATION_SERVICE] getNotificationCount called for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
[NOTIFICATION_SERVICE] Fetching notification counts for user 203cbc91-61ab-47a2-95d2-b5e1159327d7 from 1 adapters
[NOTIFICATION_SERVICE] Available adapters for count: leantime
[NOTIFICATION_SERVICE] Checking if adapter leantime is configured for count
[NOTIFICATION_SERVICE] Adapter leantime is configured for count: true
[NOTIFICATION_SERVICE] Fetching notification count from leantime for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
[LEANTIME_ADAPTER] getNotificationCount called for userId: 203cbc91-61ab-47a2-95d2-b5e1159327d7
[LEANTIME_ADAPTER] getNotifications called for userId: 203cbc91-61ab-47a2-95d2-b5e1159327d7, page: 1, limit: 100
=== SESSION CALLBACK START ===
Token error: undefined
Has accessToken: true
Has refreshToken: true
Token role: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Token sub: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Token email: a.tmiri@clm.foundation
Token name: Amine TMIRI
Token username: aminetmiri
User roles for session: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Creating session user object...
Setting session tokens...
✅ Session created successfully
Session user id: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Session user email: a.tmiri@clm.foundation
Session user roles: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
=== SESSION CALLBACK END ===
[LEANTIME_ADAPTER] Retrieved email from session: a.tmiri@clm.foundation
[LEANTIME_ADAPTER] Retrieved Leantime userId for email a.tmiri@clm.foundation: 2
[LEANTIME_ADAPTER] Sending request to get all notifications
[LEANTIME_ADAPTER] Request body: {"jsonrpc":"2.0","method":"leantime.rpc.Notifications.Notifications.getAllNotifications","params":{"userId":2,"showNewOnly":0,"limitStart":0,"limitEnd":100,"filterOptions":[]},"id":1}
[LEANTIME_ADAPTER] Response status: 200
[LEANTIME_ADAPTER] Raw response (truncated): {"jsonrpc":"2.0","result":[{"id":2732,"0":2732,"userId":2,"1":2,"read":0,"2":0,"type":"projectUpdate","3":"projectUpdate","module":"tickets","4":"tickets","moduleId":225,"5":225,"datetime":"2025-12-24...
[LEANTIME_ADAPTER] Parsed response data: {
hasResult: true,
resultIsArray: true,
resultLength: 100,
error: undefined
}
[LEANTIME_ADAPTER] Transformed notifications count: 100
[LEANTIME_ADAPTER] Notification counts: { total: 100, unread: 66 }
[NOTIFICATION_SERVICE] Got count from leantime: {
total: 100,
unread: 66,
sources: { leantime: { total: 100, unread: 66 } }
}
[NOTIFICATION_SERVICE] Adding counts from leantime: total=100, unread=66
[NOTIFICATION_SERVICE] Aggregated counts for user 203cbc91-61ab-47a2-95d2-b5e1159327d7: {
total: 100,
unread: 66,
sources: { leantime: { total: 100, unread: 66 } }
}
[NOTIFICATION_SERVICE] Cached notification counts for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
[IMAP POOL] Size: 0, Active: 0, Connecting: 0, Max: 20
=== SESSION CALLBACK START ===
Token error: undefined
Has accessToken: true
Has refreshToken: true
Token role: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Token sub: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Token email: a.tmiri@clm.foundation
Token name: Amine TMIRI
Token username: aminetmiri
User roles for session: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
Creating session user object...
Setting session tokens...
✅ Session created successfully
Session user id: 203cbc91-61ab-47a2-95d2-b5e1159327d7
Session user email: a.tmiri@clm.foundation
Session user roles: [
'expression',
'entrepreneurship',
'admin',
'dataintelligence',
'mediation',
'mentors'
]
=== SESSION CALLBACK END ===
Using cached messages data for user 203cbc91-61ab-47a2-95d2-b5e1159327d7
[IMAP POOL] Size: 0, Active: 0, Connecting: 0, Max: 20

View File

@ -123,6 +123,8 @@ export class LeantimeAdapter implements NotificationAdapter {
try { try {
// Get all notifications and count them // Get all notifications and count them
// NOTE: This only gets first 100 notifications. If there are more, the count will be inaccurate.
// TODO: Consider using a dedicated count API endpoint if Leantime provides one
const notifications = await this.getNotifications(userId, 1, 100); // Get up to 100 for counting const notifications = await this.getNotifications(userId, 1, 100); // Get up to 100 for counting
// Count total and unread // Count total and unread
@ -131,7 +133,9 @@ export class LeantimeAdapter implements NotificationAdapter {
console.log('[LEANTIME_ADAPTER] Notification counts:', { console.log('[LEANTIME_ADAPTER] Notification counts:', {
total: totalCount, total: totalCount,
unread: unreadCount unread: unreadCount,
read: totalCount - unreadCount,
note: totalCount === 100 ? 'WARNING: May have more than 100 notifications total' : 'OK'
}); });
return { return {
@ -219,15 +223,17 @@ export class LeantimeAdapter implements NotificationAdapter {
// Get user email and ID // Get user email and ID
const email = await this.getUserEmail(); const email = await this.getUserEmail();
if (!email) { if (!email) {
console.error('[LEANTIME_ADAPTER] Could not get user email from session'); console.error('[LEANTIME_ADAPTER] markAllAsRead - Could not get user email from session');
return false; return false;
} }
console.log(`[LEANTIME_ADAPTER] markAllAsRead - User email: ${email}`);
const leantimeUserId = await this.getLeantimeUserId(email); const leantimeUserId = await this.getLeantimeUserId(email);
if (!leantimeUserId) { if (!leantimeUserId) {
console.error('[LEANTIME_ADAPTER] User not found in Leantime:', email); console.error('[LEANTIME_ADAPTER] markAllAsRead - User not found in Leantime:', email);
return false; return false;
} }
console.log(`[LEANTIME_ADAPTER] markAllAsRead - Leantime user ID: ${leantimeUserId}`);
// Make request to Leantime API to mark all notifications as read // Make request to Leantime API to mark all notifications as read
const jsonRpcBody = { const jsonRpcBody = {
@ -239,6 +245,9 @@ export class LeantimeAdapter implements NotificationAdapter {
id: 1 id: 1
}; };
console.log(`[LEANTIME_ADAPTER] markAllAsRead - Request body:`, JSON.stringify(jsonRpcBody));
console.log(`[LEANTIME_ADAPTER] markAllAsRead - API URL: ${this.apiUrl}/api/jsonrpc`);
const response = await fetch(`${this.apiUrl}/api/jsonrpc`, { const response = await fetch(`${this.apiUrl}/api/jsonrpc`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -248,15 +257,44 @@ export class LeantimeAdapter implements NotificationAdapter {
body: JSON.stringify(jsonRpcBody) body: JSON.stringify(jsonRpcBody)
}); });
console.log(`[LEANTIME_ADAPTER] markAllAsRead - Response status: ${response.status}`);
if (!response.ok) { if (!response.ok) {
console.error(`[LEANTIME_ADAPTER] Failed to mark all notifications as read: ${response.status}`); const errorText = await response.text();
console.error(`[LEANTIME_ADAPTER] markAllAsRead - HTTP Error ${response.status}:`, errorText.substring(0, 500));
return false; return false;
} }
const data = await response.json(); const responseText = await response.text();
return data.result === true || data.result === "true" || !!data.result; console.log(`[LEANTIME_ADAPTER] markAllAsRead - Response body:`, responseText.substring(0, 500));
let data;
try {
data = JSON.parse(responseText);
} catch (parseError) {
console.error(`[LEANTIME_ADAPTER] markAllAsRead - Failed to parse response:`, parseError);
console.error(`[LEANTIME_ADAPTER] markAllAsRead - Raw response:`, responseText);
return false;
}
console.log(`[LEANTIME_ADAPTER] markAllAsRead - Parsed response:`, {
hasResult: 'result' in data,
result: data.result,
hasError: 'error' in data,
error: data.error
});
if (data.error) {
console.error(`[LEANTIME_ADAPTER] markAllAsRead - API Error:`, data.error);
return false;
}
const success = data.result === true || data.result === "true" || !!data.result;
console.log(`[LEANTIME_ADAPTER] markAllAsRead - Success: ${success}`);
return success;
} catch (error) { } catch (error) {
console.error('[LEANTIME_ADAPTER] Error marking all notifications as read:', error); console.error('[LEANTIME_ADAPTER] markAllAsRead - Exception:', error);
console.error('[LEANTIME_ADAPTER] markAllAsRead - Error stack:', error instanceof Error ? error.stack : 'No stack');
return false; return false;
} }
} }

1
log
View File

@ -0,0 +1 @@