#!/usr/bin/env tsx // Database configuration checker for Neon optimization import { checkDatabaseConnection } from "../lib/prisma.js"; import { withRetry } from "../lib/database-retry.js"; async function checkDatabaseConfig() { console.log("šŸ” Database Configuration Checker\n"); // Check environment variables console.log("šŸ“‹ Environment Configuration:"); console.log( ` DATABASE_URL: ${process.env.DATABASE_URL ? "āœ… Set" : "āŒ Missing"}` ); console.log( ` USE_ENHANCED_POOLING: ${process.env.USE_ENHANCED_POOLING || "false"}` ); console.log( ` DATABASE_CONNECTION_LIMIT: ${process.env.DATABASE_CONNECTION_LIMIT || "default"}` ); console.log( ` DATABASE_POOL_TIMEOUT: ${process.env.DATABASE_POOL_TIMEOUT || "default"}` ); // Parse DATABASE_URL for connection details if (process.env.DATABASE_URL) { try { const dbUrl = new URL(process.env.DATABASE_URL); console.log(` Database Host: ${dbUrl.hostname}`); console.log(` Database Port: ${dbUrl.port || "5432"}`); console.log(` Database Name: ${dbUrl.pathname.slice(1)}`); // Check for Neon-specific optimizations const searchParams = dbUrl.searchParams; console.log( ` SSL Mode: ${searchParams.get("sslmode") || "not specified"}` ); console.log( ` Connection Limit: ${searchParams.get("connection_limit") || "not specified"}` ); console.log( ` Pool Timeout: ${searchParams.get("pool_timeout") || "not specified"}` ); } catch (error) { console.log( ` āŒ Invalid DATABASE_URL format: ${error instanceof Error ? error.message : error}` ); } } // Check scheduler intervals console.log("\nā° Scheduler Configuration:"); console.log( ` CSV Import: ${process.env.CSV_IMPORT_INTERVAL || "*/15 * * * *"}` ); console.log( ` Import Processing: ${process.env.IMPORT_PROCESSING_INTERVAL || "*/5 * * * *"}` ); console.log( ` Session Processing: ${process.env.SESSION_PROCESSING_INTERVAL || "0 * * * *"}` ); // Test database connectivity console.log("\nšŸ”Œ Database Connectivity Test:"); try { console.log(" Testing basic connection..."); const isConnected = await checkDatabaseConnection(); console.log( ` Basic connection: ${isConnected ? "āœ… Success" : "āŒ Failed"}` ); if (isConnected) { console.log(" Testing connection with retry logic..."); const retryResult = await withRetry( async () => { const result = await checkDatabaseConnection(); if (!result) throw new Error("Connection check failed"); return result; }, { maxRetries: 3, initialDelay: 1000, maxDelay: 5000, backoffMultiplier: 2, }, "connectivity test" ); console.log( ` Retry connection: ${retryResult ? "āœ… Success" : "āŒ Failed"}` ); } } catch (error) { console.log( ` āŒ Connection test failed: ${error instanceof Error ? error.message : error}` ); } // Recommendations console.log("\nšŸ’” Recommendations:"); if ( !process.env.USE_ENHANCED_POOLING || process.env.USE_ENHANCED_POOLING === "false" ) { console.log(" šŸ”§ Enable enhanced pooling: USE_ENHANCED_POOLING=true"); } if ( !process.env.DATABASE_CONNECTION_LIMIT || Number.parseInt(process.env.DATABASE_CONNECTION_LIMIT) > 15 ) { console.log( " šŸ”§ Optimize connection limit for Neon: DATABASE_CONNECTION_LIMIT=15" ); } if ( !process.env.DATABASE_POOL_TIMEOUT || Number.parseInt(process.env.DATABASE_POOL_TIMEOUT) < 30 ) { console.log( " šŸ”§ Increase pool timeout for cold starts: DATABASE_POOL_TIMEOUT=30" ); } // Check for Neon-specific URL parameters if (process.env.DATABASE_URL) { const dbUrl = new URL(process.env.DATABASE_URL); if (!dbUrl.searchParams.get("sslmode")) { console.log(" šŸ”§ Add SSL mode to DATABASE_URL: ?sslmode=require"); } if (!dbUrl.searchParams.get("connection_limit")) { console.log( " šŸ”§ Add connection limit to DATABASE_URL: &connection_limit=15" ); } } console.log("\nāœ… Configuration check complete!"); } // Run the checker checkDatabaseConfig().catch((error) => { console.error("šŸ’„ Configuration check failed:", error); process.exit(1); });