All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s
Soluciones implementadas: 1. Copiar archivos SQL al contenedor Docker - Agregar COPY de server/database/ en Dockerfile - Permite que endpoint seed-database encuentre 02_seed.sql 2. Aumentar timeout de conexión PostgreSQL - connectionTimeoutMillis: 2000 -> 10000 (10 segundos) - Evita errores de autenticación en primera carga 3. Reducir logs en producción - Solo mostrar 'Nueva conexión' en desarrollo - Reduce ruido en logs de producción
110 lines
2.8 KiB
TypeScript
110 lines
2.8 KiB
TypeScript
import pg from 'pg'
|
|
|
|
const { Pool } = pg
|
|
|
|
let pool: pg.Pool | null = null
|
|
|
|
/**
|
|
* Obtiene o crea el pool de conexiones a PostgreSQL.
|
|
* Usa variables de entorno para la configuración.
|
|
*/
|
|
export function getPool(): pg.Pool {
|
|
if (!pool) {
|
|
const config = {
|
|
user: process.env.POSTGRES_USER || 'seguidor',
|
|
password: process.env.POSTGRES_PASSWORD || 'seguidor_password',
|
|
database: process.env.POSTGRES_DB || 'seguidor_lotes',
|
|
host: process.env.POSTGRES_HOST || 'postgres',
|
|
port: parseInt(process.env.POSTGRES_PORT || '5432'),
|
|
max: 20, // máximo de conexiones en el pool
|
|
idleTimeoutMillis: 30000,
|
|
connectionTimeoutMillis: 10000, // Aumentado a 10s para la primera conexión
|
|
}
|
|
|
|
pool = new Pool(config)
|
|
|
|
pool.on('error', (err) => {
|
|
console.error('Error inesperado en el pool de PostgreSQL:', err)
|
|
})
|
|
|
|
// Solo log en desarrollo para reducir ruido
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
pool.on('connect', () => {
|
|
console.log('Nueva conexión establecida con PostgreSQL')
|
|
})
|
|
}
|
|
}
|
|
|
|
return pool
|
|
}
|
|
|
|
/**
|
|
* Ejecuta una query SQL con parámetros.
|
|
* Wrapper seguro para evitar inyección SQL.
|
|
*
|
|
* @param text - Query SQL con placeholders $1, $2, etc.
|
|
* @param params - Parámetros para la query
|
|
* @returns Resultado de la query
|
|
*/
|
|
export async function query<T = any>(
|
|
text: string,
|
|
params?: any[]
|
|
): Promise<pg.QueryResult<T>> {
|
|
const pool = getPool()
|
|
const start = Date.now()
|
|
|
|
try {
|
|
const result = await pool.query<T>(text, params)
|
|
const duration = Date.now() - start
|
|
|
|
// Log solo en desarrollo
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
console.log('Query ejecutada:', { text, duration: `${duration}ms`, rows: result.rowCount })
|
|
}
|
|
|
|
return result
|
|
} catch (error) {
|
|
console.error('Error ejecutando query:', { text, params, error })
|
|
throw error
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtiene un cliente del pool para ejecutar transacciones.
|
|
* IMPORTANTE: Debes llamar a client.release() al terminar.
|
|
*
|
|
* @returns Cliente de PostgreSQL
|
|
*/
|
|
export async function getClient(): Promise<pg.PoolClient> {
|
|
const pool = getPool()
|
|
return await pool.connect()
|
|
}
|
|
|
|
/**
|
|
* Cierra el pool de conexiones.
|
|
* Útil para tests o shutdown graceful.
|
|
*/
|
|
export async function closePool(): Promise<void> {
|
|
if (pool) {
|
|
await pool.end()
|
|
pool = null
|
|
console.log('Pool de PostgreSQL cerrado')
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verifica que la conexión a la base de datos esté funcionando.
|
|
* Útil para health checks.
|
|
*
|
|
* @returns true si la conexión está OK, false en caso contrario
|
|
*/
|
|
export async function checkConnection(): Promise<boolean> {
|
|
try {
|
|
const result = await query('SELECT NOW() as now')
|
|
return result.rows.length > 0
|
|
} catch (error) {
|
|
console.error('Error verificando conexión a PostgreSQL:', error)
|
|
return false
|
|
}
|
|
}
|