Refactir
This commit is contained in:
parent
1935fc1a1e
commit
d25a2d9b68
200
NOTIFICATION_DEBUG_NEXT_STEPS.md
Normal file
200
NOTIFICATION_DEBUG_NEXT_STEPS.md
Normal file
@ -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
|
||||||
|
|
||||||
@ -255,21 +255,46 @@ export class NotificationService {
|
|||||||
* Mark all notifications from all sources as read
|
* Mark all notifications from all sources as read
|
||||||
*/
|
*/
|
||||||
async markAllAsRead(userId: string): Promise<boolean> {
|
async markAllAsRead(userId: string): Promise<boolean> {
|
||||||
|
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())
|
const promises = Array.from(this.adapters.values())
|
||||||
.map(adapter => adapter.isConfigured()
|
.map(async (adapter) => {
|
||||||
.then(configured => configured ? adapter.markAllAsRead(userId) : true)
|
const adapterName = adapter.sourceName;
|
||||||
.catch(error => {
|
console.log(`[NOTIFICATION_SERVICE] Processing adapter: ${adapterName}`);
|
||||||
console.error(`Error marking all notifications as read for ${adapter.sourceName}:`, error);
|
|
||||||
|
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;
|
return false;
|
||||||
})
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
const results = await Promise.all(promises);
|
const results = await Promise.all(promises);
|
||||||
|
console.log(`[NOTIFICATION_SERVICE] markAllAsRead results:`, results);
|
||||||
|
|
||||||
const success = results.every(result => result);
|
const success = results.every(result => result);
|
||||||
|
console.log(`[NOTIFICATION_SERVICE] markAllAsRead overall success: ${success}`);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
console.log(`[NOTIFICATION_SERVICE] Invalidating caches for user ${userId}`);
|
||||||
// Invalidate caches
|
// Invalidate caches
|
||||||
await this.invalidateCache(userId);
|
await this.invalidateCache(userId);
|
||||||
|
} else {
|
||||||
|
console.log(`[NOTIFICATION_SERVICE] Not invalidating caches - operation failed`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user