@app-connect/core 1.7.36 → 1.7.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -16
- package/dist/connector/developerPortal.d.ts +6 -0
- package/{connector → dist/connector}/developerPortal.js +29 -12
- package/dist/connector/mock.d.ts +1 -0
- package/{connector → dist/connector}/mock.js +33 -17
- package/dist/connector/proxy/engine.d.ts +10 -0
- package/dist/connector/proxy/engine.js +222 -0
- package/dist/connector/proxy/index.d.ts +5 -0
- package/dist/connector/proxy/index.js +511 -0
- package/dist/connector/registry.d.ts +1 -0
- package/dist/connector/registry.js +243 -0
- package/dist/handlers/admin.d.ts +1 -0
- package/{handlers → dist/handlers}/admin.js +137 -78
- package/dist/handlers/appointment.d.ts +9 -0
- package/{handlers → dist/handlers}/appointment.js +58 -29
- package/dist/handlers/auth.d.ts +9 -0
- package/{handlers → dist/handlers}/auth.js +68 -40
- package/dist/handlers/calldown.d.ts +10 -0
- package/dist/handlers/calldown.js +134 -0
- package/dist/handlers/contact.d.ts +1 -0
- package/{handlers → dist/handlers}/contact.js +61 -39
- package/dist/handlers/disposition.d.ts +1 -0
- package/{handlers → dist/handlers}/disposition.js +20 -10
- package/dist/handlers/log.d.ts +1 -0
- package/{handlers → dist/handlers}/log.js +91 -124
- package/dist/handlers/managedAuth.d.ts +1 -0
- package/{handlers → dist/handlers}/managedAuth.js +134 -61
- package/dist/handlers/managedOAuth.d.ts +13 -0
- package/{handlers → dist/handlers}/managedOAuth.js +102 -30
- package/dist/handlers/plugin.d.ts +1 -0
- package/{handlers → dist/handlers}/plugin.js +59 -27
- package/dist/handlers/user.d.ts +1 -0
- package/{handlers → dist/handlers}/user.js +45 -27
- package/dist/index.d.ts +1 -0
- package/{index.js → dist/index.js} +548 -450
- package/dist/jest.config.d.ts +1 -0
- package/dist/jest.config.js +65 -0
- package/dist/lib/analytics.d.ts +4 -0
- package/{lib → dist/lib}/analytics.js +8 -6
- package/dist/lib/authSession.d.ts +5 -0
- package/{lib → dist/lib}/authSession.js +15 -43
- package/dist/lib/cacheCleanup.d.ts +4 -0
- package/{lib → dist/lib}/cacheCleanup.js +5 -17
- package/dist/lib/callLogComposer.d.ts +109 -0
- package/{lib → dist/lib}/callLogComposer.js +157 -197
- package/dist/lib/callLogLookup.d.ts +6 -0
- package/{lib → dist/lib}/callLogLookup.js +12 -34
- package/dist/lib/constants.d.ts +6 -0
- package/dist/lib/constants.js +9 -0
- package/dist/lib/debugTracer.d.ts +17 -0
- package/{lib → dist/lib}/debugTracer.js +7 -83
- package/dist/lib/encode.d.ts +3 -0
- package/dist/lib/encode.js +50 -0
- package/dist/lib/errorHandler.d.ts +7 -0
- package/dist/lib/errorHandler.js +161 -0
- package/dist/lib/generalErrorMessage.d.ts +7 -0
- package/{lib → dist/lib}/generalErrorMessage.js +6 -6
- package/dist/lib/jwt.d.ts +4 -0
- package/dist/lib/jwt.js +18 -0
- package/dist/lib/logger.d.ts +24 -0
- package/dist/lib/logger.js +126 -0
- package/dist/lib/migrateCallLogsSchema.d.ts +32 -0
- package/dist/lib/migrateCallLogsSchema.js +339 -0
- package/dist/lib/oauth.d.ts +4 -0
- package/{lib → dist/lib}/oauth.js +157 -160
- package/dist/lib/ringcentral.d.ts +24 -0
- package/dist/lib/ringcentral.js +226 -0
- package/dist/lib/s3ErrorLogReport.d.ts +4 -0
- package/{lib → dist/lib}/s3ErrorLogReport.js +11 -23
- package/dist/lib/sharedSMSComposer.d.ts +7 -0
- package/{lib → dist/lib}/sharedSMSComposer.js +21 -107
- package/dist/lib/util.d.ts +7 -0
- package/{lib → dist/lib}/util.js +9 -20
- package/dist/mcp/lib/oauthError.d.ts +1 -0
- package/dist/mcp/lib/oauthError.js +25 -0
- package/dist/mcp/lib/validator.d.ts +1 -0
- package/{mcp → dist/mcp}/lib/validator.js +16 -20
- package/dist/mcp/lib/widgetSessionToken.d.ts +1 -0
- package/dist/mcp/lib/widgetSessionToken.js +46 -0
- package/dist/mcp/mcpHandler.d.ts +8 -0
- package/{mcp → dist/mcp}/mcpHandler.js +98 -88
- package/dist/mcp/tools/cancelAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/cancelAppointment.js +7 -16
- package/dist/mcp/tools/checkAuthStatus.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/checkAuthStatus.js +21 -14
- package/dist/mcp/tools/confirmAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/confirmAppointment.js +7 -16
- package/dist/mcp/tools/createAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createAppointment.js +7 -19
- package/dist/mcp/tools/createCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createCallLog.js +18 -29
- package/dist/mcp/tools/createContact.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createContact.js +8 -20
- package/dist/mcp/tools/createMessageLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/createMessageLog.js +14 -26
- package/dist/mcp/tools/doAuth.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/doAuth.js +17 -13
- package/dist/mcp/tools/findContactByName.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByName.js +9 -15
- package/dist/mcp/tools/findContactByPhone.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/findContactByPhone.js +8 -15
- package/dist/mcp/tools/getCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getCallLog.js +12 -21
- package/dist/mcp/tools/getGoogleFilePicker.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getGoogleFilePicker.js +9 -18
- package/dist/mcp/tools/getHelp.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getHelp.js +5 -6
- package/dist/mcp/tools/getPublicConnectors.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getPublicConnectors.js +19 -18
- package/dist/mcp/tools/getSessionInfo.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/getSessionInfo.js +10 -16
- package/dist/mcp/tools/index.d.ts +8 -0
- package/dist/mcp/tools/index.js +50 -0
- package/dist/mcp/tools/listAppointments.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/listAppointments.js +7 -19
- package/dist/mcp/tools/logout.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/logout.js +16 -14
- package/dist/mcp/tools/rcGetCallLogs.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/rcGetCallLogs.js +10 -8
- package/dist/mcp/tools/updateAppointment.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateAppointment.js +17 -22
- package/dist/mcp/tools/updateCallLog.d.ts +1 -0
- package/{mcp → dist/mcp}/tools/updateCallLog.js +16 -26
- package/dist/models/accountDataModel.d.ts +3 -0
- package/dist/models/accountDataModel.js +39 -0
- package/dist/models/adminConfigModel.d.ts +2 -0
- package/dist/models/adminConfigModel.js +39 -0
- package/dist/models/cacheModel.d.ts +2 -0
- package/{models → dist/models}/cacheModel.js +7 -3
- package/dist/models/callDownListModel.d.ts +2 -0
- package/{models → dist/models}/callDownListModel.js +8 -4
- package/dist/models/callLogModel.d.ts +2 -0
- package/dist/models/callLogModel.js +43 -0
- package/dist/models/dynamo/connectorSchema.d.ts +2 -0
- package/dist/models/dynamo/connectorSchema.js +141 -0
- package/dist/models/dynamo/lockSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/lockSchema.js +5 -7
- package/dist/models/dynamo/noteCacheSchema.d.ts +2 -0
- package/{models → dist/models}/dynamo/noteCacheSchema.js +4 -6
- package/dist/models/llmSessionModel.d.ts +2 -0
- package/dist/models/llmSessionModel.js +21 -0
- package/dist/models/messageLogModel.d.ts +2 -0
- package/{models → dist/models}/messageLogModel.js +8 -4
- package/dist/models/sequelize.d.ts +2 -0
- package/dist/models/sequelize.js +68 -0
- package/dist/models/userModel.d.ts +2 -0
- package/dist/models/userModel.js +49 -0
- package/dist/package.json +100 -0
- package/dist/releaseNotes.json +1222 -0
- package/dist/tsconfig.json +14 -0
- package/dist/types/admin.d.ts +141 -0
- package/dist/types/analytics.d.ts +14 -0
- package/dist/types/appointment.d.ts +50 -0
- package/dist/types/auth.d.ts +137 -0
- package/dist/types/authSession.d.ts +35 -0
- package/dist/types/cacheCleanup.d.ts +12 -0
- package/dist/types/calldown.d.ts +54 -0
- package/dist/types/common.d.ts +46 -0
- package/dist/types/connector.d.ts +165 -0
- package/dist/types/contact.d.ts +125 -0
- package/dist/types/errorHandler.d.ts +60 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/types/json.d.ts +9 -0
- package/dist/types/jwt.d.ts +8 -0
- package/dist/types/logging.d.ts +224 -0
- package/dist/types/managedAuth.d.ts +114 -0
- package/dist/types/managedOAuth.d.ts +59 -0
- package/dist/types/manifest.d.ts +120 -0
- package/dist/types/migration.d.ts +15 -0
- package/dist/types/plugin.d.ts +74 -0
- package/dist/types/ringcentral.d.ts +61 -0
- package/dist/types/s3ErrorLogReport.d.ts +16 -0
- package/dist/types/sharedSMSComposer.d.ts +105 -0
- package/dist/types/user.d.ts +46 -0
- package/dist/types/util.d.ts +7 -0
- package/package.json +34 -6
- package/releaseNotes.json +13 -1
- package/.env.test +0 -5
- package/connector/proxy/engine.js +0 -165
- package/connector/proxy/index.js +0 -500
- package/connector/registry.js +0 -252
- package/docs/README.md +0 -50
- package/docs/architecture.md +0 -94
- package/docs/connectors.md +0 -116
- package/docs/handlers.md +0 -128
- package/docs/libraries.md +0 -98
- package/docs/models.md +0 -146
- package/docs/routes.md +0 -119
- package/docs/tests.md +0 -73
- package/handlers/calldown.js +0 -99
- package/jest.config.js +0 -57
- package/lib/constants.js +0 -9
- package/lib/encode.js +0 -30
- package/lib/errorHandler.js +0 -218
- package/lib/jwt.js +0 -18
- package/lib/logger.js +0 -190
- package/lib/migrateCallLogsSchema.js +0 -237
- package/lib/ringcentral.js +0 -267
- package/mcp/README.md +0 -420
- package/mcp/tools/index.js +0 -51
- package/mcp/ui/App/App.tsx +0 -358
- package/mcp/ui/App/components/AuthInfoForm.tsx +0 -113
- package/mcp/ui/App/components/AuthSuccess.tsx +0 -22
- package/mcp/ui/App/components/ConnectorList.tsx +0 -82
- package/mcp/ui/App/components/DebugPanel.tsx +0 -43
- package/mcp/ui/App/components/OAuthConnect.tsx +0 -270
- package/mcp/ui/App/lib/callTool.ts +0 -130
- package/mcp/ui/App/lib/debugLog.ts +0 -41
- package/mcp/ui/App/lib/developerPortal.ts +0 -111
- package/mcp/ui/App/main.css +0 -6
- package/mcp/ui/App/root.tsx +0 -13
- package/mcp/ui/dist/index.html +0 -53
- package/mcp/ui/vite.config.ts +0 -16
- package/models/accountDataModel.js +0 -34
- package/models/adminConfigModel.js +0 -35
- package/models/callLogModel.js +0 -39
- package/models/dynamo/connectorSchema.js +0 -146
- package/models/llmSessionModel.js +0 -17
- package/models/sequelize.js +0 -17
- package/models/userModel.js +0 -45
- package/test/connector/developerPortal.test.js +0 -166
- package/test/connector/mock.test.js +0 -131
- package/test/connector/proxy/engine.test.js +0 -211
- package/test/connector/proxy/index.test.js +0 -525
- package/test/connector/proxy/sample.json +0 -162
- package/test/connector/registry.test.js +0 -416
- package/test/handlers/admin.test.js +0 -960
- package/test/handlers/appointment.test.js +0 -260
- package/test/handlers/auth.test.js +0 -1096
- package/test/handlers/calldown.test.js +0 -310
- package/test/handlers/contact.test.js +0 -1014
- package/test/handlers/disposition.test.js +0 -396
- package/test/handlers/log.test.js +0 -1847
- package/test/handlers/managedAuth.test.js +0 -458
- package/test/handlers/managedOAuth.test.js +0 -262
- package/test/handlers/plugin.test.js +0 -429
- package/test/handlers/user.test.js +0 -381
- package/test/index.test.js +0 -301
- package/test/lib/analytics.test.js +0 -146
- package/test/lib/authSession.test.js +0 -173
- package/test/lib/cacheCleanup.test.js +0 -127
- package/test/lib/callLogComposer.test.js +0 -1231
- package/test/lib/debugTracer.test.js +0 -328
- package/test/lib/encode.test.js +0 -59
- package/test/lib/errorHandler.test.js +0 -246
- package/test/lib/generalErrorMessage.test.js +0 -82
- package/test/lib/jwt.test.js +0 -176
- package/test/lib/logger.test.js +0 -206
- package/test/lib/oauth.test.js +0 -359
- package/test/lib/ringcentral.test.js +0 -467
- package/test/lib/s3ErrorLogReport.test.js +0 -187
- package/test/lib/sharedSMSComposer.test.js +0 -1084
- package/test/lib/util.test.js +0 -329
- package/test/mcp/mcpHandler.test.js +0 -73
- package/test/mcp/mcpHandlerMore.test.js +0 -384
- package/test/mcp/tools/appointmentTools.test.js +0 -362
- package/test/mcp/tools/checkAuthStatus.test.js +0 -83
- package/test/mcp/tools/createCallLog.test.js +0 -436
- package/test/mcp/tools/createContact.test.js +0 -58
- package/test/mcp/tools/createMessageLog.test.js +0 -595
- package/test/mcp/tools/doAuth.test.js +0 -113
- package/test/mcp/tools/findContactByName.test.js +0 -275
- package/test/mcp/tools/findContactByPhone.test.js +0 -296
- package/test/mcp/tools/getCallLog.test.js +0 -298
- package/test/mcp/tools/getGoogleFilePicker.test.js +0 -281
- package/test/mcp/tools/getPublicConnectors.test.js +0 -107
- package/test/mcp/tools/getSessionInfo.test.js +0 -127
- package/test/mcp/tools/logout.test.js +0 -233
- package/test/mcp/tools/rcGetCallLogs.test.js +0 -56
- package/test/mcp/tools/updateCallLog.test.js +0 -360
- package/test/models/accountDataModel.test.js +0 -98
- package/test/models/callDownListModel.test.js +0 -125
- package/test/models/dynamo/connectorSchema.test.js +0 -189
- package/test/models/dynamo/lockSchema.test.js +0 -37
- package/test/models/dynamo/noteCacheSchema.test.js +0 -45
- package/test/models/llmSessionModel.test.js +0 -91
- package/test/models/models.test.js +0 -660
- package/test/routes/calldownRoutes.test.js +0 -224
- package/test/routes/coreRouterBroadRoutes.test.js +0 -855
- package/test/routes/dispositionRoutes.test.js +0 -192
- package/test/routes/managedAuthRoutes.test.js +0 -386
- package/test/routes/pluginRoutes.test.js +0 -262
- package/test/setup.js +0 -178
- /package/{mcp → dist/mcp}/ui/index.html +0 -0
- /package/{mcp → dist/mcp}/ui/package-lock.json +0 -0
- /package/{mcp → dist/mcp}/ui/package.json +0 -0
- /package/{mcp → dist/mcp}/ui/tsconfig.json +0 -0
package/lib/errorHandler.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
const logger = require('./logger');
|
|
2
|
-
const errorMessage = require('./generalErrorMessage');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Centralized error handler for API operations
|
|
6
|
-
* Handles common error patterns (rate limits, auth errors, etc.)
|
|
7
|
-
*
|
|
8
|
-
* @param {Error} error - The error object
|
|
9
|
-
* @param {string} platform - Platform name (clio, bullhorn, etc.)
|
|
10
|
-
* @param {string} operation - Operation name (createCallLog, findContact, etc.)
|
|
11
|
-
* @param {Object} additionalContext - Additional logging context
|
|
12
|
-
* @returns {Object} Standardized error response
|
|
13
|
-
*/
|
|
14
|
-
function handleApiError(error, platform, operation, additionalContext = {}) {
|
|
15
|
-
const statusCode = error.response?.status ?? 'unknown';
|
|
16
|
-
|
|
17
|
-
// Log the error with full context
|
|
18
|
-
logger.error(`${operation} failed for platform ${platform}`, {
|
|
19
|
-
platform,
|
|
20
|
-
operation,
|
|
21
|
-
statusCode,
|
|
22
|
-
errorMessage: error.message,
|
|
23
|
-
errorStack: error.stack,
|
|
24
|
-
errorResponse: error.response?.data,
|
|
25
|
-
...additionalContext,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
// Rate limit error (429)
|
|
29
|
-
if (statusCode === 429) {
|
|
30
|
-
return {
|
|
31
|
-
successful: false,
|
|
32
|
-
returnMessage: errorMessage.rateLimitErrorMessage({ platform }),
|
|
33
|
-
extraDataTracking: {
|
|
34
|
-
statusCode,
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Authorization/Authentication errors (400-409)
|
|
40
|
-
if (statusCode >= 400 && statusCode < 410) {
|
|
41
|
-
return {
|
|
42
|
-
successful: false,
|
|
43
|
-
returnMessage: errorMessage.authorizationErrorMessage({ platform }),
|
|
44
|
-
extraDataTracking: {
|
|
45
|
-
statusCode,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Get operation-specific error message
|
|
51
|
-
const defaultErrorMessage = getOperationErrorMessage(operation, platform);
|
|
52
|
-
|
|
53
|
-
return {
|
|
54
|
-
successful: false,
|
|
55
|
-
returnMessage: defaultErrorMessage,
|
|
56
|
-
extraDataTracking: {
|
|
57
|
-
statusCode,
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Get operation-specific error message
|
|
64
|
-
* @param {string} operation - Operation name
|
|
65
|
-
* @param {string} platform - Platform name
|
|
66
|
-
* @returns {Object} Error message object
|
|
67
|
-
*/
|
|
68
|
-
function getOperationErrorMessage(operation, platform) {
|
|
69
|
-
const operationMessages = {
|
|
70
|
-
createCallLog: {
|
|
71
|
-
message: 'Error creating call log',
|
|
72
|
-
details: ['Please check if your account has permission to CREATE logs.'],
|
|
73
|
-
},
|
|
74
|
-
updateCallLog: {
|
|
75
|
-
message: 'Error updating call log',
|
|
76
|
-
details: [`Please check if the log entity still exists on ${platform} and your account has permission to EDIT logs.`],
|
|
77
|
-
},
|
|
78
|
-
getCallLog: {
|
|
79
|
-
message: 'Error getting call log',
|
|
80
|
-
details: ['Please check if your account has permission to READ logs.'],
|
|
81
|
-
},
|
|
82
|
-
createMessageLog: {
|
|
83
|
-
message: 'Error creating message log',
|
|
84
|
-
details: ['Please check if your account has permission to CREATE logs.'],
|
|
85
|
-
},
|
|
86
|
-
updateMessageLog: {
|
|
87
|
-
message: 'Error updating message log',
|
|
88
|
-
details: [`Please check if the log entity still exists on ${platform} and your account has permission to EDIT logs.`],
|
|
89
|
-
},
|
|
90
|
-
findContact: {
|
|
91
|
-
message: 'Error finding contact',
|
|
92
|
-
details: ['Please check if your account has permission to GET contacts.'],
|
|
93
|
-
},
|
|
94
|
-
createContact: {
|
|
95
|
-
message: 'Error creating contact',
|
|
96
|
-
details: ['Please check if your account has permission to CREATE contacts.'],
|
|
97
|
-
},
|
|
98
|
-
findContactWithName: {
|
|
99
|
-
message: 'Error searching contacts',
|
|
100
|
-
details: ['Please check if your account has permission to GET contacts.'],
|
|
101
|
-
},
|
|
102
|
-
createAppointment: {
|
|
103
|
-
message: 'Error creating appointment',
|
|
104
|
-
details: ['Please check if your account has permission to CREATE appointments. or All attendees have email address.'],
|
|
105
|
-
},
|
|
106
|
-
updateAppointment: {
|
|
107
|
-
message: 'Error updating appointment',
|
|
108
|
-
details: [`Please check if the appointment entity still exists on ${platform} and your account has permission to EDIT appointments. or All attendees have email address.`],
|
|
109
|
-
},
|
|
110
|
-
getAppointment: {
|
|
111
|
-
message: 'Error getting appointment',
|
|
112
|
-
details: ['Please check if your account has permission to GET appointments.'],
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const operationInfo = operationMessages[operation] || {
|
|
117
|
-
message: `Error performing ${operation}`,
|
|
118
|
-
details: ['Please check if your account has the necessary permissions.'],
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
message: operationInfo.message,
|
|
123
|
-
messageType: 'warning',
|
|
124
|
-
details: [
|
|
125
|
-
{
|
|
126
|
-
title: 'Details',
|
|
127
|
-
items: operationInfo.details.map((detail, index) => ({
|
|
128
|
-
id: index + 1,
|
|
129
|
-
type: 'text',
|
|
130
|
-
text: detail,
|
|
131
|
-
})),
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
ttl: 5000,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Handle database errors
|
|
140
|
-
* @param {Error} error - The error object
|
|
141
|
-
* @param {string} operation - Database operation name
|
|
142
|
-
* @param {Object} context - Additional context
|
|
143
|
-
*/
|
|
144
|
-
function handleDatabaseError(error, operation, context = {}) {
|
|
145
|
-
logger.error(`Database operation failed: ${operation}`, {
|
|
146
|
-
operation,
|
|
147
|
-
errorMessage: error.message,
|
|
148
|
-
errorStack: error.stack,
|
|
149
|
-
...context,
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
successful: false,
|
|
154
|
-
returnMessage: {
|
|
155
|
-
message: 'Database operation failed',
|
|
156
|
-
messageType: 'warning',
|
|
157
|
-
ttl: 5000,
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Wrap async route handlers to catch errors
|
|
164
|
-
* Prevents unhandled promise rejections
|
|
165
|
-
* @param {Function} fn - Async route handler
|
|
166
|
-
* @returns {Function} Wrapped handler
|
|
167
|
-
*/
|
|
168
|
-
function asyncHandler(fn) {
|
|
169
|
-
return (req, res, next) => {
|
|
170
|
-
Promise.resolve(fn(req, res, next)).catch(next);
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Express error handling middleware
|
|
176
|
-
* Should be added after all routes
|
|
177
|
-
* @param {Error} err - Error object
|
|
178
|
-
* @param {Object} req - Express request
|
|
179
|
-
* @param {Object} res - Express response
|
|
180
|
-
* @param {Function} next - Express next function (required by Express signature)
|
|
181
|
-
*/
|
|
182
|
-
function errorMiddleware(err, req, res, next) { // eslint-disable-line no-unused-vars
|
|
183
|
-
const platform = req.platform || req.query?.platform || 'unknown';
|
|
184
|
-
const operation = req.route?.path || 'unknown';
|
|
185
|
-
|
|
186
|
-
logger.error('Request failed', {
|
|
187
|
-
platform,
|
|
188
|
-
operation,
|
|
189
|
-
method: req.method,
|
|
190
|
-
path: req.path,
|
|
191
|
-
statusCode: err.statusCode || 500,
|
|
192
|
-
error: err,
|
|
193
|
-
correlationId: req.correlationId,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Don't expose internal errors in production
|
|
197
|
-
const message = process.env.NODE_ENV === 'production'
|
|
198
|
-
? 'An internal error occurred'
|
|
199
|
-
: err.message;
|
|
200
|
-
|
|
201
|
-
res.status(err.statusCode || 500).json({
|
|
202
|
-
successful: false,
|
|
203
|
-
returnMessage: {
|
|
204
|
-
message,
|
|
205
|
-
messageType: 'error',
|
|
206
|
-
ttl: 5000,
|
|
207
|
-
},
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
module.exports = {
|
|
212
|
-
handleApiError,
|
|
213
|
-
handleDatabaseError,
|
|
214
|
-
asyncHandler,
|
|
215
|
-
errorMiddleware,
|
|
216
|
-
getOperationErrorMessage,
|
|
217
|
-
};
|
|
218
|
-
|
package/lib/jwt.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const { sign, verify } = require('jsonwebtoken');
|
|
2
|
-
const logger = require('./logger');
|
|
3
|
-
|
|
4
|
-
function generateJwt(data) {
|
|
5
|
-
return sign(data, process.env.APP_SERVER_SECRET_KEY, { expiresIn: '2w' })
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function decodeJwt(token) {
|
|
9
|
-
try {
|
|
10
|
-
return verify(token, process.env.APP_SERVER_SECRET_KEY);
|
|
11
|
-
} catch (e) {
|
|
12
|
-
logger.error('Error decoding JWT', { stack: e.stack });
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
exports.generateJwt = generateJwt;
|
|
18
|
-
exports.decodeJwt = decodeJwt;
|
package/lib/logger.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
const util = require('util');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Logger levels
|
|
5
|
-
*/
|
|
6
|
-
const LOG_LEVELS = {
|
|
7
|
-
ERROR: 0,
|
|
8
|
-
WARN: 1,
|
|
9
|
-
INFO: 2,
|
|
10
|
-
DEBUG: 3,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Color codes for terminal output
|
|
15
|
-
*/
|
|
16
|
-
const COLORS = {
|
|
17
|
-
ERROR: '\x1b[31m', // Red
|
|
18
|
-
WARN: '\x1b[33m', // Yellow
|
|
19
|
-
INFO: '\x1b[36m', // Cyan
|
|
20
|
-
DEBUG: '\x1b[90m', // Gray
|
|
21
|
-
RESET: '\x1b[0m',
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
class Logger {
|
|
25
|
-
constructor(options = {}) {
|
|
26
|
-
this.level = this._getLogLevel(options.level || process.env.LOG_LEVEL || 'INFO');
|
|
27
|
-
this.isProd = process.env.NODE_ENV === 'production';
|
|
28
|
-
this.enableColors = !this.isProd && process.stdout.isTTY;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
_getLogLevel(levelName) {
|
|
32
|
-
const upperLevel = levelName.toUpperCase();
|
|
33
|
-
return LOG_LEVELS[upperLevel] !== undefined ? LOG_LEVELS[upperLevel] : LOG_LEVELS.INFO;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
_shouldLog(level) {
|
|
37
|
-
return LOG_LEVELS[level] <= this.level;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_formatMessage(level, message, context = {}) {
|
|
41
|
-
const timestamp = new Date().toISOString();
|
|
42
|
-
|
|
43
|
-
if (this.isProd) {
|
|
44
|
-
// Production: JSON format for log aggregation tools
|
|
45
|
-
return JSON.stringify({
|
|
46
|
-
timestamp,
|
|
47
|
-
level,
|
|
48
|
-
message,
|
|
49
|
-
...context,
|
|
50
|
-
});
|
|
51
|
-
} else {
|
|
52
|
-
// Development: Human-readable format with colors
|
|
53
|
-
const color = this.enableColors ? COLORS[level] : '';
|
|
54
|
-
const reset = this.enableColors ? COLORS.RESET : '';
|
|
55
|
-
const contextStr = Object.keys(context).length > 0
|
|
56
|
-
? '\n' + util.inspect(context, { depth: 4, colors: this.enableColors })
|
|
57
|
-
: '';
|
|
58
|
-
|
|
59
|
-
return `${color}[${timestamp}] [${level}]${reset} ${message}${contextStr}`;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_log(level, message, context = {}) {
|
|
64
|
-
if (!this._shouldLog(level)) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const formattedMessage = this._formatMessage(level, message, context);
|
|
69
|
-
|
|
70
|
-
if (level === 'ERROR' || level === 'WARN') {
|
|
71
|
-
console.error(formattedMessage);
|
|
72
|
-
} else {
|
|
73
|
-
console.log(formattedMessage);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Log error level messages
|
|
79
|
-
* @param {string} message - Log message
|
|
80
|
-
* @param {Object} context - Additional context (error, stack, platform, etc.)
|
|
81
|
-
*/
|
|
82
|
-
error(message, context = {}) {
|
|
83
|
-
// If context has an error object, extract useful information
|
|
84
|
-
let enrichedContext = context;
|
|
85
|
-
if (context.error instanceof Error) {
|
|
86
|
-
const { error, ...rest } = context;
|
|
87
|
-
enrichedContext = {
|
|
88
|
-
...rest,
|
|
89
|
-
errorMessage: error.message,
|
|
90
|
-
errorStack: error.stack,
|
|
91
|
-
errorResponse: error.response?.data,
|
|
92
|
-
errorStatus: error.response?.status,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
this._log('ERROR', message, enrichedContext);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Log warning level messages
|
|
101
|
-
* @param {string} message - Log message
|
|
102
|
-
* @param {Object} context - Additional context
|
|
103
|
-
*/
|
|
104
|
-
warn(message, context = {}) {
|
|
105
|
-
this._log('WARN', message, context);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Log info level messages
|
|
110
|
-
* @param {string} message - Log message
|
|
111
|
-
* @param {Object} context - Additional context
|
|
112
|
-
*/
|
|
113
|
-
info(message, context = {}) {
|
|
114
|
-
this._log('INFO', message, context);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Log debug level messages
|
|
119
|
-
* @param {string} message - Log message
|
|
120
|
-
* @param {Object} context - Additional context
|
|
121
|
-
*/
|
|
122
|
-
debug(message, context = {}) {
|
|
123
|
-
this._log('DEBUG', message, context);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Create a child logger with default context
|
|
128
|
-
* Useful for adding request-specific or module-specific context
|
|
129
|
-
* @param {Object} defaultContext - Context to include in all logs
|
|
130
|
-
* @returns {Object} Child logger with bound context
|
|
131
|
-
*/
|
|
132
|
-
child(defaultContext = {}) {
|
|
133
|
-
return {
|
|
134
|
-
error: (message, context = {}) => this.error(message, { ...defaultContext, ...context }),
|
|
135
|
-
warn: (message, context = {}) => this.warn(message, { ...defaultContext, ...context }),
|
|
136
|
-
info: (message, context = {}) => this.info(message, { ...defaultContext, ...context }),
|
|
137
|
-
debug: (message, context = {}) => this.debug(message, { ...defaultContext, ...context }),
|
|
138
|
-
child: (additionalContext) => this.child({ ...defaultContext, ...additionalContext }),
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Log API request/response for debugging
|
|
144
|
-
* @param {Object} options - Request details
|
|
145
|
-
*/
|
|
146
|
-
logApiRequest({ method, url, status, duration, platform, error }) {
|
|
147
|
-
const context = {
|
|
148
|
-
method,
|
|
149
|
-
url,
|
|
150
|
-
status,
|
|
151
|
-
duration: duration ? `${duration}ms` : undefined,
|
|
152
|
-
platform,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
if (error) {
|
|
156
|
-
this.error('API request failed', { ...context, error });
|
|
157
|
-
} else if (status >= 400) {
|
|
158
|
-
this.warn('API request returned error status', context);
|
|
159
|
-
} else {
|
|
160
|
-
this.debug('API request completed', context);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Log database query for debugging
|
|
166
|
-
* @param {Object} options - Query details
|
|
167
|
-
*/
|
|
168
|
-
logDatabaseQuery({ operation, table, duration, error }) {
|
|
169
|
-
const context = {
|
|
170
|
-
operation,
|
|
171
|
-
table,
|
|
172
|
-
duration: duration ? `${duration}ms` : undefined,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
if (error) {
|
|
176
|
-
this.error('Database query failed', { ...context, error });
|
|
177
|
-
} else {
|
|
178
|
-
this.debug('Database query completed', context);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Create singleton instance
|
|
184
|
-
const logger = new Logger();
|
|
185
|
-
|
|
186
|
-
// Export both the class and instance
|
|
187
|
-
module.exports = logger;
|
|
188
|
-
module.exports.Logger = Logger;
|
|
189
|
-
module.exports.LOG_LEVELS = LOG_LEVELS;
|
|
190
|
-
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
const Sequelize = require('sequelize');
|
|
2
|
-
|
|
3
|
-
const CALL_LOGS_TABLE = 'callLogs';
|
|
4
|
-
const HASHED_EXTENSION_ID_COLUMN = 'hashedExtensionId';
|
|
5
|
-
const CALL_LOG_IDENTITY_PK_COLUMNS = ['id', 'sessionId', 'extensionNumber', HASHED_EXTENSION_ID_COLUMN];
|
|
6
|
-
|
|
7
|
-
function findColumnKey(tableDescription, name) {
|
|
8
|
-
const lower = name.toLowerCase();
|
|
9
|
-
return Object.keys(tableDescription).find((k) => k.toLowerCase() === lower);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async function fetchCallLogsCreateSqlSqlite(sequelize, options = {}) {
|
|
13
|
-
const rows = await sequelize.query(
|
|
14
|
-
"SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'callLogs'",
|
|
15
|
-
{ type: Sequelize.QueryTypes.SELECT, ...options },
|
|
16
|
-
);
|
|
17
|
-
return rows[0]?.sql ?? null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function callLogsCreateSqlClaimsPkColumns(createSql, columns) {
|
|
21
|
-
if (!createSql || typeof createSql !== 'string') {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const pkRegex = /PRIMARY\s+KEY\s*\(([^)]+)\)/gi;
|
|
25
|
-
let m;
|
|
26
|
-
while ((m = pkRegex.exec(createSql)) !== null) {
|
|
27
|
-
const pkColumns = m[1]
|
|
28
|
-
.split(',')
|
|
29
|
-
.map((column) => column.replace(/["'`\[\]\s]/g, '').toLowerCase());
|
|
30
|
-
if (columns.every((column) => pkColumns.includes(column.toLowerCase()))) {
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function callLogsCreateSqlClaimsExtensionPk(createSql) {
|
|
38
|
-
return callLogsCreateSqlClaimsPkColumns(createSql, ['extensionNumber']);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function sqliteCallLogsPkIncludesExtension(sequelize, options = {}) {
|
|
42
|
-
const sql = await fetchCallLogsCreateSqlSqlite(sequelize, options);
|
|
43
|
-
return callLogsCreateSqlClaimsExtensionPk(sql);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function sqliteCallLogsPkIncludesHashedExtension(sequelize, options = {}) {
|
|
47
|
-
const sql = await fetchCallLogsCreateSqlSqlite(sequelize, options);
|
|
48
|
-
return callLogsCreateSqlClaimsPkColumns(sql, CALL_LOG_IDENTITY_PK_COLUMNS);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function describeCallLogsTable(sequelize, options = {}) {
|
|
52
|
-
return sequelize.getQueryInterface().describeTable(CALL_LOGS_TABLE, options);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* SQLite cannot change composite PK via Sequelize addConstraint (it appends a second PRIMARY KEY).
|
|
57
|
-
* Rebuild the table with the current call-log identity primary key and copy rows.
|
|
58
|
-
*/
|
|
59
|
-
async function migrateCallLogsIdentitySqlite(sequelize, transaction) {
|
|
60
|
-
const qg = sequelize.getQueryInterface().queryGenerator;
|
|
61
|
-
const qi = sequelize.getQueryInterface();
|
|
62
|
-
const q = (id) => qg.quoteIdentifier(id);
|
|
63
|
-
const tmpName = `callLogs_mig_legacy_${Date.now()}`;
|
|
64
|
-
const mainTableSql = qg.quoteTable({ tableName: CALL_LOGS_TABLE });
|
|
65
|
-
const tmpTableSql = qg.quoteTable({ tableName: tmpName });
|
|
66
|
-
|
|
67
|
-
await sequelize.query(
|
|
68
|
-
`ALTER TABLE ${mainTableSql} RENAME TO ${qg.quoteIdentifier(tmpName)};`,
|
|
69
|
-
{ transaction },
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
await sequelize.query(
|
|
73
|
-
`
|
|
74
|
-
CREATE TABLE ${mainTableSql} (
|
|
75
|
-
${q('id')} VARCHAR(255) NOT NULL,
|
|
76
|
-
${q('sessionId')} VARCHAR(255) NOT NULL,
|
|
77
|
-
${q('extensionNumber')} VARCHAR(255) NOT NULL DEFAULT '',
|
|
78
|
-
${q(HASHED_EXTENSION_ID_COLUMN)} VARCHAR(255) NOT NULL DEFAULT '',
|
|
79
|
-
${q('platform')} VARCHAR(255),
|
|
80
|
-
${q('thirdPartyLogId')} VARCHAR(255),
|
|
81
|
-
${q('userId')} VARCHAR(255),
|
|
82
|
-
${q('contactId')} VARCHAR(255),
|
|
83
|
-
${q('createdAt')} DATETIME NOT NULL,
|
|
84
|
-
${q('updatedAt')} DATETIME NOT NULL,
|
|
85
|
-
PRIMARY KEY (${CALL_LOG_IDENTITY_PK_COLUMNS.map(q).join(', ')})
|
|
86
|
-
);
|
|
87
|
-
`,
|
|
88
|
-
{ transaction },
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const oldDesc = await qi.describeTable(tmpName, { transaction });
|
|
92
|
-
|
|
93
|
-
const targetCols = [
|
|
94
|
-
'id',
|
|
95
|
-
'sessionId',
|
|
96
|
-
'extensionNumber',
|
|
97
|
-
HASHED_EXTENSION_ID_COLUMN,
|
|
98
|
-
'platform',
|
|
99
|
-
'thirdPartyLogId',
|
|
100
|
-
'userId',
|
|
101
|
-
'contactId',
|
|
102
|
-
'createdAt',
|
|
103
|
-
'updatedAt',
|
|
104
|
-
];
|
|
105
|
-
|
|
106
|
-
const missingRequired = targetCols.filter(
|
|
107
|
-
(c) => findColumnKey(oldDesc, c) == null && c !== 'extensionNumber' && c !== HASHED_EXTENSION_ID_COLUMN,
|
|
108
|
-
);
|
|
109
|
-
if (missingRequired.length) {
|
|
110
|
-
throw new Error(
|
|
111
|
-
`unexpected callLogs schema before migration (missing columns: ${missingRequired.join(', ')})`,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const insertCols = targetCols.map(q).join(', ');
|
|
116
|
-
const selectExprs = targetCols
|
|
117
|
-
.map((col) => {
|
|
118
|
-
const key = findColumnKey(oldDesc, col);
|
|
119
|
-
if (key != null) {
|
|
120
|
-
return q(key);
|
|
121
|
-
}
|
|
122
|
-
return `CAST('' AS VARCHAR(255))`;
|
|
123
|
-
})
|
|
124
|
-
.join(', ');
|
|
125
|
-
|
|
126
|
-
await sequelize.query(
|
|
127
|
-
`INSERT INTO ${mainTableSql} (${insertCols}) SELECT ${selectExprs} FROM ${tmpTableSql};`,
|
|
128
|
-
{ transaction },
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
await sequelize.query(`DROP TABLE ${tmpTableSql};`, { transaction });
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function migrateCallLogsExtensionNumberSqlite(sequelize, transaction) {
|
|
135
|
-
return migrateCallLogsIdentitySqlite(sequelize, transaction);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async function getPostgresPrimaryKeyConstraint(sequelize, options = {}) {
|
|
139
|
-
const constraints = await sequelize.query(
|
|
140
|
-
`
|
|
141
|
-
SELECT tc.constraint_name AS "constraintName"
|
|
142
|
-
FROM information_schema.table_constraints tc
|
|
143
|
-
WHERE tc.table_name = :tableName
|
|
144
|
-
AND tc.constraint_type = 'PRIMARY KEY'
|
|
145
|
-
LIMIT 1
|
|
146
|
-
`,
|
|
147
|
-
{
|
|
148
|
-
type: Sequelize.QueryTypes.SELECT,
|
|
149
|
-
replacements: { tableName: CALL_LOGS_TABLE },
|
|
150
|
-
...options,
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
return constraints[0]?.constraintName ?? null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async function postgresCallLogsPkIncludesHashedExtension(sequelize, options = {}) {
|
|
157
|
-
const pkConstraintName = await getPostgresPrimaryKeyConstraint(sequelize, options);
|
|
158
|
-
if (!pkConstraintName) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
const rows = await sequelize.query(
|
|
162
|
-
`
|
|
163
|
-
SELECT kcu.column_name AS "columnName"
|
|
164
|
-
FROM information_schema.key_column_usage kcu
|
|
165
|
-
WHERE kcu.table_name = :tableName
|
|
166
|
-
AND kcu.constraint_name = :constraintName
|
|
167
|
-
ORDER BY kcu.ordinal_position
|
|
168
|
-
`,
|
|
169
|
-
{
|
|
170
|
-
type: Sequelize.QueryTypes.SELECT,
|
|
171
|
-
replacements: { tableName: CALL_LOGS_TABLE, constraintName: pkConstraintName },
|
|
172
|
-
...options,
|
|
173
|
-
},
|
|
174
|
-
);
|
|
175
|
-
const pkColumns = rows.map((row) => row.columnName.toLowerCase());
|
|
176
|
-
return CALL_LOG_IDENTITY_PK_COLUMNS.every((column) => pkColumns.includes(column.toLowerCase()));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function migrateCallLogsIdentityPostgres(sequelize, transaction) {
|
|
180
|
-
const qi = sequelize.getQueryInterface();
|
|
181
|
-
const qg = qi.queryGenerator;
|
|
182
|
-
const table = qg.quoteTable({ tableName: CALL_LOGS_TABLE });
|
|
183
|
-
const pkConstraintName = await getPostgresPrimaryKeyConstraint(sequelize, { transaction });
|
|
184
|
-
if (pkConstraintName) {
|
|
185
|
-
await sequelize.query(
|
|
186
|
-
`ALTER TABLE ${table} DROP CONSTRAINT ${qg.quoteIdentifier(pkConstraintName)};`,
|
|
187
|
-
{ transaction },
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
await sequelize.query(
|
|
191
|
-
`ALTER TABLE ${table} ADD PRIMARY KEY (${CALL_LOG_IDENTITY_PK_COLUMNS.map((column) => qg.quoteIdentifier(column)).join(', ')});`,
|
|
192
|
-
{ transaction },
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async function ensureCallLogsHashedExtensionIdSchema(sequelize) {
|
|
197
|
-
const qi = sequelize.getQueryInterface();
|
|
198
|
-
const dialect = sequelize.getDialect();
|
|
199
|
-
let desc = await describeCallLogsTable(sequelize);
|
|
200
|
-
|
|
201
|
-
if (findColumnKey(desc, HASHED_EXTENSION_ID_COLUMN) == null) {
|
|
202
|
-
await qi.addColumn(CALL_LOGS_TABLE, HASHED_EXTENSION_ID_COLUMN, {
|
|
203
|
-
type: Sequelize.STRING,
|
|
204
|
-
allowNull: false,
|
|
205
|
-
defaultValue: '',
|
|
206
|
-
});
|
|
207
|
-
desc = await describeCallLogsTable(sequelize);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (dialect === 'sqlite') {
|
|
211
|
-
const hasIdentityPk = await sqliteCallLogsPkIncludesHashedExtension(sequelize);
|
|
212
|
-
if (!hasIdentityPk) {
|
|
213
|
-
await sequelize.transaction(async (transaction) => {
|
|
214
|
-
await migrateCallLogsIdentitySqlite(sequelize, transaction);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (dialect === 'postgres') {
|
|
221
|
-
const hasIdentityPk = await postgresCallLogsPkIncludesHashedExtension(sequelize);
|
|
222
|
-
if (!hasIdentityPk) {
|
|
223
|
-
await sequelize.transaction(async (transaction) => {
|
|
224
|
-
await migrateCallLogsIdentityPostgres(sequelize, transaction);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
module.exports = {
|
|
231
|
-
findColumnKey,
|
|
232
|
-
migrateCallLogsExtensionNumberSqlite,
|
|
233
|
-
migrateCallLogsIdentitySqlite,
|
|
234
|
-
sqliteCallLogsPkIncludesExtension,
|
|
235
|
-
sqliteCallLogsPkIncludesHashedExtension,
|
|
236
|
-
ensureCallLogsHashedExtensionIdSchema,
|
|
237
|
-
};
|