-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-database-config.cjs
More file actions
259 lines (219 loc) · 9.89 KB
/
test-database-config.cjs
File metadata and controls
259 lines (219 loc) · 9.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#!/usr/bin/env node
/**
* Azure PostgreSQL Database Configuration Test
*/
require('dotenv').config();
async function testDatabaseConfig() {
console.log('🗄️ Testing Azure PostgreSQL Configuration\n');
console.log('=' .repeat(60));
// Test 1: Configuration Check
console.log('📋 Configuration Check:');
console.log('-'.repeat(30));
const requiredVars = [
'DB_HOST',
'DB_PORT',
'DB_NAME',
'DB_USER',
'DB_PASSWORD'
];
const config = {};
let configComplete = true;
requiredVars.forEach(varName => {
const value = process.env[varName];
if (!value || value.includes('your_') || value.includes('_here')) {
console.log(`❌ ${varName}: NOT CONFIGURED`);
configComplete = false;
} else {
config[varName] = value;
if (varName === 'DB_PASSWORD') {
console.log(`✅ ${varName}: ${'*'.repeat(8)}${value.slice(-4)}`);
} else {
console.log(`✅ ${varName}: ${value}`);
}
}
});
if (!configComplete) {
console.log('\n❌ Please complete database configuration:');
console.log('1. Create PostgreSQL server in Azure Portal');
console.log('2. Update azure-database-config.env with actual values');
console.log('3. Copy configuration to .env file');
return false;
}
// Test 2: Connection String Validation
console.log('\n🔗 Connection String Validation:');
console.log('-'.repeat(30));
const connectionString = process.env.DATABASE_URL;
if (connectionString && !connectionString.includes('your_database_password_here')) {
console.log('✅ DATABASE_URL: CONFIGURED');
console.log(` Host: ${config.DB_HOST}`);
console.log(` Database: ${config.DB_NAME}`);
console.log(` SSL Mode: ${connectionString.includes('sslmode=require') ? 'Required' : 'Optional'}`);
} else {
console.log('⚠️ DATABASE_URL: Not configured or contains placeholder');
}
// Test 3: Pool Configuration
console.log('\n🏊 Connection Pool Settings:');
console.log('-'.repeat(30));
console.log(`Min Connections: ${process.env.DB_POOL_MIN || '2'}`);
console.log(`Max Connections: ${process.env.DB_POOL_MAX || '10'}`);
console.log(`Idle Timeout: ${process.env.DB_POOL_IDLE_TIMEOUT || '30000'}ms`);
console.log(`Connection Timeout: ${process.env.DB_CONNECTION_TIMEOUT || '5000'}ms`);
// Test 4: Performance Settings
console.log('\n⚡ Performance Settings:');
console.log('-'.repeat(30));
console.log(`Query Timeout: ${process.env.DB_QUERY_TIMEOUT || '30000'}ms`);
console.log(`Statement Timeout: ${process.env.DB_STATEMENT_TIMEOUT || '60000'}ms`);
console.log(`Max Retries: ${process.env.DB_MAX_RETRIES || '3'}`);
console.log(`SSL Enabled: ${process.env.DB_SSL || 'true'}`);
// Test 5: Database Connection Test
console.log('\n🔍 Database Connection Test:');
console.log('-'.repeat(30));
try {
// Try to load pg module
const { Client } = require('pg');
console.log('✅ PostgreSQL client loaded successfully');
// Create client configuration
const clientConfig = {
host: config.DB_HOST,
port: parseInt(config.DB_PORT),
database: config.DB_NAME,
user: config.DB_USER,
password: config.DB_PASSWORD,
ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false,
connectionTimeoutMillis: parseInt(process.env.DB_CONNECTION_TIMEOUT || '5000'),
query_timeout: parseInt(process.env.DB_QUERY_TIMEOUT || '30000')
};
const client = new Client(clientConfig);
console.log('🔄 Attempting database connection...');
// Set connection timeout
const connectionPromise = client.connect();
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Connection timeout')), 10000)
);
await Promise.race([connectionPromise, timeoutPromise]);
console.log('✅ Database connection established');
// Test basic queries
console.log('\n📊 Database Information:');
// Get PostgreSQL version
const versionResult = await client.query('SELECT version()');
const version = versionResult.rows[0].version;
console.log(` PostgreSQL Version: ${version.split(' ')[0]} ${version.split(' ')[1]}`);
// Get server time
const timeResult = await client.query('SELECT now() as server_time');
console.log(` Server Time: ${timeResult.rows[0].server_time}`);
// Check database size
const sizeResult = await client.query(`
SELECT pg_size_pretty(pg_database_size('${config.DB_NAME}')) as size
`);
console.log(` Database Size: ${sizeResult.rows[0].size}`);
// Test write permissions
try {
await client.query('CREATE TEMP TABLE test_permissions (id SERIAL PRIMARY KEY)');
await client.query('DROP TABLE test_permissions');
console.log('✅ Write permissions verified');
} catch (permError) {
console.log('⚠️ Write permissions test failed:', permError.message);
}
// Get connection stats
const statsResult = await client.query(`
SELECT count(*) as active_connections
FROM pg_stat_activity
WHERE datname = '${config.DB_NAME}' AND state = 'active'
`);
console.log(` Active Connections: ${statsResult.rows[0].active_connections}`);
await client.end();
console.log('✅ Database connection closed cleanly');
} catch (error) {
if (error.code === 'MODULE_NOT_FOUND') {
console.log('⚠️ PostgreSQL client not installed');
console.log(' Run: npm install pg');
console.log(' Configuration appears valid (connection test skipped)');
} else if (error.code === 'ENOTFOUND') {
console.log('❌ Database server not found');
console.log(' Check server name and network connectivity');
return false;
} else if (error.code === 'ECONNREFUSED') {
console.log('❌ Connection refused');
console.log(' Check firewall rules and server status');
return false;
} else if (error.message === 'Connection timeout') {
console.log('❌ Connection timeout');
console.log(' Check network connectivity and firewall rules');
return false;
} else if (error.code === '28P01') {
console.log('❌ Authentication failed');
console.log(' Check username and password');
return false;
} else if (error.code === '3D000') {
console.log('❌ Database does not exist');
console.log(' Create the database first');
return false;
} else {
console.log('❌ Connection test failed:', error.message);
console.log(` Error Code: ${error.code}`);
return false;
}
}
// Test 6: Migration Readiness Check
console.log('\n🗂️ Migration Readiness:');
console.log('-'.repeat(30));
const migrationFiles = [
'migrations/001-create-users-table.sql',
'migrations/002-create-optimized-tables.sql'
];
migrationFiles.forEach(file => {
try {
const fs = require('fs');
if (fs.existsSync(file)) {
console.log(`✅ Migration found: ${file}`);
} else {
console.log(`⚠️ Migration missing: ${file}`);
}
} catch (err) {
console.log(`⚠️ Cannot check migration: ${file}`);
}
});
// Test 7: Estimated Performance
console.log('\n📈 Performance Estimates:');
console.log('-'.repeat(30));
const connectionCount = parseInt(process.env.DB_POOL_MAX || '10');
const queryTimeout = parseInt(process.env.DB_QUERY_TIMEOUT || '30000');
console.log(`Max Concurrent Queries: ${connectionCount}`);
console.log(`Query Timeout: ${queryTimeout / 1000}s`);
console.log(`Estimated QPS: ${Math.round(connectionCount * 1000 / 100)}-${Math.round(connectionCount * 1000 / 50)} queries/sec`);
// Basic vs General Purpose comparison
console.log('\n💰 Configuration Analysis:');
console.log(' Current: Basic tier (suitable for MVP)');
console.log(' Upgrade to General Purpose when:');
console.log(' • > 50 concurrent users');
console.log(' • > 1000 calls/day');
console.log(' • Complex analytics queries');
console.log('\n' + '=' .repeat(60));
console.log('\n🎉 PostgreSQL Configuration Ready!');
console.log('\n✅ Database Capabilities:');
console.log(' • User and session management');
console.log(' • Call records and conversations');
console.log(' • Smart whitelist storage');
console.log(' • Analytics and reporting');
console.log(' • Real-time configuration');
console.log('\n📋 Next Steps:');
console.log('1. Run database migrations');
console.log('2. Seed initial data');
console.log('3. Configure connection pooling in services');
console.log('4. Set up monitoring and alerts');
console.log('5. Test backup and recovery');
return true;
}
// Run test
testDatabaseConfig().then(success => {
if (success) {
console.log('\n✅ Database configuration completed successfully!');
process.exit(0);
} else {
console.log('\n❌ Please fix configuration issues');
process.exit(1);
}
}).catch(error => {
console.error('\n💥 Test failed:', error.message);
process.exit(1);
});