update FDISK sync
This commit is contained in:
@@ -1,12 +1,36 @@
|
||||
import 'dotenv/config';
|
||||
import * as http from 'http';
|
||||
import { Pool } from 'pg';
|
||||
import { scrapeAll } from './scraper';
|
||||
import { syncToDatabase } from './db';
|
||||
|
||||
// In-memory log ring buffer — last 500 lines captured from all modules
|
||||
const LOG_BUFFER_MAX = 500;
|
||||
const logBuffer: Array<{ ts: string; line: string }> = [];
|
||||
|
||||
const _origLog = console.log;
|
||||
const _origErr = console.error;
|
||||
function captureToBuffer(line: string) {
|
||||
logBuffer.push({ ts: new Date().toISOString(), line });
|
||||
if (logBuffer.length > LOG_BUFFER_MAX) logBuffer.shift();
|
||||
}
|
||||
console.log = (...args: unknown[]) => {
|
||||
const line = args.map(String).join(' ');
|
||||
_origLog(line);
|
||||
captureToBuffer(line);
|
||||
};
|
||||
console.error = (...args: unknown[]) => {
|
||||
const line = args.map(String).join(' ');
|
||||
_origErr(line);
|
||||
captureToBuffer(line);
|
||||
};
|
||||
|
||||
function log(msg: string) {
|
||||
console.log(`[sync] ${new Date().toISOString()} ${msg}`);
|
||||
}
|
||||
|
||||
let syncRunning = false;
|
||||
|
||||
function requireEnv(name: string): string {
|
||||
const val = process.env[name];
|
||||
if (!val) throw new Error(`Missing required environment variable: ${name}`);
|
||||
@@ -23,6 +47,11 @@ function msUntilMidnight(): number {
|
||||
}
|
||||
|
||||
async function runSync(): Promise<void> {
|
||||
if (syncRunning) {
|
||||
log('Sync already in progress, skipping');
|
||||
return;
|
||||
}
|
||||
syncRunning = true;
|
||||
const username = requireEnv('FDISK_USERNAME');
|
||||
const password = requireEnv('FDISK_PASSWORD');
|
||||
|
||||
@@ -40,13 +69,41 @@ async function runSync(): Promise<void> {
|
||||
await syncToDatabase(pool, members, ausbildungen);
|
||||
log(`Sync complete — ${members.length} members, ${ausbildungen.length} Ausbildungen`);
|
||||
} finally {
|
||||
syncRunning = false;
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
function startHttpServer(port: number) {
|
||||
const server = http.createServer((req, res) => {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
|
||||
if (req.method === 'GET' && req.url === '/logs') {
|
||||
res.writeHead(200);
|
||||
res.end(JSON.stringify({ running: syncRunning, logs: logBuffer }));
|
||||
} else if (req.method === 'POST' && req.url === '/trigger') {
|
||||
if (syncRunning) {
|
||||
res.writeHead(409);
|
||||
res.end(JSON.stringify({ running: true, message: 'Sync already in progress' }));
|
||||
return;
|
||||
}
|
||||
res.writeHead(200);
|
||||
res.end(JSON.stringify({ started: true }));
|
||||
runSync().catch(err => log(`ERROR during manual sync: ${err.message}`));
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end(JSON.stringify({ message: 'Not found' }));
|
||||
}
|
||||
});
|
||||
server.listen(port, () => log(`HTTP control server listening on port ${port}`));
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
log('FDISK sync service started');
|
||||
|
||||
const httpPort = parseInt(process.env.SYNC_HTTP_PORT ?? '3001', 10);
|
||||
startHttpServer(httpPort);
|
||||
|
||||
// Run once immediately on startup so the first sync doesn't wait until midnight
|
||||
await runSync().catch(err => log(`ERROR during initial sync: ${err.message}`));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user