From d25a2d9b6847e63e54f2e9e061f9bf98f11c3476 Mon Sep 17 00:00:00 2001 From: alma Date: Tue, 6 Jan 2026 17:29:36 +0100 Subject: [PATCH] Refactir --- NOTIFICATION_DEBUG_NEXT_STEPS.md | 200 ++++++++++++++++++ .../notifications/notification-service.ts | 37 +++- 2 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 NOTIFICATION_DEBUG_NEXT_STEPS.md diff --git a/NOTIFICATION_DEBUG_NEXT_STEPS.md b/NOTIFICATION_DEBUG_NEXT_STEPS.md new file mode 100644 index 00000000..74e119b3 --- /dev/null +++ b/NOTIFICATION_DEBUG_NEXT_STEPS.md @@ -0,0 +1,200 @@ +# Notification Mark-All-As-Read Debug - Next Steps + +**Date**: 2026-01-01 +**Status**: Enhanced logging added, awaiting test results + +--- + +## 🔍 Current Situation + +**Issue**: Mark all as read fails, but no detailed error logs are visible + +**Observation from Logs**: +``` +[NOTIFICATION_API] Mark all as read - Failed { userId: '...', duration: '209ms' } +``` + +**Missing Logs**: +- No `[LEANTIME_ADAPTER] markAllAsRead` logs +- No `[NOTIFICATION_SERVICE] markAllAsRead` detailed logs + +**Possible Causes**: +1. Server not restarted with new code +2. Adapter method not being called +3. Error happening before adapter is reached + +--- + +## ✅ Fixes Applied + +### 1. Enhanced Service Layer Logging + +**File**: `lib/services/notifications/notification-service.ts` + +**Added Logging**: +- Logs when `markAllAsRead` is called +- Logs available adapters +- Logs each adapter being processed +- Logs configuration status for each adapter +- Logs when calling adapter's `markAllAsRead` +- Logs result from each adapter +- Logs overall success/failure +- Logs cache invalidation status + +### 2. Enhanced Adapter Layer Logging + +**File**: `lib/services/notifications/leantime-adapter.ts` + +**Added Logging**: +- User email and Leantime user ID +- Request body and API URL +- Response status and body +- Parsed response with error details +- Success/failure status + +--- + +## 🚀 Next Steps + +### Step 1: Restart Server + +**CRITICAL**: The server must be restarted for the new logging to take effect. + +```bash +# Stop the server +sudo npm stop +# Or if using PM2/systemd, restart appropriately + +# Start the server +sudo npm start +``` + +### Step 2: Test Mark All As Read + +1. Open the notification dropdown +2. Click "Mark all as read" +3. Immediately check the server logs + +### Step 3: Check Logs + +**Expected Log Flow** (if working correctly): +``` +[NOTIFICATION_API] Mark all as read endpoint called +[NOTIFICATION_API] Mark all as read - Processing { userId: '...', timestamp: '...' } +[NOTIFICATION_SERVICE] markAllAsRead called for user ... +[NOTIFICATION_SERVICE] Available adapters: leantime +[NOTIFICATION_SERVICE] Processing adapter: leantime +[NOTIFICATION_SERVICE] Adapter leantime is configured: true +[NOTIFICATION_SERVICE] Calling markAllAsRead on adapter leantime +[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: XXX +[LEANTIME_ADAPTER] markAllAsRead - Response body: {...} +[LEANTIME_ADAPTER] markAllAsRead - Success: true/false +[NOTIFICATION_SERVICE] Adapter leantime markAllAsRead result: true/false +[NOTIFICATION_SERVICE] markAllAsRead overall success: true/false +``` + +**If Still Failing**, the logs will show: +- Which adapter is being processed +- Whether it's configured +- Whether the adapter method is called +- What error the Leantime API returns +- Where exactly it's failing + +--- + +## 🔍 What to Look For + +### If No Adapter Logs Appear + +**Possible Issues**: +1. Server not restarted → **Solution**: Restart server +2. Adapter not configured → Check `isConfigured()` result +3. Error in service layer → Check service layer logs + +### If Adapter Logs Appear But Fail + +**Check These**: +1. **User Email**: Should show email address +2. **Leantime User ID**: Should show numeric ID (e.g., `2`) +3. **Request Body**: Should show valid JSON-RPC request +4. **Response Status**: + - `200` = Success (but check result) + - `400` = Bad request (check error body) + - `401` = Authentication issue + - `500` = Server error +5. **Response Body**: Will show the actual error from Leantime + +### Common Leantime API Errors + +1. **Method Not Found**: + - Error: `"Method not found"` + - Fix: Verify method name is correct + +2. **Invalid Parameters**: + - Error: `"Invalid params"` + - Fix: Check parameter format + +3. **Authentication Failed**: + - Error: `"Unauthorized"` or `401` + - Fix: Check API token + +4. **User Not Found**: + - Error: `"User not found"` + - Fix: Verify Leantime user ID mapping + +--- + +## 📊 Expected Log Output Examples + +### Success Case +``` +[LEANTIME_ADAPTER] markAllAsRead - Response status: 200 +[LEANTIME_ADAPTER] markAllAsRead - Response body: {"jsonrpc":"2.0","result":true,"id":1} +[LEANTIME_ADAPTER] markAllAsRead - Parsed response: { hasResult: true, result: true, hasError: false } +[LEANTIME_ADAPTER] markAllAsRead - Success: true +``` + +### Failure Case - Method Not Found +``` +[LEANTIME_ADAPTER] markAllAsRead - Response status: 200 +[LEANTIME_ADAPTER] markAllAsRead - Response body: {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":1} +[LEANTIME_ADAPTER] markAllAsRead - Parsed response: { hasResult: false, hasError: true, error: {...} } +[LEANTIME_ADAPTER] markAllAsRead - API Error: { code: -32601, message: "Method not found" } +[LEANTIME_ADAPTER] markAllAsRead - Success: false +``` + +### Failure Case - Invalid Params +``` +[LEANTIME_ADAPTER] markAllAsRead - Response status: 200 +[LEANTIME_ADAPTER] markAllAsRead - Response body: {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params"},"id":1} +[LEANTIME_ADAPTER] markAllAsRead - API Error: { code: -32602, message: "Invalid params" } +``` + +--- + +## 🎯 Action Items + +1. ✅ **Restart Server** (CRITICAL) +2. ⏳ **Test Mark All As Read** +3. ⏳ **Share Complete Logs** (from endpoint call to failure) +4. ⏳ **Analyze Error Details** (once logs are available) + +--- + +## 📝 Summary + +**Status**: Enhanced logging ready, awaiting server restart and test + +**Next**: After restart, test and share logs to identify exact failure point + +**Confidence**: 🟢 **HIGH** - Enhanced logging will reveal the root cause + +--- + +**Generated**: 2026-01-01 + diff --git a/lib/services/notifications/notification-service.ts b/lib/services/notifications/notification-service.ts index 7dc406e0..92f76ee7 100644 --- a/lib/services/notifications/notification-service.ts +++ b/lib/services/notifications/notification-service.ts @@ -255,21 +255,46 @@ export class NotificationService { * Mark all notifications from all sources as read */ async markAllAsRead(userId: string): Promise { + console.log(`[NOTIFICATION_SERVICE] markAllAsRead called for user ${userId}`); + console.log(`[NOTIFICATION_SERVICE] Available adapters: ${Array.from(this.adapters.keys()).join(', ')}`); + const promises = Array.from(this.adapters.values()) - .map(adapter => adapter.isConfigured() - .then(configured => configured ? adapter.markAllAsRead(userId) : true) - .catch(error => { - console.error(`Error marking all notifications as read for ${adapter.sourceName}:`, error); + .map(async (adapter) => { + const adapterName = adapter.sourceName; + console.log(`[NOTIFICATION_SERVICE] Processing adapter: ${adapterName}`); + + try { + const configured = await adapter.isConfigured(); + console.log(`[NOTIFICATION_SERVICE] Adapter ${adapterName} is configured: ${configured}`); + + if (!configured) { + console.log(`[NOTIFICATION_SERVICE] Skipping ${adapterName} - not configured`); + return true; // Not configured, so nothing to mark (treat as success) + } + + console.log(`[NOTIFICATION_SERVICE] Calling markAllAsRead on adapter ${adapterName}`); + const result = await adapter.markAllAsRead(userId); + console.log(`[NOTIFICATION_SERVICE] Adapter ${adapterName} markAllAsRead result: ${result}`); + return result; + } catch (error) { + console.error(`[NOTIFICATION_SERVICE] Error marking all notifications as read for ${adapterName}:`, error); + console.error(`[NOTIFICATION_SERVICE] Error stack:`, error instanceof Error ? error.stack : 'No stack'); return false; - }) - ); + } + }); const results = await Promise.all(promises); + console.log(`[NOTIFICATION_SERVICE] markAllAsRead results:`, results); + const success = results.every(result => result); + console.log(`[NOTIFICATION_SERVICE] markAllAsRead overall success: ${success}`); if (success) { + console.log(`[NOTIFICATION_SERVICE] Invalidating caches for user ${userId}`); // Invalidate caches await this.invalidateCache(userId); + } else { + console.log(`[NOTIFICATION_SERVICE] Not invalidating caches - operation failed`); } return success;