Spaces:
Sleeping
Sleeping
Changed the structure of cases
Browse files- Dockerfile.txt +14 -0
- data.json +138 -0
- gitattributes.txt +35 -0
- index.js +54 -323
- models.js +27 -99
- package-lock.json +0 -0
- readme-2.md +611 -0
- verify_refactor.js +682 -0
Dockerfile.txt
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:18-alpine
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
|
| 5 |
+
COPY package*.json ./
|
| 6 |
+
|
| 7 |
+
RUN npm install --production
|
| 8 |
+
|
| 9 |
+
COPY . .
|
| 10 |
+
|
| 11 |
+
# Expose the port that Hugging Face expects (default is 7860)
|
| 12 |
+
EXPOSE 7860
|
| 13 |
+
|
| 14 |
+
CMD ["npm", "start"]
|
data.json
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"applicantDetail": {
|
| 3 |
+
"userId": 135860,
|
| 4 |
+
"panNumber": null,
|
| 5 |
+
"dob": "24-11-1990",
|
| 6 |
+
"voterId": "ABC1234567",
|
| 7 |
+
"email": "parvej@gmail.com",
|
| 8 |
+
"mobile": "8000051783",
|
| 9 |
+
"alternateMobile": "8000051784",
|
| 10 |
+
"socialCategoryId": 1,
|
| 11 |
+
"aadharRefNumber": "800180018019",
|
| 12 |
+
"urnNumber": null,
|
| 13 |
+
"isFromLsp": null,
|
| 14 |
+
"name": "Parvez mansuri",
|
| 15 |
+
"genderId": 1,
|
| 16 |
+
"maritalStatus": 1,
|
| 17 |
+
"qualification": 4,
|
| 18 |
+
"religion": 6,
|
| 19 |
+
"womanEntrepreneur": 0,
|
| 20 |
+
"divyang": 0,
|
| 21 |
+
"serviceman": 0,
|
| 22 |
+
"fatherName": "fname",
|
| 23 |
+
"motherName": "mname",
|
| 24 |
+
"spouseName": "sname",
|
| 25 |
+
"spouseDob": "24-11-1992",
|
| 26 |
+
"numOfDependent": 4,
|
| 27 |
+
"illness": 7,
|
| 28 |
+
"primaryId": 2,
|
| 29 |
+
"secodaryId": 1,
|
| 30 |
+
"primaryDoc": 95988,
|
| 31 |
+
"secodaryDoc": 95989,
|
| 32 |
+
"applicantImg": 95990,
|
| 33 |
+
"urnFound": 0,
|
| 34 |
+
"daId": 1,
|
| 35 |
+
"numEarFamiMemb": 1,
|
| 36 |
+
"primaryFileDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 37 |
+
"secondaryFileDetail": "certificate_1758545658.pdf | 192kb | 24/11/2025",
|
| 38 |
+
"applicantFileDetail": "certificate_1758545652.pdf | 192kb | 24/11/2025",
|
| 39 |
+
"addresProofDetail": "certificate_1758545631.pdf | 192kb | 24-11-2025",
|
| 40 |
+
"updateResiAddrss": true,
|
| 41 |
+
"profileId": 24306
|
| 42 |
+
},
|
| 43 |
+
"residenceDetail": {
|
| 44 |
+
"id": 18431,
|
| 45 |
+
"ownershipStatus": 2,
|
| 46 |
+
"address1": "test1",
|
| 47 |
+
"address2": "test2",
|
| 48 |
+
"address3": "test3",
|
| 49 |
+
"cityId": 783,
|
| 50 |
+
"districtId": 134,
|
| 51 |
+
"stateId": 24,
|
| 52 |
+
"pincode": "380001",
|
| 53 |
+
"addressProofType": 2,
|
| 54 |
+
"addressProofId": 95992,
|
| 55 |
+
"addresProofDetail": "certificate_1758545631.pdf | 192kb | 24-11-2025",
|
| 56 |
+
"updateResiAddrss": null
|
| 57 |
+
},
|
| 58 |
+
"coApplicantDetail": {
|
| 59 |
+
"name": "OPL",
|
| 60 |
+
"panNumber": null,
|
| 61 |
+
"email": null,
|
| 62 |
+
"dob": "24-11-1991",
|
| 63 |
+
"mobile": "8000051785",
|
| 64 |
+
"gender": 1,
|
| 65 |
+
"maritalStatus": 2,
|
| 66 |
+
"relationshipWithApplicantId": 6,
|
| 67 |
+
"occupationId": 2,
|
| 68 |
+
"primaryId": 2,
|
| 69 |
+
"secondaryId": 1,
|
| 70 |
+
"primaryDoc": 96005,
|
| 71 |
+
"secondaryDoc": 96006,
|
| 72 |
+
"voterId": "ABC1234567",
|
| 73 |
+
"applicantImg": 96007,
|
| 74 |
+
"sameAsResidential": false,
|
| 75 |
+
"ownership": null,
|
| 76 |
+
"address1": "test7",
|
| 77 |
+
"address2": null,
|
| 78 |
+
"address3": null,
|
| 79 |
+
"landmark": null,
|
| 80 |
+
"cityId": 783,
|
| 81 |
+
"districtId": 134,
|
| 82 |
+
"stateId": 24,
|
| 83 |
+
"pincode": "380001",
|
| 84 |
+
"applicantImgDetail": "certificate_1758545652.pdf | 192kb | 24/11/2025",
|
| 85 |
+
"primaryFileDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 86 |
+
"secondaryFileDetail": "certificate_1758545658.pdf | 192kb | 24/11/2025"
|
| 87 |
+
},
|
| 88 |
+
"businessDetail": {
|
| 89 |
+
"businessName": "parvez enterprise",
|
| 90 |
+
"businessType": 4,
|
| 91 |
+
"natureActivity": 1,
|
| 92 |
+
"areaType": 3,
|
| 93 |
+
"organizationType": 1,
|
| 94 |
+
"establishDate": "1970-01-01",
|
| 95 |
+
"panNumber": "NEMPM0285K",
|
| 96 |
+
"businessLocation": 1,
|
| 97 |
+
"workExperienceInYears": 5,
|
| 98 |
+
"addressId": 18432,
|
| 99 |
+
"ownershipStatus": 1,
|
| 100 |
+
"address1": "test4",
|
| 101 |
+
"address2": null,
|
| 102 |
+
"landmark": null,
|
| 103 |
+
"cityId": 783,
|
| 104 |
+
"districtId": 134,
|
| 105 |
+
"stateId": 24,
|
| 106 |
+
"pincode": "380001",
|
| 107 |
+
"businessProofType": 1,
|
| 108 |
+
"businessProofDoc": 95993,
|
| 109 |
+
"businessProofDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 110 |
+
"updateBusinessAddrss": true
|
| 111 |
+
},
|
| 112 |
+
"incomeExpenditure": {
|
| 113 |
+
"monthlyIncome": 60000.00,
|
| 114 |
+
"freqOfIncome": 2,
|
| 115 |
+
"incomeDays": 30,
|
| 116 |
+
"avgIncomeDailyBasis": 2000.00,
|
| 117 |
+
"yearlyIncome": 750000.00,
|
| 118 |
+
"incomeFromOtherSource": 0.00,
|
| 119 |
+
"rationCard": 0,
|
| 120 |
+
"totalIncome": 750000.00,
|
| 121 |
+
"appType": 1
|
| 122 |
+
},
|
| 123 |
+
"familyExpenses": {
|
| 124 |
+
"householdExp": 100000.00,
|
| 125 |
+
"utilityExp": 10000.00,
|
| 126 |
+
"eduExp": 11000.00,
|
| 127 |
+
"mediExp": 12000.00,
|
| 128 |
+
"mediExpCritical": 13000.00,
|
| 129 |
+
"foodExp": 14000.00,
|
| 130 |
+
"grocExp": 15000.00,
|
| 131 |
+
"cookingExp": 16000.00,
|
| 132 |
+
"otherExp": 17000.00,
|
| 133 |
+
"clothing": 18000.00,
|
| 134 |
+
"transpExp": 19000.00,
|
| 135 |
+
"otherBusiExp": 20000.00,
|
| 136 |
+
"totalExp": 265000.00
|
| 137 |
+
}
|
| 138 |
+
}
|
gitattributes.txt
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
index.js
CHANGED
|
@@ -1236,80 +1236,7 @@ app.put('/api/cases/:case_id', authenticateToken, requireAgentOrAdmin, async (re
|
|
| 1236 |
}
|
| 1237 |
if (req.body.remarks) updateData.remarks = req.body.remarks;
|
| 1238 |
|
| 1239 |
-
|
| 1240 |
-
const demo = req.body.demographic_details;
|
| 1241 |
-
const currentDemo = caseDoc.demographic_details || {};
|
| 1242 |
-
|
| 1243 |
-
updateData.demographic_details = {
|
| 1244 |
-
...currentDemo,
|
| 1245 |
-
...(demo.aadhaar_photo_match !== undefined && { aadhaar_photo_match: demo.aadhaar_photo_match }),
|
| 1246 |
-
contact_information: {
|
| 1247 |
-
...(currentDemo.contact_information || {}),
|
| 1248 |
-
...(demo.contact_information || {})
|
| 1249 |
-
},
|
| 1250 |
-
personal_details: {
|
| 1251 |
-
...(currentDemo.personal_details || {}),
|
| 1252 |
-
...(demo.personal_details || {})
|
| 1253 |
-
},
|
| 1254 |
-
...(demo.customer_photo_id && { customer_photo_id: demo.customer_photo_id }),
|
| 1255 |
-
address_details: {
|
| 1256 |
-
...(currentDemo.address_details || {}),
|
| 1257 |
-
...(demo.address_details || {})
|
| 1258 |
-
},
|
| 1259 |
-
...(demo.residence_photo_id && { residence_photo_id: demo.residence_photo_id })
|
| 1260 |
-
};
|
| 1261 |
-
}
|
| 1262 |
-
|
| 1263 |
-
if (req.body.business_details) {
|
| 1264 |
-
const biz = req.body.business_details;
|
| 1265 |
-
const currentBiz = caseDoc.business_details || {};
|
| 1266 |
-
|
| 1267 |
-
updateData.business_details = {
|
| 1268 |
-
...currentBiz,
|
| 1269 |
-
enterprise_information: {
|
| 1270 |
-
...(currentBiz.enterprise_information || {}),
|
| 1271 |
-
...(biz.enterprise_information || {})
|
| 1272 |
-
},
|
| 1273 |
-
business_location_details: {
|
| 1274 |
-
...(currentBiz.business_location_details || {}),
|
| 1275 |
-
...(biz.business_location_details || {})
|
| 1276 |
-
},
|
| 1277 |
-
business_address: {
|
| 1278 |
-
...(currentBiz.business_address || {}),
|
| 1279 |
-
...(biz.business_address || {})
|
| 1280 |
-
},
|
| 1281 |
-
...(biz.business_address_photo_id && { business_address_photo_id: biz.business_address_photo_id }),
|
| 1282 |
-
business_activity: {
|
| 1283 |
-
...(currentBiz.business_activity || {}),
|
| 1284 |
-
...(biz.business_activity || {})
|
| 1285 |
-
},
|
| 1286 |
-
business_info: {
|
| 1287 |
-
...(currentBiz.business_info || {}),
|
| 1288 |
-
...(biz.business_info || {})
|
| 1289 |
-
}
|
| 1290 |
-
};
|
| 1291 |
-
}
|
| 1292 |
-
|
| 1293 |
-
if (req.body.financial_details) {
|
| 1294 |
-
const fin = req.body.financial_details;
|
| 1295 |
-
const currentFin = caseDoc.financial_details || {};
|
| 1296 |
-
|
| 1297 |
-
updateData.financial_details = {
|
| 1298 |
-
...currentFin,
|
| 1299 |
-
business_financial_information: {
|
| 1300 |
-
...(currentFin.business_financial_information || {}),
|
| 1301 |
-
...(fin.business_financial_information || {})
|
| 1302 |
-
},
|
| 1303 |
-
loans_and_emis: {
|
| 1304 |
-
...(currentFin.loans_and_emis || {}),
|
| 1305 |
-
...(fin.loans_and_emis || {})
|
| 1306 |
-
},
|
| 1307 |
-
family_financial_information: {
|
| 1308 |
-
...(currentFin.family_financial_information || {}),
|
| 1309 |
-
...(fin.family_financial_information || {})
|
| 1310 |
-
}
|
| 1311 |
-
};
|
| 1312 |
-
}
|
| 1313 |
|
| 1314 |
const updatedCase = await Case.findOneAndUpdate(
|
| 1315 |
{ case_id: req.params.case_id },
|
|
@@ -1327,66 +1254,7 @@ app.put('/api/cases/:case_id', authenticateToken, requireAgentOrAdmin, async (re
|
|
| 1327 |
});
|
| 1328 |
|
| 1329 |
// Update specific section of case
|
| 1330 |
-
|
| 1331 |
-
try {
|
| 1332 |
-
const { case_id, section } = req.params;
|
| 1333 |
-
|
| 1334 |
-
const caseDoc = await Case.findOne({ case_id });
|
| 1335 |
-
|
| 1336 |
-
if (!caseDoc) {
|
| 1337 |
-
return res.status(404).json({ error: 'Case not found' });
|
| 1338 |
-
}
|
| 1339 |
-
|
| 1340 |
-
if (req.user.role === 'agent' && caseDoc.assigned_agent !== req.user.userId) {
|
| 1341 |
-
return res.status(403).json({ error: 'Access denied to this case' });
|
| 1342 |
-
}
|
| 1343 |
-
|
| 1344 |
-
const updateData = { updated_at: new Date() };
|
| 1345 |
-
const validSections = ['demographic_details', 'business_details', 'financial_details'];
|
| 1346 |
-
|
| 1347 |
-
if (!validSections.includes(section)) {
|
| 1348 |
-
return res.status(400).json({ error: 'Invalid section. Must be: demographic_details, business_details, or financial_details' });
|
| 1349 |
-
}
|
| 1350 |
-
|
| 1351 |
-
const currentSection = caseDoc[section] || {};
|
| 1352 |
-
updateData[section] = deepMerge(currentSection, req.body);
|
| 1353 |
-
|
| 1354 |
-
const updatedCase = await Case.findOneAndUpdate(
|
| 1355 |
-
{ case_id },
|
| 1356 |
-
updateData,
|
| 1357 |
-
{ new: true }
|
| 1358 |
-
);
|
| 1359 |
-
|
| 1360 |
-
res.json({
|
| 1361 |
-
message: `${section} updated successfully`,
|
| 1362 |
-
case: updatedCase
|
| 1363 |
-
});
|
| 1364 |
-
} catch (error) {
|
| 1365 |
-
res.status(400).json({ error: error.message });
|
| 1366 |
-
}
|
| 1367 |
-
});
|
| 1368 |
-
|
| 1369 |
-
function deepMerge(target, source) {
|
| 1370 |
-
const output = { ...target };
|
| 1371 |
-
if (isObject(target) && isObject(source)) {
|
| 1372 |
-
Object.keys(source).forEach(key => {
|
| 1373 |
-
if (isObject(source[key])) {
|
| 1374 |
-
if (!(key in target)) {
|
| 1375 |
-
output[key] = source[key];
|
| 1376 |
-
} else {
|
| 1377 |
-
output[key] = deepMerge(target[key], source[key]);
|
| 1378 |
-
}
|
| 1379 |
-
} else {
|
| 1380 |
-
output[key] = source[key];
|
| 1381 |
-
}
|
| 1382 |
-
});
|
| 1383 |
-
}
|
| 1384 |
-
return output;
|
| 1385 |
-
}
|
| 1386 |
-
|
| 1387 |
-
function isObject(item) {
|
| 1388 |
-
return item && typeof item === 'object' && !Array.isArray(item);
|
| 1389 |
-
}
|
| 1390 |
|
| 1391 |
// Delete Case (Admin only)
|
| 1392 |
app.delete('/api/cases/:case_id', authenticateToken, requireAdmin, async (req, res) => {
|
|
@@ -1577,10 +1445,10 @@ app.post('/api/webhook/case-creation', validateWebhookApiKey, async (req, res) =
|
|
| 1577 |
// Check if this is an automation webhook (has applicationId and status)
|
| 1578 |
if (requestData.applicationId && requestData.status === 'New') {
|
| 1579 |
console.log(`🚀 Starting automation for App ID: ${requestData.applicationId}`);
|
| 1580 |
-
|
| 1581 |
try {
|
| 1582 |
const automationResult = await processAutomation(requestData.applicationId);
|
| 1583 |
-
|
| 1584 |
res.status(200).json({
|
| 1585 |
success: true,
|
| 1586 |
message: 'Webhook data received and automation completed successfully',
|
|
@@ -1625,34 +1493,30 @@ async function processAutomation(applicationId) {
|
|
| 1625 |
try {
|
| 1626 |
console.log(`Processing automation for Application ID: ${applicationId}`);
|
| 1627 |
|
| 1628 |
-
// 1.
|
| 1629 |
-
//
|
| 1630 |
-
const dataToEncrypt = JSON.stringify({ appIicationid: applicationId });
|
| 1631 |
-
const encryptedData = encryptStringB2C(dataToEncrypt);
|
| 1632 |
-
|
| 1633 |
-
// 2. Call external API
|
| 1634 |
const externalApiUrl = 'https://qa-uapmp.instantmseloans.in/gateway/loans/msme/uapmp/v1/getBorrowerdetails';
|
|
|
|
| 1635 |
const response = await axios.post(externalApiUrl, {
|
| 1636 |
-
|
| 1637 |
}, {
|
| 1638 |
headers: {
|
| 1639 |
'Content-Type': 'application/json',
|
| 1640 |
-
'User-name': '
|
| 1641 |
-
'api-key': '
|
| 1642 |
-
'
|
| 1643 |
-
'is_decrypt': 'true',
|
| 1644 |
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
| 1645 |
}
|
| 1646 |
});
|
| 1647 |
|
| 1648 |
-
|
|
|
|
| 1649 |
|
| 1650 |
-
if (!
|
| 1651 |
-
throw new Error('External API did not return
|
| 1652 |
}
|
| 1653 |
|
| 1654 |
-
// 3.
|
| 1655 |
-
const result = await processAndSaveBorrowerData(
|
| 1656 |
|
| 1657 |
return {
|
| 1658 |
success: true,
|
|
@@ -1730,32 +1594,33 @@ app.post('/api/decrypt', async (req, res) => {
|
|
| 1730 |
|
| 1731 |
// Decrypt and Parse B2C encrypted string to JSON and Save directly to Cases
|
| 1732 |
// Helper function to process and save borrower data
|
| 1733 |
-
|
| 1734 |
-
|
| 1735 |
-
|
| 1736 |
-
|
| 1737 |
-
// Parse to JSON
|
| 1738 |
-
const jsonData = JSON.parse(decryptedString);
|
| 1739 |
-
|
| 1740 |
-
// Transform the new API structure to match your exact backend schema
|
| 1741 |
-
const transformedData = transformToBackendStructure(jsonData);
|
| 1742 |
|
| 1743 |
// Create case data with your exact schema using the main Case model
|
| 1744 |
const caseData = {
|
| 1745 |
case_id: uuidv4(),
|
| 1746 |
-
application_id: appId || jsonData.applicationId,
|
| 1747 |
-
case_applicant_name:
|
| 1748 |
-
case_applicant_contact:
|
| 1749 |
-
address:
|
| 1750 |
-
case_type:
|
| 1751 |
-
loan_amount:
|
| 1752 |
-
priority:
|
| 1753 |
-
assigned_agent: "",
|
| 1754 |
-
status: "Pending",
|
| 1755 |
-
|
| 1756 |
-
|
| 1757 |
-
|
| 1758 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1759 |
created_at: new Date(),
|
| 1760 |
updated_at: new Date()
|
| 1761 |
};
|
|
@@ -1765,7 +1630,7 @@ async function processAndSaveBorrowerData(encData, appId) {
|
|
| 1765 |
|
| 1766 |
return {
|
| 1767 |
case_id: newCase.case_id,
|
| 1768 |
-
application_id: jsonData.applicationId,
|
| 1769 |
saved_data: caseData
|
| 1770 |
};
|
| 1771 |
}
|
|
@@ -1809,6 +1674,7 @@ app.post('/api/decrypt-json-save', async (req, res) => {
|
|
| 1809 |
}
|
| 1810 |
});
|
| 1811 |
|
|
|
|
| 1812 |
// Webhook Automation Endpoint
|
| 1813 |
app.post('/api/webhook/automation', async (req, res) => {
|
| 1814 |
try {
|
|
@@ -1823,34 +1689,28 @@ app.post('/api/webhook/automation', async (req, res) => {
|
|
| 1823 |
});
|
| 1824 |
}
|
| 1825 |
|
| 1826 |
-
// 1.
|
| 1827 |
-
// Using the specific key "appIicationid" as requested by user
|
| 1828 |
-
const dataToEncrypt = JSON.stringify({ appIicationid: applicationId });
|
| 1829 |
-
const encryptedData = encryptStringB2C(dataToEncrypt);
|
| 1830 |
-
|
| 1831 |
-
// 2. Call external API
|
| 1832 |
const externalApiUrl = 'https://qa-uapmp.instantmseloans.in/gateway/loans/msme/uapmp/v1/getBorrowerdetails';
|
|
|
|
| 1833 |
const response = await axios.post(externalApiUrl, {
|
| 1834 |
-
|
| 1835 |
}, {
|
| 1836 |
headers: {
|
| 1837 |
'Content-Type': 'application/json',
|
| 1838 |
-
'User-name': '
|
| 1839 |
-
'api-key': '
|
| 1840 |
-
'
|
| 1841 |
-
'is_decrypt': 'true',
|
| 1842 |
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
|
| 1843 |
}
|
| 1844 |
});
|
| 1845 |
|
| 1846 |
-
const {
|
| 1847 |
|
| 1848 |
-
if (!
|
| 1849 |
-
throw new Error('External API did not return
|
| 1850 |
}
|
| 1851 |
|
| 1852 |
-
// 3.
|
| 1853 |
-
const result = await processAndSaveBorrowerData(
|
| 1854 |
|
| 1855 |
res.json({
|
| 1856 |
success: true,
|
|
@@ -1868,136 +1728,7 @@ app.post('/api/webhook/automation', async (req, res) => {
|
|
| 1868 |
}
|
| 1869 |
});
|
| 1870 |
|
| 1871 |
-
//
|
| 1872 |
-
function transformToBackendStructure(newData) {
|
| 1873 |
-
const { data, metaData } = newData;
|
| 1874 |
-
const { applicantDetail, residenceDetail, businessDetail, coApplicantDetail, incomeExpenditure, familyExpenses } = data;
|
| 1875 |
-
|
| 1876 |
-
// Helper function to get display value from metaData
|
| 1877 |
-
const getDisplayValue = (metaArray, id) => {
|
| 1878 |
-
if (!metaArray || !id) return '';
|
| 1879 |
-
const item = metaArray.find(item => item.id === id);
|
| 1880 |
-
return item ? item.value : '';
|
| 1881 |
-
};
|
| 1882 |
-
|
| 1883 |
-
// Helper function to handle empty values
|
| 1884 |
-
const handleEmptyValue = (value, defaultValue = '') => {
|
| 1885 |
-
if (value === null || value === undefined || value === '') {
|
| 1886 |
-
return defaultValue;
|
| 1887 |
-
}
|
| 1888 |
-
return value;
|
| 1889 |
-
};
|
| 1890 |
-
|
| 1891 |
-
const handleEmptyNumber = (value, defaultValue = 0) => {
|
| 1892 |
-
if (value === null || value === undefined || value === '') {
|
| 1893 |
-
return defaultValue;
|
| 1894 |
-
}
|
| 1895 |
-
return Number(value) || defaultValue;
|
| 1896 |
-
};
|
| 1897 |
-
|
| 1898 |
-
// Build address from residence details
|
| 1899 |
-
const buildAddress = () => {
|
| 1900 |
-
const parts = [
|
| 1901 |
-
residenceDetail?.address1,
|
| 1902 |
-
residenceDetail?.address2,
|
| 1903 |
-
residenceDetail?.address3,
|
| 1904 |
-
getDisplayValue(metaData.residenceDetail?.cityId, residenceDetail?.cityId),
|
| 1905 |
-
getDisplayValue(metaData.residenceDetail?.stateId, residenceDetail?.stateId),
|
| 1906 |
-
residenceDetail?.pincode
|
| 1907 |
-
].filter(part => part && part !== '');
|
| 1908 |
-
|
| 1909 |
-
return parts.join(', ');
|
| 1910 |
-
};
|
| 1911 |
-
|
| 1912 |
-
// Transform to your exact backend structure
|
| 1913 |
-
return {
|
| 1914 |
-
// Root level fields matching your schema
|
| 1915 |
-
case_applicant_name: handleEmptyValue(applicantDetail?.name),
|
| 1916 |
-
case_applicant_contact: handleEmptyValue(applicantDetail?.mobile),
|
| 1917 |
-
address: buildAddress(),
|
| 1918 |
-
case_type: "Business Loan", // Default as per your example
|
| 1919 |
-
loan_amount: handleEmptyNumber(incomeExpenditure?.yearlyIncome),
|
| 1920 |
-
priority: "MED", // Default priority
|
| 1921 |
-
|
| 1922 |
-
// Demographic Details - exact structure as in your image
|
| 1923 |
-
demographic_details: {
|
| 1924 |
-
aadhaar_photo_match: null,
|
| 1925 |
-
contact_information: {
|
| 1926 |
-
email_id: handleEmptyValue(applicantDetail?.email),
|
| 1927 |
-
mobile_number: handleEmptyValue(applicantDetail?.mobile)
|
| 1928 |
-
},
|
| 1929 |
-
personal_details: {
|
| 1930 |
-
gender: getDisplayValue(metaData.genderId, applicantDetail?.genderId),
|
| 1931 |
-
education: getDisplayValue(metaData.qualification, applicantDetail?.qualification),
|
| 1932 |
-
number_of_family_members: handleEmptyNumber(applicantDetail?.numOfDependent)
|
| 1933 |
-
},
|
| 1934 |
-
customer_photo_id: handleEmptyValue(applicantDetail?.applicantFileDetail),
|
| 1935 |
-
address_details: {
|
| 1936 |
-
residence_address_type: getDisplayValue(metaData.ownershipStatus, residenceDetail?.ownershipStatus),
|
| 1937 |
-
residential_address: buildAddress(),
|
| 1938 |
-
city: getDisplayValue(metaData.residenceDetail?.cityId, residenceDetail?.cityId),
|
| 1939 |
-
state: getDisplayValue(metaData.residenceDetail?.stateId, residenceDetail?.stateId),
|
| 1940 |
-
district: getDisplayValue(metaData.residenceDetail?.districtId, residenceDetail?.districtId),
|
| 1941 |
-
pincode: handleEmptyValue(residenceDetail?.pincode)
|
| 1942 |
-
},
|
| 1943 |
-
residence_photo_id: handleEmptyValue(residenceDetail?.addresProofDetail)
|
| 1944 |
-
},
|
| 1945 |
-
|
| 1946 |
-
// Business Details - exact structure as in your image
|
| 1947 |
-
business_details: {
|
| 1948 |
-
enterprise_information: {
|
| 1949 |
-
enterprise_name: handleEmptyValue(businessDetail?.businessName),
|
| 1950 |
-
type_of_organization: getDisplayValue(metaData.organizationType, businessDetail?.organizationType)
|
| 1951 |
-
},
|
| 1952 |
-
business_location_details: {
|
| 1953 |
-
business_address_type: getDisplayValue(metaData.businessLocation, businessDetail?.businessLocation),
|
| 1954 |
-
business_location: `${handleEmptyValue(businessDetail?.address1)} ${handleEmptyValue(businessDetail?.address2)}`.trim()
|
| 1955 |
-
},
|
| 1956 |
-
business_address: {
|
| 1957 |
-
address: `${handleEmptyValue(businessDetail?.address1)} ${handleEmptyValue(businessDetail?.address2)}`.trim(),
|
| 1958 |
-
city: getDisplayValue(metaData.businessDetail?.cityId, businessDetail?.cityId),
|
| 1959 |
-
district: getDisplayValue(metaData.businessDetail?.districtId, businessDetail?.districtId),
|
| 1960 |
-
state: getDisplayValue(metaData.businessDetail?.stateId, businessDetail?.stateId),
|
| 1961 |
-
pincode: handleEmptyValue(businessDetail?.pincode),
|
| 1962 |
-
landmark: handleEmptyValue(businessDetail?.landmark)
|
| 1963 |
-
},
|
| 1964 |
-
business_address_photo_id: handleEmptyValue(businessDetail?.businessProofDetail),
|
| 1965 |
-
business_activity: {
|
| 1966 |
-
business_activity: getDisplayValue(metaData.businessDetail?.natureActivity, businessDetail?.natureActivity),
|
| 1967 |
-
activity_type: getDisplayValue(metaData.businessType, businessDetail?.businessType)
|
| 1968 |
-
},
|
| 1969 |
-
business_info: {
|
| 1970 |
-
employee_count: 0, // Default as not available in new API
|
| 1971 |
-
years_of_running_business: handleEmptyNumber(businessDetail?.workExperienceInYears),
|
| 1972 |
-
additional_business: '' // Default as not available in new API
|
| 1973 |
-
}
|
| 1974 |
-
},
|
| 1975 |
-
|
| 1976 |
-
// Financial Details - exact structure as in your image
|
| 1977 |
-
financial_details: {
|
| 1978 |
-
monthly_income: handleEmptyNumber(incomeExpenditure?.monthlyIncome),
|
| 1979 |
-
yearly_income: handleEmptyNumber(incomeExpenditure?.yearlyIncome),
|
| 1980 |
-
total_income: handleEmptyNumber(incomeExpenditure?.totalIncome),
|
| 1981 |
-
income_from_other_sources: handleEmptyNumber(incomeExpenditure?.incomeFromOtherSource),
|
| 1982 |
-
frequency_of_income: getDisplayValue([
|
| 1983 |
-
{ id: 1, value: 'Daily' },
|
| 1984 |
-
{ id: 2, value: 'Monthly' },
|
| 1985 |
-
{ id: 3, value: 'Yearly' }
|
| 1986 |
-
], incomeExpenditure?.freqOfIncome),
|
| 1987 |
-
household_expenses: handleEmptyNumber(familyExpenses?.householdExp),
|
| 1988 |
-
utility_expenses: handleEmptyNumber(familyExpenses?.utilityExp),
|
| 1989 |
-
education_expenses: handleEmptyNumber(familyExpenses?.eduExp),
|
| 1990 |
-
medical_expenses: handleEmptyNumber(familyExpenses?.mediExp),
|
| 1991 |
-
food_expenses: handleEmptyNumber(familyExpenses?.foodExp),
|
| 1992 |
-
grocery_expenses: handleEmptyNumber(familyExpenses?.grocExp),
|
| 1993 |
-
transportation_expenses: handleEmptyNumber(familyExpenses?.transpExp),
|
| 1994 |
-
other_expenses: handleEmptyNumber(familyExpenses?.otherExp),
|
| 1995 |
-
total_expenses: handleEmptyNumber(familyExpenses?.totalExp)
|
| 1996 |
-
},
|
| 1997 |
-
|
| 1998 |
-
remarks: `Application ID: ${newData.applicationId} - Auto imported`
|
| 1999 |
-
};
|
| 2000 |
-
}
|
| 2001 |
|
| 2002 |
|
| 2003 |
|
|
|
|
| 1236 |
}
|
| 1237 |
if (req.body.remarks) updateData.remarks = req.body.remarks;
|
| 1238 |
|
| 1239 |
+
// Legacy update logic for demographic_details, business_details, financial_details removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
|
| 1241 |
const updatedCase = await Case.findOneAndUpdate(
|
| 1242 |
{ case_id: req.params.case_id },
|
|
|
|
| 1254 |
});
|
| 1255 |
|
| 1256 |
// Update specific section of case
|
| 1257 |
+
// PATCH endpoint removed as it handled legacy sections
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1258 |
|
| 1259 |
// Delete Case (Admin only)
|
| 1260 |
app.delete('/api/cases/:case_id', authenticateToken, requireAdmin, async (req, res) => {
|
|
|
|
| 1445 |
// Check if this is an automation webhook (has applicationId and status)
|
| 1446 |
if (requestData.applicationId && requestData.status === 'New') {
|
| 1447 |
console.log(`🚀 Starting automation for App ID: ${requestData.applicationId}`);
|
| 1448 |
+
|
| 1449 |
try {
|
| 1450 |
const automationResult = await processAutomation(requestData.applicationId);
|
| 1451 |
+
|
| 1452 |
res.status(200).json({
|
| 1453 |
success: true,
|
| 1454 |
message: 'Webhook data received and automation completed successfully',
|
|
|
|
| 1493 |
try {
|
| 1494 |
console.log(`Processing automation for Application ID: ${applicationId}`);
|
| 1495 |
|
| 1496 |
+
// 1. Call external API directly (no encryption of request body needed as per new spec)
|
| 1497 |
+
// User said: Request{ "appIicationid": 38789 }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1498 |
const externalApiUrl = 'https://qa-uapmp.instantmseloans.in/gateway/loans/msme/uapmp/v1/getBorrowerdetails';
|
| 1499 |
+
|
| 1500 |
const response = await axios.post(externalApiUrl, {
|
| 1501 |
+
appIicationid: applicationId
|
| 1502 |
}, {
|
| 1503 |
headers: {
|
| 1504 |
'Content-Type': 'application/json',
|
| 1505 |
+
'User-name': 'Biz2x',
|
| 1506 |
+
'api-key': process.env.OPL_API_KEY || 'PLACEHOLDER_API_KEY_WILL_BE_SHARED_BY_OPL',
|
| 1507 |
+
'Request-type': 'POST'
|
|
|
|
|
|
|
| 1508 |
}
|
| 1509 |
});
|
| 1510 |
|
| 1511 |
+
// User said Response structure: { "appIicationid": ..., "message": ..., "data": { ... } }
|
| 1512 |
+
const { data } = response.data;
|
| 1513 |
|
| 1514 |
+
if (!data) {
|
| 1515 |
+
throw new Error('External API did not return data');
|
| 1516 |
}
|
| 1517 |
|
| 1518 |
+
// 3. Save Data directly
|
| 1519 |
+
const result = await processAndSaveBorrowerData(data, applicationId);
|
| 1520 |
|
| 1521 |
return {
|
| 1522 |
success: true,
|
|
|
|
| 1594 |
|
| 1595 |
// Decrypt and Parse B2C encrypted string to JSON and Save directly to Cases
|
| 1596 |
// Helper function to process and save borrower data
|
| 1597 |
+
// Helper function to process and save borrower data
|
| 1598 |
+
async function processAndSaveBorrowerData(jsonData, appId) {
|
| 1599 |
+
// No transformation needed, save directly to new fields
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1600 |
|
| 1601 |
// Create case data with your exact schema using the main Case model
|
| 1602 |
const caseData = {
|
| 1603 |
case_id: uuidv4(),
|
| 1604 |
+
application_id: appId || jsonData.applicationId || jsonData.appIicationid, // Handle both spellings
|
| 1605 |
+
case_applicant_name: jsonData.applicantDetail?.name || '',
|
| 1606 |
+
case_applicant_contact: jsonData.applicantDetail?.mobile || '',
|
| 1607 |
+
address: jsonData.residenceDetail ? `${jsonData.residenceDetail.address1}, ${jsonData.residenceDetail.cityId}` : '', // Simplified address for main field
|
| 1608 |
+
case_type: "Business Loan", // Default
|
| 1609 |
+
loan_amount: jsonData.incomeExpenditure?.yearlyIncome || 0,
|
| 1610 |
+
priority: "MED",
|
| 1611 |
+
assigned_agent: "",
|
| 1612 |
+
status: "Pending",
|
| 1613 |
+
|
| 1614 |
+
// Save the full detailed structures
|
| 1615 |
+
applicantDetail: jsonData.applicantDetail,
|
| 1616 |
+
residenceDetail: jsonData.residenceDetail,
|
| 1617 |
+
coApplicantDetail: jsonData.coApplicantDetail,
|
| 1618 |
+
businessDetail: jsonData.businessDetail,
|
| 1619 |
+
incomeExpenditure: jsonData.incomeExpenditure,
|
| 1620 |
+
familyExpenses: jsonData.familyExpenses,
|
| 1621 |
+
metaData: jsonData.metaData,
|
| 1622 |
+
|
| 1623 |
+
remarks: `Application ID: ${appId || jsonData.applicationId || jsonData.appIicationid} - Auto imported`,
|
| 1624 |
created_at: new Date(),
|
| 1625 |
updated_at: new Date()
|
| 1626 |
};
|
|
|
|
| 1630 |
|
| 1631 |
return {
|
| 1632 |
case_id: newCase.case_id,
|
| 1633 |
+
application_id: appId || jsonData.applicationId || jsonData.appIicationid,
|
| 1634 |
saved_data: caseData
|
| 1635 |
};
|
| 1636 |
}
|
|
|
|
| 1674 |
}
|
| 1675 |
});
|
| 1676 |
|
| 1677 |
+
// Webhook Automation Endpoint
|
| 1678 |
// Webhook Automation Endpoint
|
| 1679 |
app.post('/api/webhook/automation', async (req, res) => {
|
| 1680 |
try {
|
|
|
|
| 1689 |
});
|
| 1690 |
}
|
| 1691 |
|
| 1692 |
+
// 1. Call external API directly
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1693 |
const externalApiUrl = 'https://qa-uapmp.instantmseloans.in/gateway/loans/msme/uapmp/v1/getBorrowerdetails';
|
| 1694 |
+
|
| 1695 |
const response = await axios.post(externalApiUrl, {
|
| 1696 |
+
appIicationid: applicationId
|
| 1697 |
}, {
|
| 1698 |
headers: {
|
| 1699 |
'Content-Type': 'application/json',
|
| 1700 |
+
'User-name': 'Biz2x',
|
| 1701 |
+
'api-key': process.env.OPL_API_KEY || 'PLACEHOLDER_API_KEY_WILL_BE_SHARED_BY_OPL',
|
| 1702 |
+
'Request-type': 'POST'
|
|
|
|
|
|
|
| 1703 |
}
|
| 1704 |
});
|
| 1705 |
|
| 1706 |
+
const { data } = response.data;
|
| 1707 |
|
| 1708 |
+
if (!data) {
|
| 1709 |
+
throw new Error('External API did not return data');
|
| 1710 |
}
|
| 1711 |
|
| 1712 |
+
// 3. Save Data directly
|
| 1713 |
+
const result = await processAndSaveBorrowerData(data, applicationId);
|
| 1714 |
|
| 1715 |
res.json({
|
| 1716 |
success: true,
|
|
|
|
| 1728 |
}
|
| 1729 |
});
|
| 1730 |
|
| 1731 |
+
// Removed transformToBackendStructure as it is no longer needed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1732 |
|
| 1733 |
|
| 1734 |
|
models.js
CHANGED
|
@@ -56,7 +56,7 @@
|
|
| 56 |
// // default: 'Unassigned',
|
| 57 |
// // enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 58 |
// // },
|
| 59 |
-
|
| 60 |
// // // Demographic Details
|
| 61 |
// // demographic_details: {
|
| 62 |
// // aadhaar_photo_match: { type: Boolean, default: null },
|
|
@@ -80,7 +80,7 @@
|
|
| 80 |
// // },
|
| 81 |
// // residence_photo_id: String
|
| 82 |
// // },
|
| 83 |
-
|
| 84 |
// // // Business Details
|
| 85 |
// // business_details: {
|
| 86 |
// // enterprise_information: {
|
|
@@ -110,7 +110,7 @@
|
|
| 110 |
// // additional_business: { type: String, enum: ['Yes', 'No'] }
|
| 111 |
// // }
|
| 112 |
// // },
|
| 113 |
-
|
| 114 |
// // // Financial Details
|
| 115 |
// // financial_details: {
|
| 116 |
// // business_financial_information: {
|
|
@@ -126,7 +126,7 @@
|
|
| 126 |
// // monthly_family_expense: Number
|
| 127 |
// // }
|
| 128 |
// // },
|
| 129 |
-
|
| 130 |
// // created_at: { type: Date, default: Date.now },
|
| 131 |
// // assigned_at: Date,
|
| 132 |
// // accepted_at: Date,
|
|
@@ -219,7 +219,7 @@
|
|
| 219 |
// default: 'Unassigned',
|
| 220 |
// enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 221 |
// },
|
| 222 |
-
|
| 223 |
// // Demographic Details
|
| 224 |
// demographic_details: {
|
| 225 |
// aadhaar_photo_match: { type: Boolean, default: null },
|
|
@@ -243,7 +243,7 @@
|
|
| 243 |
// },
|
| 244 |
// residence_photo_id: String
|
| 245 |
// },
|
| 246 |
-
|
| 247 |
// // Business Details
|
| 248 |
// business_details: {
|
| 249 |
// enterprise_information: {
|
|
@@ -273,7 +273,7 @@
|
|
| 273 |
// additional_business: { type: String, enum: ['Yes', 'No'] }
|
| 274 |
// }
|
| 275 |
// },
|
| 276 |
-
|
| 277 |
// // Financial Details
|
| 278 |
// financial_details: {
|
| 279 |
// business_financial_information: {
|
|
@@ -289,7 +289,7 @@
|
|
| 289 |
// monthly_family_expense: Number
|
| 290 |
// }
|
| 291 |
// },
|
| 292 |
-
|
| 293 |
// created_at: { type: Date, default: Date.now },
|
| 294 |
// assigned_at: Date,
|
| 295 |
// accepted_at: Date,
|
|
@@ -371,12 +371,12 @@ const agentSchema = new mongoose.Schema({
|
|
| 371 |
// Case Schema with all sections
|
| 372 |
const caseSchema = new mongoose.Schema({
|
| 373 |
case_id: { type: String, required: true, unique: true },
|
| 374 |
-
application_id
|
| 375 |
case_applicant_name: { type: String, required: true },
|
| 376 |
case_applicant_contact: { type: String, required: true },
|
| 377 |
address: { type: String, required: true },
|
| 378 |
-
case_type: {
|
| 379 |
-
type: String,
|
| 380 |
required: true
|
| 381 |
},
|
| 382 |
loan_amount: { type: Number, default: 0 },
|
|
@@ -386,88 +386,29 @@ const caseSchema = new mongoose.Schema({
|
|
| 386 |
enum: ['LOW', 'MED', 'HIGH']
|
| 387 |
},
|
| 388 |
assigned_agent: { type: String, default: null },
|
| 389 |
-
status: {
|
| 390 |
-
type: String,
|
| 391 |
default: 'Unassigned',
|
| 392 |
enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 393 |
},
|
| 394 |
-
|
| 395 |
-
//
|
| 396 |
-
|
| 397 |
-
aadhaar_photo_match: { type: Boolean, default: null },
|
| 398 |
-
contact_information: {
|
| 399 |
-
email_id: String,
|
| 400 |
-
mobile_number: String
|
| 401 |
-
},
|
| 402 |
-
personal_details: {
|
| 403 |
-
gender: String,
|
| 404 |
-
education: String,
|
| 405 |
-
number_of_family_members: Number
|
| 406 |
-
},
|
| 407 |
-
customer_photo_id: String,
|
| 408 |
-
address_details: {
|
| 409 |
-
residence_address_type: String,
|
| 410 |
-
residential_address: String,
|
| 411 |
-
city: String,
|
| 412 |
-
state: String,
|
| 413 |
-
district: String,
|
| 414 |
-
pincode: String
|
| 415 |
-
},
|
| 416 |
-
residence_photo_id: String
|
| 417 |
-
},
|
| 418 |
-
|
| 419 |
-
// Business Details
|
| 420 |
-
business_details: {
|
| 421 |
-
enterprise_information: {
|
| 422 |
-
enterprise_name: String,
|
| 423 |
-
type_of_organization: String
|
| 424 |
-
},
|
| 425 |
-
business_location_details: {
|
| 426 |
-
business_address_type: String,
|
| 427 |
-
business_location: String
|
| 428 |
-
},
|
| 429 |
-
business_address: {
|
| 430 |
-
address: String,
|
| 431 |
-
city: String,
|
| 432 |
-
district: String,
|
| 433 |
-
state: String,
|
| 434 |
-
pincode: String,
|
| 435 |
-
landmark: String
|
| 436 |
-
},
|
| 437 |
-
business_address_photo_id: String,
|
| 438 |
-
business_activity: {
|
| 439 |
-
business_activity: String,
|
| 440 |
-
activity_type: String
|
| 441 |
-
},
|
| 442 |
-
business_info: {
|
| 443 |
-
employee_count: Number,
|
| 444 |
-
years_of_running_business: Number,
|
| 445 |
-
additional_business: String
|
| 446 |
-
}
|
| 447 |
-
},
|
| 448 |
-
|
| 449 |
-
// Financial Details
|
| 450 |
-
financial_details: {
|
| 451 |
-
business_financial_information: {
|
| 452 |
-
monthly_income_from_business: Number,
|
| 453 |
-
monthly_expense_of_business: Number
|
| 454 |
-
},
|
| 455 |
-
loans_and_emis: {
|
| 456 |
-
current_loans_emis: String
|
| 457 |
-
},
|
| 458 |
-
family_financial_information: {
|
| 459 |
-
monthly_family_income: Number,
|
| 460 |
-
number_of_working_members: Number,
|
| 461 |
-
monthly_family_expense: Number
|
| 462 |
-
}
|
| 463 |
-
},
|
| 464 |
-
|
| 465 |
created_at: { type: Date, default: Date.now },
|
| 466 |
assigned_at: Date,
|
| 467 |
accepted_at: Date,
|
| 468 |
completed_at: Date,
|
| 469 |
updated_at: { type: Date, default: Date.now },
|
| 470 |
-
remarks: String
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
});
|
| 472 |
|
| 473 |
// File Schema
|
|
@@ -497,23 +438,10 @@ const caseCreationWebhookSchema = new mongoose.Schema({
|
|
| 497 |
user_agent: String
|
| 498 |
});
|
| 499 |
|
| 500 |
-
// NEW: Borrower Case Schema - Simplified schema for storing API data directly
|
| 501 |
-
const borrowerCaseSchema = new mongoose.Schema({
|
| 502 |
-
case_id: { type: String, required: true, unique: true },
|
| 503 |
-
application_id: { type: Number, required: true },
|
| 504 |
-
borrower_data: { type: mongoose.Schema.Types.Mixed, required: true }, // Stores the entire 'data' JSON
|
| 505 |
-
created_at: { type: Date, default: Date.now },
|
| 506 |
-
updated_at: { type: Date, default: Date.now }
|
| 507 |
-
}, {
|
| 508 |
-
collection: 'cases', // This will use the same 'cases' collection
|
| 509 |
-
strict: false // Allows storing any JSON structure
|
| 510 |
-
});
|
| 511 |
-
|
| 512 |
const CaseCreationWebhook = mongoose.model('CaseCreationWebhook', caseCreationWebhookSchema);
|
| 513 |
const Admin = mongoose.model('Admin', adminSchema);
|
| 514 |
const Agent = mongoose.model('Agent', agentSchema);
|
| 515 |
const Case = mongoose.model('Case', caseSchema);
|
| 516 |
const File = mongoose.model('File', fileSchema);
|
| 517 |
-
const BorrowerCase = mongoose.model('BorrowerCase', borrowerCaseSchema);
|
| 518 |
|
| 519 |
-
module.exports = { connectDB, Admin, Agent, Case, File, CaseCreationWebhook
|
|
|
|
| 56 |
// // default: 'Unassigned',
|
| 57 |
// // enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 58 |
// // },
|
| 59 |
+
|
| 60 |
// // // Demographic Details
|
| 61 |
// // demographic_details: {
|
| 62 |
// // aadhaar_photo_match: { type: Boolean, default: null },
|
|
|
|
| 80 |
// // },
|
| 81 |
// // residence_photo_id: String
|
| 82 |
// // },
|
| 83 |
+
|
| 84 |
// // // Business Details
|
| 85 |
// // business_details: {
|
| 86 |
// // enterprise_information: {
|
|
|
|
| 110 |
// // additional_business: { type: String, enum: ['Yes', 'No'] }
|
| 111 |
// // }
|
| 112 |
// // },
|
| 113 |
+
|
| 114 |
// // // Financial Details
|
| 115 |
// // financial_details: {
|
| 116 |
// // business_financial_information: {
|
|
|
|
| 126 |
// // monthly_family_expense: Number
|
| 127 |
// // }
|
| 128 |
// // },
|
| 129 |
+
|
| 130 |
// // created_at: { type: Date, default: Date.now },
|
| 131 |
// // assigned_at: Date,
|
| 132 |
// // accepted_at: Date,
|
|
|
|
| 219 |
// default: 'Unassigned',
|
| 220 |
// enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 221 |
// },
|
| 222 |
+
|
| 223 |
// // Demographic Details
|
| 224 |
// demographic_details: {
|
| 225 |
// aadhaar_photo_match: { type: Boolean, default: null },
|
|
|
|
| 243 |
// },
|
| 244 |
// residence_photo_id: String
|
| 245 |
// },
|
| 246 |
+
|
| 247 |
// // Business Details
|
| 248 |
// business_details: {
|
| 249 |
// enterprise_information: {
|
|
|
|
| 273 |
// additional_business: { type: String, enum: ['Yes', 'No'] }
|
| 274 |
// }
|
| 275 |
// },
|
| 276 |
+
|
| 277 |
// // Financial Details
|
| 278 |
// financial_details: {
|
| 279 |
// business_financial_information: {
|
|
|
|
| 289 |
// monthly_family_expense: Number
|
| 290 |
// }
|
| 291 |
// },
|
| 292 |
+
|
| 293 |
// created_at: { type: Date, default: Date.now },
|
| 294 |
// assigned_at: Date,
|
| 295 |
// accepted_at: Date,
|
|
|
|
| 371 |
// Case Schema with all sections
|
| 372 |
const caseSchema = new mongoose.Schema({
|
| 373 |
case_id: { type: String, required: true, unique: true },
|
| 374 |
+
application_id: { type: String, required: true },
|
| 375 |
case_applicant_name: { type: String, required: true },
|
| 376 |
case_applicant_contact: { type: String, required: true },
|
| 377 |
address: { type: String, required: true },
|
| 378 |
+
case_type: {
|
| 379 |
+
type: String,
|
| 380 |
required: true
|
| 381 |
},
|
| 382 |
loan_amount: { type: Number, default: 0 },
|
|
|
|
| 386 |
enum: ['LOW', 'MED', 'HIGH']
|
| 387 |
},
|
| 388 |
assigned_agent: { type: String, default: null },
|
| 389 |
+
status: {
|
| 390 |
+
type: String,
|
| 391 |
default: 'Unassigned',
|
| 392 |
enum: ['Completed', 'In Progress', 'Pending', 'Unassigned']
|
| 393 |
},
|
| 394 |
+
|
| 395 |
+
// Legacy fields removed: demographic_details, business_details, financial_details
|
| 396 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
created_at: { type: Date, default: Date.now },
|
| 398 |
assigned_at: Date,
|
| 399 |
accepted_at: Date,
|
| 400 |
completed_at: Date,
|
| 401 |
updated_at: { type: Date, default: Date.now },
|
| 402 |
+
remarks: String,
|
| 403 |
+
|
| 404 |
+
// New fields for UAPMP API integration
|
| 405 |
+
applicantDetail: { type: mongoose.Schema.Types.Mixed },
|
| 406 |
+
residenceDetail: { type: mongoose.Schema.Types.Mixed },
|
| 407 |
+
coApplicantDetail: { type: mongoose.Schema.Types.Mixed },
|
| 408 |
+
businessDetail: { type: mongoose.Schema.Types.Mixed },
|
| 409 |
+
incomeExpenditure: { type: mongoose.Schema.Types.Mixed },
|
| 410 |
+
familyExpenses: { type: mongoose.Schema.Types.Mixed },
|
| 411 |
+
metaData: { type: mongoose.Schema.Types.Mixed }
|
| 412 |
});
|
| 413 |
|
| 414 |
// File Schema
|
|
|
|
| 438 |
user_agent: String
|
| 439 |
});
|
| 440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
const CaseCreationWebhook = mongoose.model('CaseCreationWebhook', caseCreationWebhookSchema);
|
| 442 |
const Admin = mongoose.model('Admin', adminSchema);
|
| 443 |
const Agent = mongoose.model('Agent', agentSchema);
|
| 444 |
const Case = mongoose.model('Case', caseSchema);
|
| 445 |
const File = mongoose.model('File', fileSchema);
|
|
|
|
| 446 |
|
| 447 |
+
module.exports = { connectDB, Admin, Agent, Case, File, CaseCreationWebhook };
|
package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
readme-2.md
ADDED
|
@@ -0,0 +1,611 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CPV Platform API Documentation
|
| 2 |
+
|
| 3 |
+
**Base URL:** `https://cpv-b2c-apis-117274959277.asia-south1.run.app`
|
| 4 |
+
|
| 5 |
+
**Authentication:** JWT Token in Authorization header: `Bearer <token>`
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## 1. Admin Endpoints
|
| 10 |
+
|
| 11 |
+
### 1.1 Create Admin
|
| 12 |
+
- **Endpoint:** `/api/admin/create`
|
| 13 |
+
- **Method:** `POST`
|
| 14 |
+
- **Auth Required:** No
|
| 15 |
+
- **Request Body:**
|
| 16 |
+
```json
|
| 17 |
+
{
|
| 18 |
+
"name": "Admin Name",
|
| 19 |
+
"email": "admin@example.com",
|
| 20 |
+
"password": "SecurePass123"
|
| 21 |
+
}
|
| 22 |
+
```
|
| 23 |
+
- **Response:**
|
| 24 |
+
```json
|
| 25 |
+
{
|
| 26 |
+
"message": "Admin created successfully",
|
| 27 |
+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
| 28 |
+
"admin": {
|
| 29 |
+
"admin_id": "uuid-here",
|
| 30 |
+
"name": "Admin Name",
|
| 31 |
+
"email": "admin@example.com"
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
### 1.2 Admin Login
|
| 37 |
+
- **Endpoint:** `/api/admin/login`
|
| 38 |
+
- **Method:** `POST`
|
| 39 |
+
- **Auth Required:** No
|
| 40 |
+
- **Request Body:**
|
| 41 |
+
```json
|
| 42 |
+
{
|
| 43 |
+
"email": "admin@example.com",
|
| 44 |
+
"password": "SecurePass123"
|
| 45 |
+
}
|
| 46 |
+
```
|
| 47 |
+
- **Response:**
|
| 48 |
+
```json
|
| 49 |
+
{
|
| 50 |
+
"message": "Login successful",
|
| 51 |
+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
| 52 |
+
"admin": {
|
| 53 |
+
"admin_id": "uuid-here",
|
| 54 |
+
"name": "Admin Name",
|
| 55 |
+
"email": "admin@example.com"
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
---
|
| 61 |
+
|
| 62 |
+
## 2. Agent Endpoints
|
| 63 |
+
|
| 64 |
+
### 2.1 Create Agent (Admin Only)
|
| 65 |
+
- **Endpoint:** `/api/agents`
|
| 66 |
+
- **Method:** `POST`
|
| 67 |
+
- **Auth Required:** Yes (Admin)
|
| 68 |
+
- **Request Body:**
|
| 69 |
+
```json
|
| 70 |
+
{
|
| 71 |
+
"agent_name": "Agent Name",
|
| 72 |
+
"agent_email": "agent@example.com",
|
| 73 |
+
"contact_number": "9876543210",
|
| 74 |
+
"password": "AgentPass123"
|
| 75 |
+
}
|
| 76 |
+
```
|
| 77 |
+
- **Response:**
|
| 78 |
+
```json
|
| 79 |
+
{
|
| 80 |
+
"message": "Agent created successfully",
|
| 81 |
+
"agent": {
|
| 82 |
+
"agent_id": "uuid-here",
|
| 83 |
+
"agent_name": "Agent Name",
|
| 84 |
+
"agent_email": "agent@example.com",
|
| 85 |
+
"contact_number": "9876543210"
|
| 86 |
+
}
|
| 87 |
+
}
|
| 88 |
+
```
|
| 89 |
+
|
| 90 |
+
### 2.2 Agent Login
|
| 91 |
+
- **Endpoint:** `/api/agents/login`
|
| 92 |
+
- **Method:** `POST`
|
| 93 |
+
- **Auth Required:** No
|
| 94 |
+
- **Request Body:**
|
| 95 |
+
```json
|
| 96 |
+
{
|
| 97 |
+
"email": "agent@example.com",
|
| 98 |
+
"password": "AgentPass123"
|
| 99 |
+
}
|
| 100 |
+
```
|
| 101 |
+
- **Response:**
|
| 102 |
+
```json
|
| 103 |
+
{
|
| 104 |
+
"message": "Login successful",
|
| 105 |
+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
| 106 |
+
"agent": {
|
| 107 |
+
"agent_id": "uuid-here",
|
| 108 |
+
"agent_name": "Agent Name",
|
| 109 |
+
"agent_email": "agent@example.com",
|
| 110 |
+
"contact_number": "9876543210"
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
### 2.3 Get All Agents (Admin Only)
|
| 116 |
+
- **Endpoint:** `/api/agents`
|
| 117 |
+
- **Method:** `GET`
|
| 118 |
+
- **Auth Required:** Yes (Admin)
|
| 119 |
+
- **Response:**
|
| 120 |
+
```json
|
| 121 |
+
{
|
| 122 |
+
"agents": [
|
| 123 |
+
{
|
| 124 |
+
"agent_id": "uuid-here",
|
| 125 |
+
"agent_name": "Agent Name",
|
| 126 |
+
"agent_email": "agent@example.com",
|
| 127 |
+
"contact_number": "9876543210",
|
| 128 |
+
"status": "active",
|
| 129 |
+
"created_at": "2024-01-15T10:30:00.000Z"
|
| 130 |
+
}
|
| 131 |
+
]
|
| 132 |
+
}
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
### 2.4 Get Single Agent
|
| 136 |
+
- **Endpoint:** `/api/agents/:agent_id`
|
| 137 |
+
- **Method:** `GET`
|
| 138 |
+
- **Auth Required:** Yes
|
| 139 |
+
- **Response:**
|
| 140 |
+
```json
|
| 141 |
+
{
|
| 142 |
+
"agent_id": "uuid-here",
|
| 143 |
+
"agent_name": "Agent Name",
|
| 144 |
+
"agent_email": "agent@example.com",
|
| 145 |
+
"contact_number": "9876543210",
|
| 146 |
+
"status": "active",
|
| 147 |
+
"created_at": "2024-01-15T10:30:00.000Z"
|
| 148 |
+
}
|
| 149 |
+
```
|
| 150 |
+
|
| 151 |
+
### 2.5 Update Agent (Admin Only)
|
| 152 |
+
- **Endpoint:** `/api/agents/:agent_id`
|
| 153 |
+
- **Method:** `PUT`
|
| 154 |
+
- **Auth Required:** Yes (Admin)
|
| 155 |
+
- **Request Body:**
|
| 156 |
+
```json
|
| 157 |
+
{
|
| 158 |
+
"agent_name": "Updated Name",
|
| 159 |
+
"contact_number": "9988776655",
|
| 160 |
+
"status": "active"
|
| 161 |
+
}
|
| 162 |
+
```
|
| 163 |
+
- **Response:**
|
| 164 |
+
```json
|
| 165 |
+
{
|
| 166 |
+
"message": "Agent updated",
|
| 167 |
+
"agent": {
|
| 168 |
+
"agent_id": "uuid-here",
|
| 169 |
+
"agent_name": "Updated Name",
|
| 170 |
+
"contact_number": "9988776655",
|
| 171 |
+
"status": "active"
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
```
|
| 175 |
+
|
| 176 |
+
### 2.6 Delete Agent (Admin Only)
|
| 177 |
+
- **Endpoint:** `/api/agents/:agent_id`
|
| 178 |
+
- **Method:** `DELETE`
|
| 179 |
+
- **Auth Required:** Yes (Admin)
|
| 180 |
+
- **Response:**
|
| 181 |
+
```json
|
| 182 |
+
{
|
| 183 |
+
"message": "Agent deleted"
|
| 184 |
+
}
|
| 185 |
+
```
|
| 186 |
+
|
| 187 |
+
---
|
| 188 |
+
|
| 189 |
+
## 3. Case Endpoints
|
| 190 |
+
|
| 191 |
+
### 3.1 Create Case
|
| 192 |
+
- **Endpoint:** `/api/cases`
|
| 193 |
+
- **Method:** `POST`
|
| 194 |
+
- **Auth Required:** Yes (Agent or Admin)
|
| 195 |
+
- **Request Body:**
|
| 196 |
+
```json
|
| 197 |
+
{
|
| 198 |
+
"case_applicant_name": "John Doe",
|
| 199 |
+
"case_applicant_contact": "9876543210",
|
| 200 |
+
"address": "123 Main Street, Mumbai",
|
| 201 |
+
"case_type": "Business Loan",
|
| 202 |
+
"priority": "MED",
|
| 203 |
+
"loan_amount": 500000
|
| 204 |
+
}
|
| 205 |
+
```
|
| 206 |
+
- **Response:**
|
| 207 |
+
```json
|
| 208 |
+
{
|
| 209 |
+
"message": "Case created successfully",
|
| 210 |
+
"case_id": "case-uuid-here"
|
| 211 |
+
}
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
### 3.2 Get All Cases
|
| 215 |
+
- **Endpoint:** `/api/cases`
|
| 216 |
+
- **Method:** `GET`
|
| 217 |
+
- **Auth Required:** Yes
|
| 218 |
+
- **Query Params:** `?status=In Progress&case_type=Business Loan&priority=HIGH`
|
| 219 |
+
- **Response:**
|
| 220 |
+
```json
|
| 221 |
+
{
|
| 222 |
+
"cases": [
|
| 223 |
+
{
|
| 224 |
+
"case_id": "case-uuid-here",
|
| 225 |
+
"case_applicant_name": "John Doe",
|
| 226 |
+
"case_applicant_contact": "9876543210",
|
| 227 |
+
"address": "123 Main Street, Mumbai",
|
| 228 |
+
"case_type": "Business Loan",
|
| 229 |
+
"loan_amount": 500000,
|
| 230 |
+
"priority": "MED",
|
| 231 |
+
"status": "In Progress",
|
| 232 |
+
"assigned_agent": "agent-uuid",
|
| 233 |
+
"created_at": "2024-01-15T10:30:00.000Z",
|
| 234 |
+
"updated_at": "2024-01-15T14:20:00.000Z"
|
| 235 |
+
}
|
| 236 |
+
]
|
| 237 |
+
}
|
| 238 |
+
```
|
| 239 |
+
|
| 240 |
+
### 3.3 Get Single Case
|
| 241 |
+
- **Endpoint:** `/api/cases/:case_id`
|
| 242 |
+
- **Method:** `GET`
|
| 243 |
+
- **Auth Required:** Yes
|
| 244 |
+
- **Response:**
|
| 245 |
+
```json
|
| 246 |
+
{
|
| 247 |
+
"case_id": "case-uuid-here",
|
| 248 |
+
"case_applicant_name": "John Doe",
|
| 249 |
+
"case_applicant_contact": "9876543210",
|
| 250 |
+
"address": "123 Main Street, Mumbai",
|
| 251 |
+
"case_type": "Business Loan",
|
| 252 |
+
"loan_amount": 500000,
|
| 253 |
+
"priority": "MED",
|
| 254 |
+
"status": "Pending",
|
| 255 |
+
"assigned_agent": "agent-uuid",
|
| 256 |
+
"remarks": "Verification in progress",
|
| 257 |
+
"demographic_details": {},
|
| 258 |
+
"business_details": {},
|
| 259 |
+
"financial_details": {},
|
| 260 |
+
"created_at": "2024-01-15T10:30:00.000Z",
|
| 261 |
+
"assigned_at": "2024-01-15T11:00:00.000Z",
|
| 262 |
+
"accepted_at": "2024-01-15T11:30:00.000Z",
|
| 263 |
+
"updated_at": "2024-01-15T14:20:00.000Z"
|
| 264 |
+
}
|
| 265 |
+
```
|
| 266 |
+
|
| 267 |
+
### 3.4 Assign Case to Agent (Admin Only)
|
| 268 |
+
- **Endpoint:** `/api/cases/:case_id/assign`
|
| 269 |
+
- **Method:** `PUT`
|
| 270 |
+
- **Auth Required:** Yes (Admin)
|
| 271 |
+
- **Request Body:**
|
| 272 |
+
```json
|
| 273 |
+
{
|
| 274 |
+
"agent_id": "agent-uuid-here"
|
| 275 |
+
}
|
| 276 |
+
```
|
| 277 |
+
- **Response:**
|
| 278 |
+
```json
|
| 279 |
+
{
|
| 280 |
+
"message": "Case assigned successfully",
|
| 281 |
+
"case": {
|
| 282 |
+
"case_id": "case-uuid-here",
|
| 283 |
+
"assigned_agent": "agent-uuid-here",
|
| 284 |
+
"status": "In Progress",
|
| 285 |
+
"assigned_at": "2024-01-15T11:00:00.000Z"
|
| 286 |
+
}
|
| 287 |
+
}
|
| 288 |
+
```
|
| 289 |
+
|
| 290 |
+
### 3.5 Accept Case (Agent Only) ⭐ NEW
|
| 291 |
+
- **Endpoint:** `/api/cases/:case_id/accept`
|
| 292 |
+
- **Method:** `PUT`
|
| 293 |
+
- **Auth Required:** Yes (Agent)
|
| 294 |
+
- **Request Body:** None
|
| 295 |
+
- **Response:**
|
| 296 |
+
```json
|
| 297 |
+
{
|
| 298 |
+
"message": "Case accepted successfully",
|
| 299 |
+
"case": {
|
| 300 |
+
"case_id": "case-uuid-here",
|
| 301 |
+
"case_applicant_name": "John Doe",
|
| 302 |
+
"status": "Pending",
|
| 303 |
+
"assigned_agent": "agent-uuid-here",
|
| 304 |
+
"accepted_at": "2024-01-15T11:30:00.000Z",
|
| 305 |
+
"updated_at": "2024-01-15T11:30:00.000Z"
|
| 306 |
+
}
|
| 307 |
+
}
|
| 308 |
+
```
|
| 309 |
+
|
| 310 |
+
### 3.6 Update Case (Complete or Partial)
|
| 311 |
+
- **Endpoint:** `/api/cases/:case_id`
|
| 312 |
+
- **Method:** `PUT`
|
| 313 |
+
- **Auth Required:** Yes (Agent or Admin)
|
| 314 |
+
- **Request Body (Example - Update Demographics):**
|
| 315 |
+
```json
|
| 316 |
+
{
|
| 317 |
+
"demographic_details": {
|
| 318 |
+
"aadhaar_photo_match": true,
|
| 319 |
+
"contact_information": {
|
| 320 |
+
"email_id": "john@example.com",
|
| 321 |
+
"mobile_number": "9876543210"
|
| 322 |
+
},
|
| 323 |
+
"personal_details": {
|
| 324 |
+
"gender": "Male",
|
| 325 |
+
"education": "Graduate",
|
| 326 |
+
"number_of_family_members": 4
|
| 327 |
+
},
|
| 328 |
+
"address_details": {
|
| 329 |
+
"residence_address_type": "Own",
|
| 330 |
+
"residential_address": "123 Main Street",
|
| 331 |
+
"city": "Mumbai",
|
| 332 |
+
"state": "Maharashtra",
|
| 333 |
+
"district": "Mumbai Suburban",
|
| 334 |
+
"pincode": "400001"
|
| 335 |
+
}
|
| 336 |
+
}
|
| 337 |
+
}
|
| 338 |
+
```
|
| 339 |
+
- **Response:**
|
| 340 |
+
```json
|
| 341 |
+
{
|
| 342 |
+
"message": "Case updated successfully",
|
| 343 |
+
"case": {
|
| 344 |
+
"case_id": "case-uuid-here",
|
| 345 |
+
"status": "Pending",
|
| 346 |
+
"updated_at": "2024-01-15T15:00:00.000Z"
|
| 347 |
+
}
|
| 348 |
+
}
|
| 349 |
+
```
|
| 350 |
+
|
| 351 |
+
### 3.7 Update Case Section
|
| 352 |
+
- **Endpoint:** `/api/cases/:case_id/:section`
|
| 353 |
+
- **Method:** `PATCH`
|
| 354 |
+
- **Auth Required:** Yes (Agent or Admin)
|
| 355 |
+
- **Sections:** `demographic_details`, `business_details`, `financial_details`
|
| 356 |
+
- **Request Body:**
|
| 357 |
+
```json
|
| 358 |
+
{
|
| 359 |
+
"business_financial_information": {
|
| 360 |
+
"monthly_income_from_business": 50000,
|
| 361 |
+
"monthly_expense_of_business": 30000
|
| 362 |
+
}
|
| 363 |
+
}
|
| 364 |
+
```
|
| 365 |
+
- **Response:**
|
| 366 |
+
```json
|
| 367 |
+
{
|
| 368 |
+
"message": "financial_details updated successfully",
|
| 369 |
+
"case": {
|
| 370 |
+
"case_id": "case-uuid-here",
|
| 371 |
+
"financial_details": {
|
| 372 |
+
"business_financial_information": {
|
| 373 |
+
"monthly_income_from_business": 50000,
|
| 374 |
+
"monthly_expense_of_business": 30000
|
| 375 |
+
}
|
| 376 |
+
}
|
| 377 |
+
}
|
| 378 |
+
}
|
| 379 |
+
```
|
| 380 |
+
|
| 381 |
+
### 3.8 Delete Case (Admin Only)
|
| 382 |
+
- **Endpoint:** `/api/cases/:case_id`
|
| 383 |
+
- **Method:** `DELETE`
|
| 384 |
+
- **Auth Required:** Yes (Admin)
|
| 385 |
+
- **Response:**
|
| 386 |
+
```json
|
| 387 |
+
{
|
| 388 |
+
"message": "Case and associated files deleted"
|
| 389 |
+
}
|
| 390 |
+
```
|
| 391 |
+
|
| 392 |
+
---
|
| 393 |
+
|
| 394 |
+
## 4. File Endpoints
|
| 395 |
+
|
| 396 |
+
### 4.1 Upload File
|
| 397 |
+
- **Endpoint:** `/api/cases/:case_id/files`
|
| 398 |
+
- **Method:** `POST`
|
| 399 |
+
- **Auth Required:** Yes (Agent or Admin)
|
| 400 |
+
- **Content-Type:** `multipart/form-data`
|
| 401 |
+
- **Form Data:**
|
| 402 |
+
- `file`: File to upload
|
| 403 |
+
- `file_type`: `customer_photo`, `residence_photo`, `business_photo`, `document`
|
| 404 |
+
- `geo_lat`: Optional latitude
|
| 405 |
+
- `geo_lng`: Optional longitude
|
| 406 |
+
- **Response:**
|
| 407 |
+
```json
|
| 408 |
+
{
|
| 409 |
+
"message": "File uploaded successfully",
|
| 410 |
+
"file_id": "file-uuid-here",
|
| 411 |
+
"filename": "photo.jpg",
|
| 412 |
+
"file_size": 204800,
|
| 413 |
+
"file_type": "customer_photo",
|
| 414 |
+
"uploaded_at": "2024-01-15T11:30:00.000Z"
|
| 415 |
+
}
|
| 416 |
+
```
|
| 417 |
+
|
| 418 |
+
### 4.2 Get All Files for Case
|
| 419 |
+
- **Endpoint:** `/api/cases/:case_id/files`
|
| 420 |
+
- **Method:** `GET`
|
| 421 |
+
- **Auth Required:** Yes
|
| 422 |
+
- **Response:**
|
| 423 |
+
```json
|
| 424 |
+
{
|
| 425 |
+
"files": [
|
| 426 |
+
{
|
| 427 |
+
"file_id": "file-uuid-here",
|
| 428 |
+
"filename": "file-uuid_photo.jpg",
|
| 429 |
+
"original_name": "photo.jpg",
|
| 430 |
+
"file_type": "customer_photo",
|
| 431 |
+
"mime_type": "image/jpeg",
|
| 432 |
+
"file_size": 204800,
|
| 433 |
+
"geo_location": {
|
| 434 |
+
"lat": 19.0760,
|
| 435 |
+
"lng": 72.8777
|
| 436 |
+
},
|
| 437 |
+
"uploaded_at": "2024-01-15T11:30:00.000Z",
|
| 438 |
+
"uploaded_by": "agent-uuid"
|
| 439 |
+
}
|
| 440 |
+
]
|
| 441 |
+
}
|
| 442 |
+
```
|
| 443 |
+
|
| 444 |
+
### 4.3 Download File
|
| 445 |
+
- **Endpoint:** `/api/files/:file_id`
|
| 446 |
+
- **Method:** `GET`
|
| 447 |
+
- **Auth Required:** Yes
|
| 448 |
+
- **Response:** Binary file data with appropriate headers
|
| 449 |
+
|
| 450 |
+
### 4.4 Delete File
|
| 451 |
+
- **Endpoint:** `/api/files/:file_id`
|
| 452 |
+
- **Method:** `DELETE`
|
| 453 |
+
- **Auth Required:** Yes (Agent or Admin)
|
| 454 |
+
- **Response:**
|
| 455 |
+
```json
|
| 456 |
+
{
|
| 457 |
+
"message": "File deleted successfully"
|
| 458 |
+
}
|
| 459 |
+
```
|
| 460 |
+
|
| 461 |
+
---
|
| 462 |
+
|
| 463 |
+
## 5. Dashboard Endpoints
|
| 464 |
+
|
| 465 |
+
### 5.1 Get Statistics
|
| 466 |
+
- **Endpoint:** `/api/dashboard/stats`
|
| 467 |
+
- **Method:** `GET`
|
| 468 |
+
- **Auth Required:** Yes
|
| 469 |
+
- **Query Params:** `?agent_id=uuid` (Admin only)
|
| 470 |
+
- **Response:**
|
| 471 |
+
```json
|
| 472 |
+
{
|
| 473 |
+
"total": 150,
|
| 474 |
+
"unassigned": 20,
|
| 475 |
+
"in_progress": 30,
|
| 476 |
+
"pending": 50,
|
| 477 |
+
"completed": 50,
|
| 478 |
+
"by_case_type": {
|
| 479 |
+
"business_loan": 60,
|
| 480 |
+
"personal_loan": 40,
|
| 481 |
+
"credit_card": 30,
|
| 482 |
+
"home_loan": 20
|
| 483 |
+
},
|
| 484 |
+
"by_priority": {
|
| 485 |
+
"low": 40,
|
| 486 |
+
"med": 80,
|
| 487 |
+
"high": 30
|
| 488 |
+
},
|
| 489 |
+
"total_loan_amount": 75000000,
|
| 490 |
+
"average_loan_amount": 500000
|
| 491 |
+
}
|
| 492 |
+
```
|
| 493 |
+
|
| 494 |
+
### 5.2 Get Agent Performance (Admin Only)
|
| 495 |
+
- **Endpoint:** `/api/dashboard/agent-performance`
|
| 496 |
+
- **Method:** `GET`
|
| 497 |
+
- **Auth Required:** Yes (Admin)
|
| 498 |
+
- **Response:**
|
| 499 |
+
```json
|
| 500 |
+
{
|
| 501 |
+
"agent_performance": [
|
| 502 |
+
{
|
| 503 |
+
"agent_id": "agent-uuid",
|
| 504 |
+
"agent_name": "Agent Name",
|
| 505 |
+
"agent_email": "agent@example.com",
|
| 506 |
+
"total_cases": 25,
|
| 507 |
+
"completed": 15,
|
| 508 |
+
"in_progress": 5,
|
| 509 |
+
"pending": 5,
|
| 510 |
+
"total_loan_amount": 12500000,
|
| 511 |
+
"average_loan_amount": 500000,
|
| 512 |
+
"priority_breakdown": {
|
| 513 |
+
"low": 5,
|
| 514 |
+
"med": 15,
|
| 515 |
+
"high": 5
|
| 516 |
+
}
|
| 517 |
+
}
|
| 518 |
+
]
|
| 519 |
+
}
|
| 520 |
+
```
|
| 521 |
+
|
| 522 |
+
---
|
| 523 |
+
|
| 524 |
+
## 6. Public Endpoints
|
| 525 |
+
|
| 526 |
+
### 6.1 Health Check
|
| 527 |
+
- **Endpoint:** `/health`
|
| 528 |
+
- **Method:** `GET`
|
| 529 |
+
- **Auth Required:** No
|
| 530 |
+
- **Response:**
|
| 531 |
+
```json
|
| 532 |
+
{
|
| 533 |
+
"status": "healthy",
|
| 534 |
+
"database": "connected",
|
| 535 |
+
"timestamp": "2024-01-15T12:00:00.000Z"
|
| 536 |
+
}
|
| 537 |
+
```
|
| 538 |
+
|
| 539 |
+
### 6.2 API Status
|
| 540 |
+
- **Endpoint:** `/`
|
| 541 |
+
- **Method:** `GET`
|
| 542 |
+
- **Auth Required:** No
|
| 543 |
+
- **Response:**
|
| 544 |
+
```json
|
| 545 |
+
{
|
| 546 |
+
"status": "CPV API Running - Biz2Credit",
|
| 547 |
+
"timestamp": "2024-01-15T12:00:00.000Z",
|
| 548 |
+
"version": "2.0.0",
|
| 549 |
+
"authentication": "JWT Token Required for Protected Routes",
|
| 550 |
+
"endpoints": {
|
| 551 |
+
"admin": "/api/admin/*",
|
| 552 |
+
"agents": "/api/agents/*",
|
| 553 |
+
"cases": "/api/cases/*",
|
| 554 |
+
"files": "/api/files/*",
|
| 555 |
+
"dashboard": "/api/dashboard/*"
|
| 556 |
+
}
|
| 557 |
+
}
|
| 558 |
+
```
|
| 559 |
+
|
| 560 |
+
---
|
| 561 |
+
|
| 562 |
+
## Status Flow
|
| 563 |
+
|
| 564 |
+
1. **Unassigned** → Case created, no agent assigned
|
| 565 |
+
2. **In Progress** → Admin assigns case to agent
|
| 566 |
+
3. **Pending** → Agent accepts the case ⭐ NEW
|
| 567 |
+
4. **Completed** → Agent marks case as completed
|
| 568 |
+
|
| 569 |
+
## Case Types
|
| 570 |
+
|
| 571 |
+
- `Business Loan`
|
| 572 |
+
- `Personal Loan`
|
| 573 |
+
- `Credit Card`
|
| 574 |
+
- `Home Loan`
|
| 575 |
+
|
| 576 |
+
## Priority Levels
|
| 577 |
+
|
| 578 |
+
- `LOW`
|
| 579 |
+
- `MED`
|
| 580 |
+
- `HIGH`
|
| 581 |
+
|
| 582 |
+
## Error Responses
|
| 583 |
+
|
| 584 |
+
**401 Unauthorized:**
|
| 585 |
+
```json
|
| 586 |
+
{
|
| 587 |
+
"error": "Access token required"
|
| 588 |
+
}
|
| 589 |
+
```
|
| 590 |
+
|
| 591 |
+
**403 Forbidden:**
|
| 592 |
+
```json
|
| 593 |
+
{
|
| 594 |
+
"error": "Admin access required"
|
| 595 |
+
}
|
| 596 |
+
```
|
| 597 |
+
|
| 598 |
+
**404 Not Found:**
|
| 599 |
+
```json
|
| 600 |
+
{
|
| 601 |
+
"error": "Case not found"
|
| 602 |
+
}
|
| 603 |
+
```
|
| 604 |
+
|
| 605 |
+
**400 Bad Request:**
|
| 606 |
+
```json
|
| 607 |
+
{
|
| 608 |
+
"error": "Validation failed",
|
| 609 |
+
"message": "Invalid case type"
|
| 610 |
+
}
|
| 611 |
+
```
|
verify_refactor.js
ADDED
|
@@ -0,0 +1,682 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
require('dotenv').config();
|
| 2 |
+
const mongoose = require('mongoose');
|
| 3 |
+
const { connectDB, Case } = require('./models');
|
| 4 |
+
const { v4: uuidv4 } = require('uuid');
|
| 5 |
+
|
| 6 |
+
async function verifyModel() {
|
| 7 |
+
try {
|
| 8 |
+
await connectDB();
|
| 9 |
+
console.log('Connected to DB');
|
| 10 |
+
|
| 11 |
+
// Full JSON payload from the new API
|
| 12 |
+
const apiResponse = {
|
| 13 |
+
"applicationId": 39295,
|
| 14 |
+
"message": "Successfully get Details !!",
|
| 15 |
+
"data": {
|
| 16 |
+
"applicantDetail": {
|
| 17 |
+
"userId": 135860,
|
| 18 |
+
"panNumber": null,
|
| 19 |
+
"dob": "24-11-1990",
|
| 20 |
+
"voterId": "ABC1234567",
|
| 21 |
+
"email": "parvej@gmail.com",
|
| 22 |
+
"mobile": "8000051783",
|
| 23 |
+
"alternateMobile": "8000051784",
|
| 24 |
+
"socialCategoryId": 1,
|
| 25 |
+
"aadharRefNumber": "800180018019",
|
| 26 |
+
"urnNumber": null,
|
| 27 |
+
"isFromLsp": null,
|
| 28 |
+
"name": "Parvez mansuri",
|
| 29 |
+
"genderId": 1,
|
| 30 |
+
"maritalStatus": 1,
|
| 31 |
+
"qualification": 4,
|
| 32 |
+
"religion": 6,
|
| 33 |
+
"womanEntrepreneur": 0,
|
| 34 |
+
"divyang": 0,
|
| 35 |
+
"serviceman": 0,
|
| 36 |
+
"fatherName": "fname",
|
| 37 |
+
"motherName": "mname",
|
| 38 |
+
"spouseName": "sname",
|
| 39 |
+
"spouseDob": "24-11-1992",
|
| 40 |
+
"numOfDependent": 4,
|
| 41 |
+
"illness": 7,
|
| 42 |
+
"primaryId": 2,
|
| 43 |
+
"secodaryId": 1,
|
| 44 |
+
"primaryDoc": 95988,
|
| 45 |
+
"secodaryDoc": 95989,
|
| 46 |
+
"applicantImg": 95990,
|
| 47 |
+
"urnFound": 0,
|
| 48 |
+
"daId": 1,
|
| 49 |
+
"numEarFamiMemb": 1,
|
| 50 |
+
"primaryFileDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 51 |
+
"secondaryFileDetail": "certificate_1758545658.pdf | 192kb | 24/11/2025",
|
| 52 |
+
"applicantFileDetail": "certificate_1758545652.pdf | 192kb | 24/11/2025",
|
| 53 |
+
"addresProofDetail": "certificate_1758545631.pdf | 192kb | 24-11-2025",
|
| 54 |
+
"updateResiAddrss": true,
|
| 55 |
+
"profileId": 24306
|
| 56 |
+
},
|
| 57 |
+
"residenceDetail": {
|
| 58 |
+
"id": 18431,
|
| 59 |
+
"ownershipStatus": 2,
|
| 60 |
+
"address1": "test1",
|
| 61 |
+
"address2": "test2",
|
| 62 |
+
"address3": "test3",
|
| 63 |
+
"cityId": 783,
|
| 64 |
+
"districtId": 134,
|
| 65 |
+
"stateId": 24,
|
| 66 |
+
"pincode": "380001",
|
| 67 |
+
"addressProofType": 2,
|
| 68 |
+
"addressProofId": 95992,
|
| 69 |
+
"addresProofDetail": "certificate_1758545631.pdf | 192kb | 24-11-2025",
|
| 70 |
+
"updateResiAddrss": null
|
| 71 |
+
},
|
| 72 |
+
"coApplicantDetail": {
|
| 73 |
+
"name": "OPL",
|
| 74 |
+
"panNumber": null,
|
| 75 |
+
"email": null,
|
| 76 |
+
"dob": "24-11-1991",
|
| 77 |
+
"mobile": "8000051785",
|
| 78 |
+
"gender": 1,
|
| 79 |
+
"maritalStatus": 2,
|
| 80 |
+
"relationshipWithApplicantId": 6,
|
| 81 |
+
"occupationId": 2,
|
| 82 |
+
"primaryId": 2,
|
| 83 |
+
"secondaryId": 1,
|
| 84 |
+
"primaryDoc": 96005,
|
| 85 |
+
"secondaryDoc": 96006,
|
| 86 |
+
"voterId": "ABC1234567",
|
| 87 |
+
"applicantImg": 96007,
|
| 88 |
+
"sameAsResidential": false,
|
| 89 |
+
"ownership": null,
|
| 90 |
+
"address1": "test7",
|
| 91 |
+
"address2": null,
|
| 92 |
+
"address3": null,
|
| 93 |
+
"landmark": null,
|
| 94 |
+
"cityId": 783,
|
| 95 |
+
"districtId": 134,
|
| 96 |
+
"stateId": 24,
|
| 97 |
+
"pincode": "380001",
|
| 98 |
+
"applicantImgDetail": "certificate_1758545652.pdf | 192kb | 24/11/2025",
|
| 99 |
+
"primaryFileDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 100 |
+
"secondaryFileDetail": "certificate_1758545658.pdf | 192kb | 24/11/2025"
|
| 101 |
+
},
|
| 102 |
+
"businessDetail": {
|
| 103 |
+
"businessName": "parvez enterprise",
|
| 104 |
+
"businessType": 4,
|
| 105 |
+
"natureActivity": 1,
|
| 106 |
+
"areaType": 3,
|
| 107 |
+
"organizationType": 1,
|
| 108 |
+
"establishDate": "1970-01-01",
|
| 109 |
+
"panNumber": "NEMPM0285K",
|
| 110 |
+
"businessLocation": 1,
|
| 111 |
+
"workExperienceInYears": 5,
|
| 112 |
+
"addressId": 18432,
|
| 113 |
+
"ownershipStatus": 1,
|
| 114 |
+
"address1": "test4",
|
| 115 |
+
"address2": null,
|
| 116 |
+
"landmark": null,
|
| 117 |
+
"cityId": 783,
|
| 118 |
+
"districtId": 134,
|
| 119 |
+
"stateId": 24,
|
| 120 |
+
"pincode": "380001",
|
| 121 |
+
"businessProofType": 1,
|
| 122 |
+
"businessProofDoc": 95993,
|
| 123 |
+
"businessProofDetail": "certificate_1758545662.pdf | 192kb | 24/11/2025",
|
| 124 |
+
"updateBusinessAddrss": true
|
| 125 |
+
},
|
| 126 |
+
"incomeExpenditure": {
|
| 127 |
+
"monthlyIncome": 60000.00,
|
| 128 |
+
"freqOfIncome": 2,
|
| 129 |
+
"incomeDays": 30,
|
| 130 |
+
"avgIncomeDailyBasis": 2000.00,
|
| 131 |
+
"yearlyIncome": 750000.00,
|
| 132 |
+
"incomeFromOtherSource": 0.00,
|
| 133 |
+
"rationCard": 0,
|
| 134 |
+
"totalIncome": 750000.00,
|
| 135 |
+
"appType": 1
|
| 136 |
+
},
|
| 137 |
+
"familyExpenses": {
|
| 138 |
+
"householdExp": 100000.00,
|
| 139 |
+
"utilityExp": 10000.00,
|
| 140 |
+
"eduExp": 11000.00,
|
| 141 |
+
"mediExp": 12000.00,
|
| 142 |
+
"mediExpCritical": 13000.00,
|
| 143 |
+
"foodExp": 14000.00,
|
| 144 |
+
"grocExp": 15000.00,
|
| 145 |
+
"cookingExp": 16000.00,
|
| 146 |
+
"otherExp": 17000.00,
|
| 147 |
+
"clothing": 18000.00,
|
| 148 |
+
"transpExp": 19000.00,
|
| 149 |
+
"otherBusiExp": 20000.00,
|
| 150 |
+
"totalExp": 265000.00
|
| 151 |
+
}
|
| 152 |
+
},
|
| 153 |
+
"metaData": {
|
| 154 |
+
"genderId": [
|
| 155 |
+
{
|
| 156 |
+
"id": 1,
|
| 157 |
+
"value": "Male"
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"id": 2,
|
| 161 |
+
"value": "Female"
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"id": 3,
|
| 165 |
+
"value": "Other"
|
| 166 |
+
}
|
| 167 |
+
],
|
| 168 |
+
"maritalStatus": [
|
| 169 |
+
{
|
| 170 |
+
"id": 1,
|
| 171 |
+
"value": "Married "
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"id": 2,
|
| 175 |
+
"value": "Unmarried"
|
| 176 |
+
},
|
| 177 |
+
{
|
| 178 |
+
"id": 3,
|
| 179 |
+
"value": "Others"
|
| 180 |
+
}
|
| 181 |
+
],
|
| 182 |
+
"qualification": [
|
| 183 |
+
{
|
| 184 |
+
"id": 1,
|
| 185 |
+
"value": "illiterate"
|
| 186 |
+
},
|
| 187 |
+
{
|
| 188 |
+
"id": 2,
|
| 189 |
+
"value": "Upto 10"
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"id": 3,
|
| 193 |
+
"value": "11 to 12"
|
| 194 |
+
},
|
| 195 |
+
{
|
| 196 |
+
"id": 4,
|
| 197 |
+
"value": "Graduate and Above"
|
| 198 |
+
}
|
| 199 |
+
],
|
| 200 |
+
"religion": [
|
| 201 |
+
{
|
| 202 |
+
"id": 1,
|
| 203 |
+
"value": "Shikh"
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"id": 2,
|
| 207 |
+
"value": "Muslim"
|
| 208 |
+
},
|
| 209 |
+
{
|
| 210 |
+
"id": 3,
|
| 211 |
+
"value": "Christian"
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"id": 4,
|
| 215 |
+
"value": "Zoroastrian"
|
| 216 |
+
},
|
| 217 |
+
{
|
| 218 |
+
"id": 5,
|
| 219 |
+
"value": "Buddhist"
|
| 220 |
+
},
|
| 221 |
+
{
|
| 222 |
+
"id": 6,
|
| 223 |
+
"value": "Jain"
|
| 224 |
+
},
|
| 225 |
+
{
|
| 226 |
+
"id": 7,
|
| 227 |
+
"value": "Hindu"
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"id": 8,
|
| 231 |
+
"value": "Other"
|
| 232 |
+
}
|
| 233 |
+
],
|
| 234 |
+
"socialCategoryId": [
|
| 235 |
+
{
|
| 236 |
+
"id": 1,
|
| 237 |
+
"value": "General"
|
| 238 |
+
},
|
| 239 |
+
{
|
| 240 |
+
"id": 2,
|
| 241 |
+
"value": "SC"
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"id": 3,
|
| 245 |
+
"value": "ST"
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"id": 4,
|
| 249 |
+
"value": "OBC"
|
| 250 |
+
}
|
| 251 |
+
],
|
| 252 |
+
"addressProofType": [
|
| 253 |
+
{
|
| 254 |
+
"id": 1,
|
| 255 |
+
"value": "Rent Agreement"
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"id": 2,
|
| 259 |
+
"value": "Electricity Bill"
|
| 260 |
+
}
|
| 261 |
+
],
|
| 262 |
+
"occupationId": [
|
| 263 |
+
{
|
| 264 |
+
"id": 1,
|
| 265 |
+
"value": "Service"
|
| 266 |
+
},
|
| 267 |
+
{
|
| 268 |
+
"id": 2,
|
| 269 |
+
"value": "Business"
|
| 270 |
+
},
|
| 271 |
+
{
|
| 272 |
+
"id": 3,
|
| 273 |
+
"value": "Other"
|
| 274 |
+
}
|
| 275 |
+
],
|
| 276 |
+
"relationshipWithApplicantId": [
|
| 277 |
+
{
|
| 278 |
+
"id": 1,
|
| 279 |
+
"value": "Father"
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"id": 2,
|
| 283 |
+
"value": "Mother"
|
| 284 |
+
},
|
| 285 |
+
{
|
| 286 |
+
"id": 3,
|
| 287 |
+
"value": "Brother"
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"id": 4,
|
| 291 |
+
"value": "Sister"
|
| 292 |
+
},
|
| 293 |
+
{
|
| 294 |
+
"id": 5,
|
| 295 |
+
"value": "Spouse"
|
| 296 |
+
},
|
| 297 |
+
{
|
| 298 |
+
"id": 6,
|
| 299 |
+
"value": "Brother-in-law"
|
| 300 |
+
},
|
| 301 |
+
{
|
| 302 |
+
"id": 7,
|
| 303 |
+
"value": "Son"
|
| 304 |
+
},
|
| 305 |
+
{
|
| 306 |
+
"id": 8,
|
| 307 |
+
"value": "Daughter"
|
| 308 |
+
},
|
| 309 |
+
{
|
| 310 |
+
"id": 9,
|
| 311 |
+
"value": "Daughter-in-law"
|
| 312 |
+
},
|
| 313 |
+
{
|
| 314 |
+
"id": 10,
|
| 315 |
+
"value": "Father-in-Law"
|
| 316 |
+
},
|
| 317 |
+
{
|
| 318 |
+
"id": 11,
|
| 319 |
+
"value": "Grand daughter"
|
| 320 |
+
},
|
| 321 |
+
{
|
| 322 |
+
"id": 12,
|
| 323 |
+
"value": "Grand Father"
|
| 324 |
+
},
|
| 325 |
+
{
|
| 326 |
+
"id": 13,
|
| 327 |
+
"value": "Grand Mother"
|
| 328 |
+
},
|
| 329 |
+
{
|
| 330 |
+
"id": 14,
|
| 331 |
+
"value": "Grand Son"
|
| 332 |
+
},
|
| 333 |
+
{
|
| 334 |
+
"id": 15,
|
| 335 |
+
"value": "Mother-in-law"
|
| 336 |
+
},
|
| 337 |
+
{
|
| 338 |
+
"id": 16,
|
| 339 |
+
"value": "Sister-in law"
|
| 340 |
+
},
|
| 341 |
+
{
|
| 342 |
+
"id": 17,
|
| 343 |
+
"value": "Son-in-law"
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"id": 18,
|
| 347 |
+
"value": "Others"
|
| 348 |
+
}
|
| 349 |
+
],
|
| 350 |
+
"primaryId": [
|
| 351 |
+
{
|
| 352 |
+
"id": 1,
|
| 353 |
+
"value": "PAN Card"
|
| 354 |
+
},
|
| 355 |
+
{
|
| 356 |
+
"id": 2,
|
| 357 |
+
"value": "Form-60"
|
| 358 |
+
}
|
| 359 |
+
],
|
| 360 |
+
"secondaryId": [
|
| 361 |
+
{
|
| 362 |
+
"id": 1,
|
| 363 |
+
"value": "Voter ID"
|
| 364 |
+
},
|
| 365 |
+
{
|
| 366 |
+
"id": 2,
|
| 367 |
+
"value": "PAN"
|
| 368 |
+
},
|
| 369 |
+
{
|
| 370 |
+
"id": 3,
|
| 371 |
+
"value": "Passport"
|
| 372 |
+
},
|
| 373 |
+
{
|
| 374 |
+
"id": 4,
|
| 375 |
+
"value": "Driving License"
|
| 376 |
+
},
|
| 377 |
+
{
|
| 378 |
+
"id": 5,
|
| 379 |
+
"value": "Job Card"
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"id": 6,
|
| 383 |
+
"value": "Letter by NPR"
|
| 384 |
+
},
|
| 385 |
+
{
|
| 386 |
+
"id": 7,
|
| 387 |
+
"value": "Form-16"
|
| 388 |
+
}
|
| 389 |
+
],
|
| 390 |
+
"illness": [
|
| 391 |
+
{
|
| 392 |
+
"id": 1,
|
| 393 |
+
"value": "Severe Organ Failure"
|
| 394 |
+
},
|
| 395 |
+
{
|
| 396 |
+
"id": 2,
|
| 397 |
+
"value": "Heart Attack"
|
| 398 |
+
},
|
| 399 |
+
{
|
| 400 |
+
"id": 3,
|
| 401 |
+
"value": "Stroke"
|
| 402 |
+
},
|
| 403 |
+
{
|
| 404 |
+
"id": 4,
|
| 405 |
+
"value": "Cancer"
|
| 406 |
+
},
|
| 407 |
+
{
|
| 408 |
+
"id": 5,
|
| 409 |
+
"value": "Kidney Failure"
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"id": 6,
|
| 413 |
+
"value": "Organ Transplants"
|
| 414 |
+
},
|
| 415 |
+
{
|
| 416 |
+
"id": 7,
|
| 417 |
+
"value": "N/A"
|
| 418 |
+
}
|
| 419 |
+
],
|
| 420 |
+
"organizationType": [
|
| 421 |
+
{
|
| 422 |
+
"id": 1,
|
| 423 |
+
"value": "Proprietory"
|
| 424 |
+
}
|
| 425 |
+
],
|
| 426 |
+
"businessLocation": [
|
| 427 |
+
{
|
| 428 |
+
"id": 1,
|
| 429 |
+
"value": "Fixed"
|
| 430 |
+
},
|
| 431 |
+
{
|
| 432 |
+
"id": 2,
|
| 433 |
+
"value": "Mobile"
|
| 434 |
+
}
|
| 435 |
+
],
|
| 436 |
+
"ownershipStatus": [
|
| 437 |
+
{
|
| 438 |
+
"id": 1,
|
| 439 |
+
"value": "Rented"
|
| 440 |
+
},
|
| 441 |
+
{
|
| 442 |
+
"id": 2,
|
| 443 |
+
"value": "Owned"
|
| 444 |
+
}
|
| 445 |
+
],
|
| 446 |
+
"areaType": [
|
| 447 |
+
{
|
| 448 |
+
"id": 1,
|
| 449 |
+
"value": "Rural"
|
| 450 |
+
},
|
| 451 |
+
{
|
| 452 |
+
"id": 3,
|
| 453 |
+
"value": "Semi Urban"
|
| 454 |
+
},
|
| 455 |
+
{
|
| 456 |
+
"id": 2,
|
| 457 |
+
"value": "Urban"
|
| 458 |
+
}
|
| 459 |
+
],
|
| 460 |
+
"businessType": [
|
| 461 |
+
{
|
| 462 |
+
"id": 1,
|
| 463 |
+
"value": "Manufacturing"
|
| 464 |
+
},
|
| 465 |
+
{
|
| 466 |
+
"id": 2,
|
| 467 |
+
"value": "Services"
|
| 468 |
+
},
|
| 469 |
+
{
|
| 470 |
+
"id": 3,
|
| 471 |
+
"value": "Services-Trading"
|
| 472 |
+
},
|
| 473 |
+
{
|
| 474 |
+
"id": 4,
|
| 475 |
+
"value": "Other"
|
| 476 |
+
}
|
| 477 |
+
],
|
| 478 |
+
"workExperienceInYears": [
|
| 479 |
+
{
|
| 480 |
+
"id": 1,
|
| 481 |
+
"value": "1"
|
| 482 |
+
},
|
| 483 |
+
{
|
| 484 |
+
"id": 2,
|
| 485 |
+
"value": "2"
|
| 486 |
+
},
|
| 487 |
+
{
|
| 488 |
+
"id": 3,
|
| 489 |
+
"value": "3"
|
| 490 |
+
},
|
| 491 |
+
{
|
| 492 |
+
"id": 4,
|
| 493 |
+
"value": "4"
|
| 494 |
+
},
|
| 495 |
+
{
|
| 496 |
+
"id": 5,
|
| 497 |
+
"value": "5"
|
| 498 |
+
},
|
| 499 |
+
{
|
| 500 |
+
"id": 6,
|
| 501 |
+
"value": "6"
|
| 502 |
+
},
|
| 503 |
+
{
|
| 504 |
+
"id": 7,
|
| 505 |
+
"value": "7"
|
| 506 |
+
},
|
| 507 |
+
{
|
| 508 |
+
"id": 8,
|
| 509 |
+
"value": "8"
|
| 510 |
+
},
|
| 511 |
+
{
|
| 512 |
+
"id": 9,
|
| 513 |
+
"value": "9"
|
| 514 |
+
},
|
| 515 |
+
{
|
| 516 |
+
"id": 10,
|
| 517 |
+
"value": "10"
|
| 518 |
+
},
|
| 519 |
+
{
|
| 520 |
+
"id": 11,
|
| 521 |
+
"value": "11"
|
| 522 |
+
},
|
| 523 |
+
{
|
| 524 |
+
"id": 12,
|
| 525 |
+
"value": "12"
|
| 526 |
+
},
|
| 527 |
+
{
|
| 528 |
+
"id": 13,
|
| 529 |
+
"value": "13"
|
| 530 |
+
},
|
| 531 |
+
{
|
| 532 |
+
"id": 14,
|
| 533 |
+
"value": "14"
|
| 534 |
+
},
|
| 535 |
+
{
|
| 536 |
+
"id": 15,
|
| 537 |
+
"value": "More than 15"
|
| 538 |
+
}
|
| 539 |
+
],
|
| 540 |
+
"applicantDetail": {
|
| 541 |
+
"daId": [
|
| 542 |
+
{
|
| 543 |
+
"id": null,
|
| 544 |
+
"value": null
|
| 545 |
+
}
|
| 546 |
+
]
|
| 547 |
+
},
|
| 548 |
+
"businessDetail": {
|
| 549 |
+
"districtId": [
|
| 550 |
+
{
|
| 551 |
+
"id": 134,
|
| 552 |
+
"value": "AHMADABAD"
|
| 553 |
+
}
|
| 554 |
+
],
|
| 555 |
+
"stateId": [
|
| 556 |
+
{
|
| 557 |
+
"id": 24,
|
| 558 |
+
"value": "Meghalaya"
|
| 559 |
+
}
|
| 560 |
+
],
|
| 561 |
+
"natureActivity": [
|
| 562 |
+
{
|
| 563 |
+
"id": 1,
|
| 564 |
+
"value": "Retail sale of seeds, fertilisers, pesticides, machinery equipments and hand tools"
|
| 565 |
+
}
|
| 566 |
+
],
|
| 567 |
+
"cityId": [
|
| 568 |
+
{
|
| 569 |
+
"id": 783,
|
| 570 |
+
"value": "Ahmedabad"
|
| 571 |
+
}
|
| 572 |
+
]
|
| 573 |
+
},
|
| 574 |
+
"coApplicantDetail": {
|
| 575 |
+
"districtId": [
|
| 576 |
+
{
|
| 577 |
+
"id": 134,
|
| 578 |
+
"value": "AHMADABAD"
|
| 579 |
+
}
|
| 580 |
+
],
|
| 581 |
+
"stateId": [
|
| 582 |
+
{
|
| 583 |
+
"id": 24,
|
| 584 |
+
"value": "Meghalaya"
|
| 585 |
+
}
|
| 586 |
+
],
|
| 587 |
+
"cityId": [
|
| 588 |
+
{
|
| 589 |
+
"id": 783,
|
| 590 |
+
"value": "Ahmedabad"
|
| 591 |
+
}
|
| 592 |
+
]
|
| 593 |
+
},
|
| 594 |
+
"residenceDetail": {
|
| 595 |
+
"districtId": [
|
| 596 |
+
{
|
| 597 |
+
"id": 134,
|
| 598 |
+
"value": "AHMADABAD"
|
| 599 |
+
}
|
| 600 |
+
],
|
| 601 |
+
"stateId": [
|
| 602 |
+
{
|
| 603 |
+
"id": 24,
|
| 604 |
+
"value": "Meghalaya"
|
| 605 |
+
}
|
| 606 |
+
],
|
| 607 |
+
"cityId": [
|
| 608 |
+
{
|
| 609 |
+
"id": 783,
|
| 610 |
+
"value": "Ahmedabad"
|
| 611 |
+
}
|
| 612 |
+
]
|
| 613 |
+
}
|
| 614 |
+
},
|
| 615 |
+
"status": 200,
|
| 616 |
+
"success": true
|
| 617 |
+
};
|
| 618 |
+
|
| 619 |
+
const jsonData = apiResponse.data;
|
| 620 |
+
const appId = apiResponse.applicationId || apiResponse.appIicationid;
|
| 621 |
+
|
| 622 |
+
// Simulate the logic from index.js processAndSaveBorrowerData
|
| 623 |
+
const caseData = {
|
| 624 |
+
case_id: uuidv4(),
|
| 625 |
+
application_id: appId,
|
| 626 |
+
case_applicant_name: jsonData.applicantDetail?.name || '',
|
| 627 |
+
case_applicant_contact: jsonData.applicantDetail?.mobile || '',
|
| 628 |
+
address: jsonData.residenceDetail ? `${jsonData.residenceDetail.address1}, ${jsonData.residenceDetail.cityId}` : '',
|
| 629 |
+
case_type: "Business Loan",
|
| 630 |
+
loan_amount: jsonData.incomeExpenditure?.yearlyIncome || 0,
|
| 631 |
+
priority: "MED",
|
| 632 |
+
assigned_agent: "",
|
| 633 |
+
status: "Pending",
|
| 634 |
+
|
| 635 |
+
// Save the full detailed structures
|
| 636 |
+
applicantDetail: jsonData.applicantDetail,
|
| 637 |
+
residenceDetail: jsonData.residenceDetail,
|
| 638 |
+
coApplicantDetail: jsonData.coApplicantDetail,
|
| 639 |
+
businessDetail: jsonData.businessDetail,
|
| 640 |
+
incomeExpenditure: jsonData.incomeExpenditure,
|
| 641 |
+
familyExpenses: jsonData.familyExpenses,
|
| 642 |
+
metaData: jsonData.metaData,
|
| 643 |
+
|
| 644 |
+
remarks: `Application ID: ${appId} - Verification Test`,
|
| 645 |
+
created_at: new Date(),
|
| 646 |
+
updated_at: new Date()
|
| 647 |
+
};
|
| 648 |
+
|
| 649 |
+
console.log('Attempting to save case with full API payload...');
|
| 650 |
+
const newCase = new Case(caseData);
|
| 651 |
+
await newCase.save();
|
| 652 |
+
console.log('✅ Case saved successfully!');
|
| 653 |
+
console.log('Saved Case ID:', newCase.case_id);
|
| 654 |
+
|
| 655 |
+
// Verify retrieval
|
| 656 |
+
const savedCase = await Case.findOne({ case_id: newCase.case_id });
|
| 657 |
+
|
| 658 |
+
// Verify specific fields
|
| 659 |
+
if (savedCase.applicantDetail && savedCase.applicantDetail.name === "Parvez mansuri") {
|
| 660 |
+
console.log('✅ Data retrieval verified: applicantDetail.name is correct.');
|
| 661 |
+
} else {
|
| 662 |
+
console.error(`❌ Data retrieval failed: applicantDetail.name mismatch. Expected "Parvez mansuri", got "${savedCase.applicantDetail?.name}"`);
|
| 663 |
+
}
|
| 664 |
+
|
| 665 |
+
if (savedCase.businessDetail && savedCase.businessDetail.businessName === "parvez enterprise") {
|
| 666 |
+
console.log('✅ Data retrieval verified: businessDetail.businessName is correct.');
|
| 667 |
+
} else {
|
| 668 |
+
console.error(`❌ Data retrieval failed: businessDetail.businessName mismatch. Expected "parvez enterprise", got "${savedCase.businessDetail?.businessName}"`);
|
| 669 |
+
}
|
| 670 |
+
|
| 671 |
+
// Cleanup
|
| 672 |
+
await Case.deleteOne({ case_id: newCase.case_id });
|
| 673 |
+
console.log('Cleanup done.');
|
| 674 |
+
|
| 675 |
+
process.exit(0);
|
| 676 |
+
} catch (error) {
|
| 677 |
+
console.error('❌ Verification failed:', error);
|
| 678 |
+
process.exit(1);
|
| 679 |
+
}
|
| 680 |
+
}
|
| 681 |
+
|
| 682 |
+
verifyModel();
|