92 lines
3.5 KiB
JavaScript
92 lines
3.5 KiB
JavaScript
require('dotenv').config();
|
|
|
|
const cron = require('node-cron');
|
|
const http = require('http');
|
|
|
|
const PHP_BASE = process.env.PHP_BASE_URL || 'http://127.0.0.1';
|
|
const PHP_WEBROOT = process.env.PHP_WEBROOT || '/mn3wms/app';
|
|
const SECRET = process.env.EMIT_SECRET || '';
|
|
|
|
function callPhp(path, body) {
|
|
return new Promise((resolve, reject) => {
|
|
const payload = JSON.stringify(body);
|
|
const url = new URL(PHP_BASE + PHP_WEBROOT + path);
|
|
|
|
const options = {
|
|
hostname: url.hostname,
|
|
port: url.port || 80,
|
|
path: url.pathname,
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': Buffer.byteLength(payload),
|
|
'x-cron-secret': SECRET,
|
|
},
|
|
};
|
|
|
|
const req = http.request(options, (res) => {
|
|
let data = '';
|
|
res.on('data', (chunk) => { data += chunk; });
|
|
res.on('end', () => {
|
|
try { resolve(JSON.parse(data)); }
|
|
catch (e) { reject(new Error('Bad JSON: ' + data.slice(0, 100))); }
|
|
});
|
|
});
|
|
|
|
req.on('error', reject);
|
|
req.write(payload);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
// ── ETL GL Summary maintenance — runs every hour ─────────────────────────────
|
|
// Checks and repairs etl_gl_summary (GL aggregation table).
|
|
// Each company has a fixed slot = company_id % 24 — load is spread across 24 hours.
|
|
// For etl_stock_summary add a separate schedule below when ready.
|
|
cron.schedule('0 * * * *', async () => {
|
|
const slot = new Date().getHours();
|
|
console.log(`[scheduler] etl_gl slot=${slot}`);
|
|
|
|
try {
|
|
const result = await callPhp('/cron/etl_gl_maintenance.php', { slot });
|
|
const summary = (result.results || []).map(r =>
|
|
r.error
|
|
? `company=${r.company_id} ERROR: ${r.error}`
|
|
: `company=${r.company_id} gaps=${r.gaps_found} rebuilt=${r.periods_rebuilt}`
|
|
);
|
|
if (summary.length === 0) {
|
|
console.log(`[scheduler] etl_gl slot=${slot} — no companies`);
|
|
} else {
|
|
summary.forEach(s => console.log(`[scheduler] etl_gl ${s}`));
|
|
}
|
|
} catch (e) {
|
|
console.error('[scheduler] etl_gl_maintenance failed:', e.message);
|
|
}
|
|
});
|
|
|
|
// ── ETL Stock Summary maintenance — runs every hour ──────────────────────────
|
|
// Checks and repairs etl_stock_summary (stock aggregation table).
|
|
// Same slot-based distribution as GL: company_id % 24.
|
|
cron.schedule('30 * * * *', async () => {
|
|
const slot = new Date().getHours();
|
|
console.log(`[scheduler] etl_stock slot=${slot}`);
|
|
|
|
try {
|
|
const result = await callPhp('/cron/etl_stock_maintenance.php', { slot });
|
|
const summary = (result.results || []).map(r =>
|
|
r.error
|
|
? `company=${r.company_id} ERROR: ${r.error}`
|
|
: `company=${r.company_id} gaps=${r.gaps_found} rebuilt=${r.periods_rebuilt}`
|
|
);
|
|
if (summary.length === 0) {
|
|
console.log(`[scheduler] etl_stock slot=${slot} — no companies`);
|
|
} else {
|
|
summary.forEach(s => console.log(`[scheduler] etl_stock ${s}`));
|
|
}
|
|
} catch (e) {
|
|
console.error('[scheduler] etl_stock_maintenance failed:', e.message);
|
|
}
|
|
});
|
|
|
|
console.log('[scheduler] running — etl_gl_maintenance + etl_stock_maintenance wired (hourly, slot-based)');
|