Batch-Buendelung (Phase 2): xlsx + Sammel-PDF + FTP + Cron
All checks were successful
Build & Deploy / deploy (push) Successful in 25s
All checks were successful
Build & Deploy / deploy (push) Successful in 25s
Neuer Endpunkt POST /api/batch/build (Token) und Cron (03:00 Europe/Berlin): buendelt offene batch_submissions JE ZUGANG (api_client) zu einer xlsx (Schema Firma/Vorname/Nachname/Zeile1-3/PLZ/Stadt/Land) + einer Sammel- Druck-PDF (alle mitgelieferten Druck-PDFs 1:1) und laedt beide per FTP(S) in die Wurzel. Dateiname <api_client_id>_<YYYY-MM-DD>(.xlsx/.pdf); manuelle Laeufe mit Uhrzeit-Suffix (kein Ueberschreiben des Tageslaufs). Text-only- Datensaetze (ohne PDF) bleiben offen (manuelle Schreibvorlage), nicht im Buendel. Sa+So gemeinsam am Montag (Sonntag-Lauf uebersprungen). Neue Pakete: exceljs, basic-ftp. FTP-Config via ENV (SKRIFT_FTP_HOST/PORT/ USER/PASSWORD/SECURE), Passwort nur in ENV. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,9 @@ const config = require('./config');
|
||||
const previewRoutes = require('./api/routes/preview-routes');
|
||||
const orderRoutes = require('./api/routes/order-routes');
|
||||
const chargeRoutes = require('./api/routes/charge-routes');
|
||||
const batchRoutes = require('./api/routes/batch-routes');
|
||||
const healthRoutes = require('./api/routes/health-routes');
|
||||
const { runScheduledBatch, berlinParts } = require('./api/controllers/batch-controller');
|
||||
|
||||
const errorHandler = require('./api/middleware/error-handler');
|
||||
const requestLogger = require('./api/middleware/request-logger');
|
||||
@@ -49,6 +51,7 @@ app.use('/health', healthRoutes);
|
||||
app.use('/api/preview', previewRoutes);
|
||||
app.use('/api/order', orderRoutes);
|
||||
app.use('/api/charge', chargeRoutes);
|
||||
app.use('/api/batch', batchRoutes);
|
||||
|
||||
// Format-Cache manuell auffrischen (Token-geschützt) – für „sofort übernehmen".
|
||||
app.post('/api/formats/refresh', async (req, res) => {
|
||||
@@ -80,6 +83,19 @@ app.listen(config.port, () => {
|
||||
// Formate initial laden und stündlich auffrischen (zentral aus Directus).
|
||||
refreshRenderFormats();
|
||||
setInterval(refreshRenderFormats, 60 * 60 * 1000);
|
||||
|
||||
// Batch-Bündelung: täglich um 03:00 (Europe/Berlin) den Vortag bündeln + FTP.
|
||||
// Sa+So werden gemeinsam am Montag verarbeitet (Sonntag-Lauf wird übersprungen).
|
||||
// Minuten-Tick; einmal pro Tag im 3-Uhr-Fenster (idempotent über letzterBatchTag).
|
||||
let letzterBatchTag = null;
|
||||
setInterval(() => {
|
||||
try {
|
||||
const { date, hour } = berlinParts();
|
||||
if (hour !== 3 || letzterBatchTag === date) return;
|
||||
letzterBatchTag = date; // markiert den Lauf für heute – auch bei Fehler kein Doppel-Lauf.
|
||||
runScheduledBatch().catch((e) => console.error('[batch-cron] Fehler:', e.message));
|
||||
} catch (e) { console.error('[batch-cron] Tick-Fehler:', e.message); }
|
||||
}, 60 * 1000);
|
||||
});
|
||||
|
||||
// Graceful shutdown
|
||||
|
||||
Reference in New Issue
Block a user