# 🐛 Notification API 500 Error - Fixed ## Issue **Error**: 500 Internal Server Error **Endpoint**: `GET /api/notifications?page=1&limit=20` **URL**: https://chitfund.deepteklabs.com/api/notifications --- ## Root Cause The notifications route was using **Mongoose** (MongoDB) methods like: - `.find()` - `.countDocuments()` - `.populate()` - `.aggregate()` But your Notification model is using **Sequelize** (PostgreSQL). This mismatch caused the 500 error. --- ## What Was Fixed ### File: `backend/src/routes/notifications.js` #### 1. GET /api/notifications Route **Before** (Mongoose - Wrong!): ```javascript const notifications = await Notification.find(query) .sort({ createdAt: -1 }) .limit(parseInt(limit)) .skip((parseInt(page) - 1) * parseInt(limit)) .populate('group_id', 'name'); const total = await Notification.countDocuments(query); ``` **After** (Sequelize - Correct!): ```javascript const { count, rows: notifications } = await Notification.findAndCountAll({ where, order: [['created_at', 'DESC']], limit: parseInt(limit), offset: offset, include: [ { model: ChitGroup, as: 'group', attributes: ['name'], required: false } ] }); ``` #### 2. GET /api/notifications/stats Route **Before** (Mongoose - Wrong!): ```javascript const total = await Notification.countDocuments({ user_id: req.user.id }); const byType = await Notification.aggregate([ { $match: { user_id: req.user.id } }, { $group: { _id: '$type', count: { $sum: 1 } } } ]); ``` **After** (Sequelize - Correct!): ```javascript const total = await Notification.count({ where: { user_id: req.user.id } }); const byType = await Notification.findAll({ attributes: [ 'type', [Sequelize.fn('COUNT', Sequelize.col('type')), 'count'] ], where: { user_id: req.user.id }, group: ['type'], raw: true }); ``` --- ## Mongoose vs Sequelize Method Comparison | Operation | Mongoose (MongoDB) | Sequelize (PostgreSQL) | |-----------|-------------------|------------------------| | **Find with filter** | `.find(query)` | `.findAll({ where })` | | **Count** | `.countDocuments(query)` | `.count({ where })` | | **Sort** | `.sort({ field: -1 })` | `order: [['field', 'DESC']]` | | **Limit** | `.limit(10)` | `limit: 10` | | **Skip/Offset** | `.skip(20)` | `offset: 20` | | **Populate/Join** | `.populate('field', 'name')` | `include: [{ model, as, attributes }]` | | **Aggregate** | `.aggregate([...])` | `attributes: [Sequelize.fn(...)]` | | **Find and count** | N/A | `.findAndCountAll({ ... })` | --- ## How to Deploy ### Step 1: Commit Changes ```bash git add backend/src/routes/notifications.js git commit -m "Fix notification API - use Sequelize instead of Mongoose" git push origin prodnew ``` ### Step 2: Deploy to Production ```bash ssh luckychit@192.168.8.148 cd /home/luckychit/apps/chitfund ./scripts/deploy.sh backend ``` ### Step 3: Verify Fix ```bash # Test the API curl -H "Authorization: Bearer YOUR_TOKEN" \ https://chitfund.deepteklabs.com/api/notifications?page=1&limit=20 # Should return: { "success": true, "data": { "notifications": [...], "pagination": {...} } } ``` --- ## Expected Response Format ### GET /api/notifications ```json { "success": true, "data": { "notifications": [ { "id": "uuid", "type": "payment_reminder", "user_id": "uuid", "group_id": "uuid", "title": "Payment Reminder", "message": "Your payment is due...", "status": "sent", "priority": "high", "created_at": "2025-11-06T...", "read_at": null, "group": { "name": "Group A" } } ], "pagination": { "currentPage": 1, "totalPages": 1, "totalItems": 0, "itemsPerPage": 20 } } } ``` ### GET /api/notifications/stats ```json { "success": true, "data": { "total": 10, "unread": 5, "read": 5, "by_type": [ { "type": "payment_reminder", "count": "3" }, { "type": "draw_result", "count": "2" } ] } } ``` --- ## Testing ### 1. Test Empty Response (No Notifications) ```bash # Should return empty array with pagination curl -H "Authorization: Bearer TOKEN" \ https://chitfund.deepteklabs.com/api/notifications ``` **Expected**: ```json { "success": true, "data": { "notifications": [], "pagination": { "currentPage": 1, "totalPages": 0, "totalItems": 0, "itemsPerPage": 20 } } } ``` ### 2. Test with Filters ```bash # Filter by type curl -H "Authorization: Bearer TOKEN" \ "https://chitfund.deepteklabs.com/api/notifications?type=payment_reminder" # Filter by status curl -H "Authorization: Bearer TOKEN" \ "https://chitfund.deepteklabs.com/api/notifications?status=sent" ``` ### 3. Test Stats Endpoint ```bash curl -H "Authorization: Bearer TOKEN" \ https://chitfund.deepteklabs.com/api/notifications/stats ``` --- ## Why This Happened This is a common issue when: 1. Copying code from a MongoDB project to a PostgreSQL project 2. Using boilerplate code without adapting it 3. Not testing API endpoints before deployment --- ## Prevention ### 1. Always Check Database Type ```javascript // PostgreSQL → Use Sequelize methods // MongoDB → Use Mongoose methods ``` ### 2. Test Before Deploying ```bash # Test locally first npm start curl http://localhost:3000/api/notifications ``` ### 3. Use Consistent Patterns All your other models use Sequelize correctly. This was an isolated issue in the notifications route. --- ## Related Files - `backend/src/routes/notifications.js` ✅ Fixed - `backend/src/models/Notification.js` ✅ Already correct (Sequelize) - `backend/src/models/index.js` ✅ Associations defined correctly --- ## Summary **Problem**: Route used Mongoose methods with Sequelize model **Solution**: Converted to proper Sequelize syntax **Status**: ✅ Fixed **Deploy**: `./scripts/deploy.sh backend` --- **The notification API should now work correctly!** 🎉