@friggframework/core 2.0.0--canary.427.c8ff14b.0 → 2.0.0--canary.427.04558b7.0
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/database/mongo.js +131 -5
- package/handlers/routers/health.js +205 -86
- package/package.json +5 -5
package/database/mongo.js
CHANGED
|
@@ -5,14 +5,16 @@
|
|
|
5
5
|
const { Encrypt } = require('../encrypt');
|
|
6
6
|
const { mongoose } = require('./mongoose');
|
|
7
7
|
const { debug, flushDebugLog } = require('../logs');
|
|
8
|
+
const { findNearestBackendPackageJson } = require('../utils');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const fs = require('fs');
|
|
8
11
|
|
|
9
12
|
mongoose.plugin(Encrypt);
|
|
10
13
|
mongoose.set('applyPluginsToDiscriminators', true); // Needed for LHEncrypt
|
|
11
14
|
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const mongoConfig = {
|
|
15
|
+
// Load app definition to check for DocumentDB configuration
|
|
16
|
+
let appDefinition = {};
|
|
17
|
+
let mongoConfig = {
|
|
16
18
|
useNewUrlParser: true,
|
|
17
19
|
bufferCommands: false, // Disable mongoose buffering
|
|
18
20
|
autoCreate: false, // Disable because auto creation does not work without buffering
|
|
@@ -28,9 +30,133 @@ const connectToDatabase = async () => {
|
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
console.log('🔗 Connecting to database...');
|
|
34
|
+
|
|
35
|
+
// Load appDefinition inside the function
|
|
36
|
+
try {
|
|
37
|
+
console.log(
|
|
38
|
+
'🔍 Loading app definition for DocumentDB configuration...'
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const backendPath = findNearestBackendPackageJson();
|
|
42
|
+
if (!backendPath) {
|
|
43
|
+
throw new Error('Could not find backend package.json');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const backendDir = path.dirname(backendPath);
|
|
47
|
+
const backendFilePath = path.join(backendDir, 'index.js');
|
|
48
|
+
if (!fs.existsSync(backendFilePath)) {
|
|
49
|
+
throw new Error('Could not find index.js');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const backend = require(backendFilePath);
|
|
53
|
+
appDefinition = backend.Definition;
|
|
54
|
+
|
|
55
|
+
console.log('📁 AppDefinition content:', JSON.stringify(appDefinition));
|
|
56
|
+
|
|
57
|
+
// Add DocumentDB TLS configuration if enabled
|
|
58
|
+
if (appDefinition.database?.documentDB?.enable === true) {
|
|
59
|
+
console.log('📄 DocumentDB configuration detected, enabling TLS');
|
|
60
|
+
console.log('📁 Current working directory:', process.cwd());
|
|
61
|
+
console.log(
|
|
62
|
+
'📋 App definition database config:',
|
|
63
|
+
JSON.stringify(appDefinition.database, null, 2)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
mongoConfig.tls = true;
|
|
67
|
+
|
|
68
|
+
// Set TLS CA file path if specified
|
|
69
|
+
if (appDefinition.database.documentDB.tlsCAFile) {
|
|
70
|
+
const tlsCAFile = appDefinition.database.documentDB.tlsCAFile;
|
|
71
|
+
|
|
72
|
+
// Basic safety: reject obviously dangerous paths
|
|
73
|
+
if (tlsCAFile.includes('..') || path.isAbsolute(tlsCAFile)) {
|
|
74
|
+
console.warn(
|
|
75
|
+
'⚠️ Rejecting potentially unsafe tlsCAFile path:',
|
|
76
|
+
tlsCAFile
|
|
77
|
+
);
|
|
78
|
+
} else {
|
|
79
|
+
const tlsCAFilePath = path.resolve(
|
|
80
|
+
process.cwd(),
|
|
81
|
+
tlsCAFile
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
console.log('📄 DocumentDB TLS CA file configured:');
|
|
85
|
+
console.log(' 📎 Original path:', tlsCAFile);
|
|
86
|
+
console.log(' 📎 Resolved path:', tlsCAFilePath);
|
|
87
|
+
console.log(
|
|
88
|
+
' 📄 File exists:',
|
|
89
|
+
fs.existsSync(tlsCAFilePath)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Only set tlsCAFile if the file actually exists
|
|
93
|
+
if (fs.existsSync(tlsCAFilePath)) {
|
|
94
|
+
mongoConfig.tlsCAFile = tlsCAFilePath;
|
|
95
|
+
console.log('✅ TLS CA file configured successfully');
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`TLS CA file not found at ${tlsCAFilePath}`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Debug directory listing (only in development)
|
|
103
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
104
|
+
try {
|
|
105
|
+
console.log('📁 Current directory contents:');
|
|
106
|
+
fs.readdirSync(process.cwd()).forEach((item) => {
|
|
107
|
+
const stats = fs.statSync(
|
|
108
|
+
path.join(process.cwd(), item)
|
|
109
|
+
);
|
|
110
|
+
console.log(
|
|
111
|
+
` ${
|
|
112
|
+
stats.isDirectory() ? '📁' : '📄'
|
|
113
|
+
} ${item}`
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const securityDir = path.join(
|
|
118
|
+
process.cwd(),
|
|
119
|
+
'security'
|
|
120
|
+
);
|
|
121
|
+
if (fs.existsSync(securityDir)) {
|
|
122
|
+
console.log('📁 Security directory contents:');
|
|
123
|
+
fs.readdirSync(securityDir).forEach((item) => {
|
|
124
|
+
console.log(` 📄 ${item}`);
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
console.log(
|
|
128
|
+
'❌ Security directory does not exist at:',
|
|
129
|
+
securityDir
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.log(
|
|
134
|
+
'❌ Error listing directory contents:',
|
|
135
|
+
error.message
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
console.log(
|
|
143
|
+
'📄 DocumentDB not enabled, using standard MongoDB configuration'
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error('❌ Error loading app definition:', error.message);
|
|
148
|
+
debug(
|
|
149
|
+
'Could not load app definition for DocumentDB configuration:',
|
|
150
|
+
error.message
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log('🔗 MongoDB URI:', process.env.MONGO_URI ? 'SET' : 'NOT SET');
|
|
155
|
+
console.log('🔧 Final mongoConfig:', JSON.stringify(mongoConfig, null, 2));
|
|
156
|
+
|
|
31
157
|
debug('=> using new database connection');
|
|
32
158
|
await mongoose.connect(process.env.MONGO_URI, mongoConfig);
|
|
33
|
-
debug('Connection state:',
|
|
159
|
+
debug('Connection state:', mongoose.STATES[mongoose.connection.readyState]);
|
|
34
160
|
mongoose.connection.on('error', (error) => flushDebugLog(error));
|
|
35
161
|
};
|
|
36
162
|
|
|
@@ -15,6 +15,7 @@ const validateApiKey = (req, res, next) => {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (!apiKey || apiKey !== process.env.HEALTH_API_KEY) {
|
|
18
|
+
console.error('Unauthorized access attempt to health endpoint');
|
|
18
19
|
return res.status(401).json({
|
|
19
20
|
status: 'error',
|
|
20
21
|
message: 'Unauthorized',
|
|
@@ -149,69 +150,6 @@ const createTestEncryptionModel = () => {
|
|
|
149
150
|
);
|
|
150
151
|
};
|
|
151
152
|
|
|
152
|
-
const createTestDocument = async (TestModel) => {
|
|
153
|
-
const testData = {
|
|
154
|
-
testSecret: 'This is a secret value that should be encrypted',
|
|
155
|
-
normalField: 'This is a normal field that should not be encrypted',
|
|
156
|
-
nestedSecret: {
|
|
157
|
-
value: 'This is a nested secret that should be encrypted',
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
console.log('🔧 Creating test document with encryption...');
|
|
162
|
-
const testDoc = new TestModel(testData);
|
|
163
|
-
|
|
164
|
-
// Add timeout and detailed error logging
|
|
165
|
-
const savePromise = testDoc.save();
|
|
166
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
167
|
-
setTimeout(
|
|
168
|
-
() =>
|
|
169
|
-
reject(new Error('Save operation timed out after 30 seconds')),
|
|
170
|
-
30000
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
console.log('💾 Attempting to save document...');
|
|
176
|
-
const startTime = Date.now();
|
|
177
|
-
|
|
178
|
-
await Promise.race([savePromise, timeoutPromise]);
|
|
179
|
-
|
|
180
|
-
const duration = Date.now() - startTime;
|
|
181
|
-
console.log(`✅ Document saved successfully in ${duration}ms`);
|
|
182
|
-
|
|
183
|
-
return { testDoc, testData };
|
|
184
|
-
} catch (error) {
|
|
185
|
-
console.error('❌ Save operation failed:', {
|
|
186
|
-
errorName: error.name,
|
|
187
|
-
errorMessage: error.message,
|
|
188
|
-
errorStack: error.stack,
|
|
189
|
-
mongooseConnectionState: testDoc.db.readyState,
|
|
190
|
-
modelName: TestModel.modelName,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
// Try to get more details about the connection
|
|
194
|
-
if (mongoose.connection && mongoose.connection.db) {
|
|
195
|
-
try {
|
|
196
|
-
const admin = mongoose.connection.db.admin();
|
|
197
|
-
const serverStatus = await admin.serverStatus();
|
|
198
|
-
console.log('📊 DocumentDB Server Status:', {
|
|
199
|
-
version: serverStatus.version,
|
|
200
|
-
uptime: serverStatus.uptime,
|
|
201
|
-
connections: serverStatus.connections,
|
|
202
|
-
});
|
|
203
|
-
} catch (statusError) {
|
|
204
|
-
console.error(
|
|
205
|
-
'❌ Could not get server status:',
|
|
206
|
-
statusError.message
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
throw error;
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
|
|
215
153
|
const verifyDecryption = (retrievedDoc, originalData) => {
|
|
216
154
|
return (
|
|
217
155
|
retrievedDoc &&
|
|
@@ -285,18 +223,95 @@ const evaluateEncryptionTestResults = (decryptionWorks, encryptionResults) => {
|
|
|
285
223
|
};
|
|
286
224
|
};
|
|
287
225
|
|
|
226
|
+
const withTimeout = (promise, ms, errorMessage) => {
|
|
227
|
+
return Promise.race([
|
|
228
|
+
promise,
|
|
229
|
+
new Promise((_, reject) =>
|
|
230
|
+
setTimeout(() => reject(new Error(errorMessage)), ms)
|
|
231
|
+
),
|
|
232
|
+
]);
|
|
233
|
+
};
|
|
234
|
+
|
|
288
235
|
const testEncryption = async () => {
|
|
236
|
+
// eslint-disable-next-line no-console
|
|
237
|
+
console.log('Starting encryption test');
|
|
289
238
|
const TestModel = createTestEncryptionModel();
|
|
290
|
-
|
|
239
|
+
// eslint-disable-next-line no-console
|
|
240
|
+
console.log('Test model created');
|
|
241
|
+
|
|
242
|
+
const testData = {
|
|
243
|
+
testSecret: 'This is a secret value that should be encrypted',
|
|
244
|
+
normalField: 'This is a normal field that should not be encrypted',
|
|
245
|
+
nestedSecret: {
|
|
246
|
+
value: 'This is a nested secret that should be encrypted',
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const testDoc = new TestModel(testData);
|
|
291
251
|
|
|
292
252
|
try {
|
|
293
|
-
|
|
253
|
+
// eslint-disable-next-line no-console
|
|
254
|
+
console.log('Attempting to save document with encryption...');
|
|
255
|
+
const startTime = Date.now();
|
|
256
|
+
|
|
257
|
+
await withTimeout(
|
|
258
|
+
testDoc.save(),
|
|
259
|
+
30000,
|
|
260
|
+
'Save operation timed out after 30 seconds'
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const duration = Date.now() - startTime;
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
265
|
+
console.log(`Test document saved successfully in ${duration}ms`);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// eslint-disable-next-line no-console
|
|
268
|
+
console.error('Save operation failed:', {
|
|
269
|
+
errorName: error.name,
|
|
270
|
+
errorMessage: error.message,
|
|
271
|
+
errorStack: error.stack,
|
|
272
|
+
mongooseConnectionState: testDoc.db.readyState,
|
|
273
|
+
modelName: TestModel.modelName,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Try to get more details about the connection
|
|
277
|
+
if (mongoose.connection && mongoose.connection.db) {
|
|
278
|
+
try {
|
|
279
|
+
const admin = mongoose.connection.db.admin();
|
|
280
|
+
const serverStatus = await admin.serverStatus();
|
|
281
|
+
// eslint-disable-next-line no-console
|
|
282
|
+
console.log('DocumentDB Server Status:', {
|
|
283
|
+
version: serverStatus.version,
|
|
284
|
+
uptime: serverStatus.uptime,
|
|
285
|
+
connections: serverStatus.connections,
|
|
286
|
+
});
|
|
287
|
+
} catch (statusError) {
|
|
288
|
+
// eslint-disable-next-line no-console
|
|
289
|
+
console.error(
|
|
290
|
+
'Could not get server status:',
|
|
291
|
+
statusError.message
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
const retrievedDoc = await withTimeout(
|
|
301
|
+
TestModel.findById(testDoc._id),
|
|
302
|
+
5000,
|
|
303
|
+
'Find operation timed out'
|
|
304
|
+
);
|
|
305
|
+
// eslint-disable-next-line no-console
|
|
306
|
+
console.log('Test document retrieved');
|
|
294
307
|
const decryptionWorks = verifyDecryption(retrievedDoc, testData);
|
|
295
|
-
const encryptionResults = await
|
|
296
|
-
testDoc,
|
|
297
|
-
|
|
298
|
-
|
|
308
|
+
const encryptionResults = await withTimeout(
|
|
309
|
+
verifyEncryptionInDatabase(testDoc, testData, TestModel),
|
|
310
|
+
5000,
|
|
311
|
+
'Database verification timed out'
|
|
299
312
|
);
|
|
313
|
+
// eslint-disable-next-line no-console
|
|
314
|
+
console.log('Encryption verification completed');
|
|
300
315
|
|
|
301
316
|
const evaluation = evaluateEncryptionTestResults(
|
|
302
317
|
decryptionWorks,
|
|
@@ -308,7 +323,13 @@ const testEncryption = async () => {
|
|
|
308
323
|
encryptionWorks: decryptionWorks,
|
|
309
324
|
};
|
|
310
325
|
} finally {
|
|
311
|
-
await
|
|
326
|
+
await withTimeout(
|
|
327
|
+
TestModel.deleteOne({ _id: testDoc._id }),
|
|
328
|
+
5000,
|
|
329
|
+
'Delete operation timed out'
|
|
330
|
+
);
|
|
331
|
+
// eslint-disable-next-line no-console
|
|
332
|
+
console.log('Test document deleted');
|
|
312
333
|
}
|
|
313
334
|
};
|
|
314
335
|
|
|
@@ -316,6 +337,12 @@ const checkEncryptionHealth = async () => {
|
|
|
316
337
|
const config = getEncryptionConfiguration();
|
|
317
338
|
|
|
318
339
|
if (config.isBypassed || config.mode === 'none') {
|
|
340
|
+
// eslint-disable-next-line no-console
|
|
341
|
+
console.log('Encryption check bypassed:', {
|
|
342
|
+
stage: config.stage,
|
|
343
|
+
mode: config.mode,
|
|
344
|
+
});
|
|
345
|
+
|
|
319
346
|
const testResult = config.isBypassed
|
|
320
347
|
? 'Encryption bypassed for this stage'
|
|
321
348
|
: 'No encryption keys configured';
|
|
@@ -434,50 +461,134 @@ router.get('/health', async (_req, res) => {
|
|
|
434
461
|
});
|
|
435
462
|
|
|
436
463
|
router.get('/health/detailed', async (_req, res) => {
|
|
464
|
+
// eslint-disable-next-line no-console
|
|
465
|
+
console.log('Starting detailed health check');
|
|
437
466
|
const startTime = Date.now();
|
|
438
467
|
const response = buildHealthCheckResponse(startTime);
|
|
439
468
|
|
|
440
|
-
|
|
441
|
-
|
|
469
|
+
// Run all async health checks concurrently
|
|
470
|
+
const [
|
|
471
|
+
databaseResult,
|
|
472
|
+
encryptionResult,
|
|
473
|
+
externalApisResult,
|
|
474
|
+
integrationsResult,
|
|
475
|
+
] = await Promise.allSettled([
|
|
476
|
+
checkDatabaseHealth().catch((error) => ({
|
|
477
|
+
status: 'unhealthy',
|
|
478
|
+
error: error.message,
|
|
479
|
+
})),
|
|
480
|
+
checkEncryptionHealth().catch((error) => ({
|
|
481
|
+
status: 'unhealthy',
|
|
482
|
+
error: error.message,
|
|
483
|
+
})),
|
|
484
|
+
checkExternalAPIs(),
|
|
485
|
+
Promise.resolve().then(() => {
|
|
486
|
+
try {
|
|
487
|
+
return checkIntegrations();
|
|
488
|
+
} catch (error) {
|
|
489
|
+
return {
|
|
490
|
+
status: 'unhealthy',
|
|
491
|
+
error: error.message,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
}),
|
|
495
|
+
]);
|
|
496
|
+
|
|
497
|
+
// Process database check results
|
|
498
|
+
if (databaseResult.status === 'fulfilled') {
|
|
499
|
+
response.checks.database = databaseResult.value;
|
|
442
500
|
const dbState = getDatabaseState();
|
|
443
|
-
if (
|
|
501
|
+
if (
|
|
502
|
+
!dbState.isConnected ||
|
|
503
|
+
response.checks.database.status === 'unhealthy'
|
|
504
|
+
) {
|
|
444
505
|
response.status = 'unhealthy';
|
|
445
506
|
}
|
|
446
|
-
|
|
507
|
+
// eslint-disable-next-line no-console
|
|
508
|
+
console.log('Database check completed:', response.checks.database);
|
|
509
|
+
} else {
|
|
447
510
|
response.checks.database = {
|
|
448
511
|
status: 'unhealthy',
|
|
449
|
-
error:
|
|
512
|
+
error: databaseResult.reason?.message || 'Database check failed',
|
|
450
513
|
};
|
|
451
514
|
response.status = 'unhealthy';
|
|
515
|
+
// eslint-disable-next-line no-console
|
|
516
|
+
console.log('Database check error:', databaseResult.reason?.message);
|
|
452
517
|
}
|
|
453
518
|
|
|
454
|
-
|
|
455
|
-
|
|
519
|
+
// Process encryption check results
|
|
520
|
+
if (encryptionResult.status === 'fulfilled') {
|
|
521
|
+
response.checks.encryption = encryptionResult.value;
|
|
456
522
|
if (response.checks.encryption.status === 'unhealthy') {
|
|
457
523
|
response.status = 'unhealthy';
|
|
458
524
|
}
|
|
459
|
-
|
|
525
|
+
// eslint-disable-next-line no-console
|
|
526
|
+
console.log('Encryption check completed:', response.checks.encryption);
|
|
527
|
+
} else {
|
|
460
528
|
response.checks.encryption = {
|
|
461
529
|
status: 'unhealthy',
|
|
462
|
-
error:
|
|
530
|
+
error:
|
|
531
|
+
encryptionResult.reason?.message || 'Encryption check failed',
|
|
463
532
|
};
|
|
464
533
|
response.status = 'unhealthy';
|
|
534
|
+
// eslint-disable-next-line no-console
|
|
535
|
+
console.log(
|
|
536
|
+
'Encryption check error:',
|
|
537
|
+
encryptionResult.reason?.message
|
|
538
|
+
);
|
|
465
539
|
}
|
|
466
540
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
541
|
+
// Process external APIs check results
|
|
542
|
+
if (externalApisResult.status === 'fulfilled') {
|
|
543
|
+
const { apiStatuses, allReachable } = externalApisResult.value;
|
|
544
|
+
response.checks.externalApis = apiStatuses;
|
|
545
|
+
if (!allReachable) {
|
|
546
|
+
response.status = 'unhealthy';
|
|
547
|
+
}
|
|
548
|
+
// eslint-disable-next-line no-console
|
|
549
|
+
console.log(
|
|
550
|
+
'External APIs check completed:',
|
|
551
|
+
response.checks.externalApis
|
|
552
|
+
);
|
|
553
|
+
} else {
|
|
554
|
+
response.checks.externalApis = {
|
|
555
|
+
status: 'unhealthy',
|
|
556
|
+
error:
|
|
557
|
+
externalApisResult.reason?.message ||
|
|
558
|
+
'External APIs check failed',
|
|
559
|
+
};
|
|
470
560
|
response.status = 'unhealthy';
|
|
561
|
+
// eslint-disable-next-line no-console
|
|
562
|
+
console.log(
|
|
563
|
+
'External APIs check error:',
|
|
564
|
+
externalApisResult.reason?.message
|
|
565
|
+
);
|
|
471
566
|
}
|
|
472
567
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
568
|
+
// Process integrations check results
|
|
569
|
+
if (integrationsResult.status === 'fulfilled') {
|
|
570
|
+
response.checks.integrations = integrationsResult.value;
|
|
571
|
+
if (response.checks.integrations.status === 'unhealthy') {
|
|
572
|
+
response.status = 'unhealthy';
|
|
573
|
+
}
|
|
574
|
+
// eslint-disable-next-line no-console
|
|
575
|
+
console.log(
|
|
576
|
+
'Integrations check completed:',
|
|
577
|
+
response.checks.integrations
|
|
578
|
+
);
|
|
579
|
+
} else {
|
|
476
580
|
response.checks.integrations = {
|
|
477
581
|
status: 'unhealthy',
|
|
478
|
-
error:
|
|
582
|
+
error:
|
|
583
|
+
integrationsResult.reason?.message ||
|
|
584
|
+
'Integrations check failed',
|
|
479
585
|
};
|
|
480
586
|
response.status = 'unhealthy';
|
|
587
|
+
// eslint-disable-next-line no-console
|
|
588
|
+
console.log(
|
|
589
|
+
'Integrations check error:',
|
|
590
|
+
integrationsResult.reason?.message
|
|
591
|
+
);
|
|
481
592
|
}
|
|
482
593
|
|
|
483
594
|
response.responseTime = response.calculateResponseTime();
|
|
@@ -485,6 +596,14 @@ router.get('/health/detailed', async (_req, res) => {
|
|
|
485
596
|
|
|
486
597
|
const statusCode = response.status === 'healthy' ? 200 : 503;
|
|
487
598
|
res.status(statusCode).json(response);
|
|
599
|
+
|
|
600
|
+
// eslint-disable-next-line no-console
|
|
601
|
+
console.log(
|
|
602
|
+
'Final health status:',
|
|
603
|
+
response.status,
|
|
604
|
+
'Response time:',
|
|
605
|
+
response.responseTime
|
|
606
|
+
);
|
|
488
607
|
});
|
|
489
608
|
|
|
490
609
|
router.get('/health/live', (_req, res) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/core",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.427.
|
|
4
|
+
"version": "2.0.0--canary.427.04558b7.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@hapi/boom": "^10.0.1",
|
|
7
7
|
"aws-sdk": "^2.1200.0",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"uuid": "^9.0.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@friggframework/eslint-config": "2.0.0--canary.427.
|
|
26
|
-
"@friggframework/prettier-config": "2.0.0--canary.427.
|
|
27
|
-
"@friggframework/test": "2.0.0--canary.427.
|
|
25
|
+
"@friggframework/eslint-config": "2.0.0--canary.427.04558b7.0",
|
|
26
|
+
"@friggframework/prettier-config": "2.0.0--canary.427.04558b7.0",
|
|
27
|
+
"@friggframework/test": "2.0.0--canary.427.04558b7.0",
|
|
28
28
|
"@types/lodash": "4.17.15",
|
|
29
29
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
30
30
|
"chai": "^4.3.6",
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"publishConfig": {
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "04558b7a08b166c687327d9635bf872ca33f8b94"
|
|
60
60
|
}
|