integraciones para cloud recovery Reviewed-on: #9 Co-authored-by: hreyes <hreyes@aduanasoft.com.mx> Co-committed-by: hreyes <hreyes@aduanasoft.com.mx>
99 lines
3.1 KiB
JavaScript
99 lines
3.1 KiB
JavaScript
/**
|
|
* Espera a que PostgreSQL responda y que el esquema CloudRestore (Alembic a24c)
|
|
* esté aplicado antes de arrancar el panel HTTPS.
|
|
*/
|
|
import { fileURLToPath } from 'url';
|
|
import pg from 'pg';
|
|
|
|
const { Pool } = pg;
|
|
|
|
const REQUIRED_TABLES = ['restore_targets', 'cloudrestore_status', 'restore_job_logs'];
|
|
|
|
function envInt(name, fallback) {
|
|
const raw = process.env[name];
|
|
if (!raw) return fallback;
|
|
const n = Number.parseInt(raw, 10);
|
|
return Number.isFinite(n) && n > 0 ? n : fallback;
|
|
}
|
|
|
|
function poolConfig() {
|
|
return {
|
|
host: process.env.DB_POSTGRES_HOST || 'localhost',
|
|
port: Number.parseInt(process.env.DB_POSTGRES_PORT || '5432', 10),
|
|
database: process.env.DB_POSTGRES_DB || 'a24c',
|
|
user: process.env.DB_POSTGRES_USER || 'postgres',
|
|
password: process.env.DB_POSTGRES_PASS || 'postgres',
|
|
max: 1,
|
|
connectionTimeoutMillis: 5000,
|
|
};
|
|
}
|
|
|
|
async function postgresReady(pool) {
|
|
await pool.query('SELECT 1');
|
|
}
|
|
|
|
async function tablesReady(pool) {
|
|
const r = await pool.query(
|
|
`
|
|
SELECT table_name
|
|
FROM information_schema.tables
|
|
WHERE table_schema = 'a24c'
|
|
AND table_name = ANY($1::text[])
|
|
`,
|
|
[REQUIRED_TABLES]
|
|
);
|
|
return r.rows.length === REQUIRED_TABLES.length;
|
|
}
|
|
|
|
function sleep(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
export async function waitForA24cSchema() {
|
|
const maxAttempts = envInt('A24C_SCHEMA_WAIT_ATTEMPTS', 60);
|
|
const intervalMs = envInt('A24C_SCHEMA_WAIT_INTERVAL_MS', 2000);
|
|
const pool = new Pool(poolConfig());
|
|
|
|
console.log('==========================================');
|
|
console.log('Panel — esperando esquema a24c (CloudRestore)');
|
|
console.log(` host: ${poolConfig().host}:${poolConfig().port}`);
|
|
console.log(` db: ${poolConfig().database}`);
|
|
console.log('==========================================');
|
|
|
|
try {
|
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
try {
|
|
await postgresReady(pool);
|
|
if (await tablesReady(pool)) {
|
|
console.log('✓ PostgreSQL y esquema CloudRestore listos');
|
|
return;
|
|
}
|
|
console.log(
|
|
` intento ${attempt}/${maxAttempts}: tablas CRA pendientes (levanta a24c-backend si aún no corre)`
|
|
);
|
|
} catch (err) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
console.log(` intento ${attempt}/${maxAttempts}: ${msg}`);
|
|
}
|
|
|
|
if (attempt < maxAttempts) {
|
|
await sleep(intervalMs);
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
'Timeout esperando esquema CloudRestore. Orden recomendado: ' +
|
|
'a24c-postgres → a24c-backend (alembic upgrade head) → panel'
|
|
);
|
|
} finally {
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
waitForA24cSchema().catch((err) => {
|
|
console.error('❌', err instanceof Error ? err.message : err);
|
|
process.exit(1);
|
|
});
|
|
}
|