94 lines
4.1 KiB
JavaScript
94 lines
4.1 KiB
JavaScript
const express = require('express');
|
||
const cors = require('cors');
|
||
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 healthRoutes = require('./api/routes/health-routes');
|
||
|
||
const errorHandler = require('./api/middleware/error-handler');
|
||
const requestLogger = require('./api/middleware/request-logger');
|
||
|
||
const { applyRenderFormats, setFormatMissHandler } = require('./lib/page-layout');
|
||
const { fetchRenderFormats } = require('./services/directus-service');
|
||
|
||
// Zentrale Format-Definitionen aus Directus in den Cache holen. Läuft beim Start
|
||
// und stündlich; Fehler sind unkritisch (die Defaults im page-layout greifen).
|
||
let lastFormatRefresh = 0;
|
||
async function refreshRenderFormats() {
|
||
lastFormatRefresh = Date.now();
|
||
try {
|
||
const rows = await fetchRenderFormats();
|
||
applyRenderFormats(rows);
|
||
console.log(`[Formate] ${Array.isArray(rows) ? rows.length : 0} Format(e) aus Directus geladen.`);
|
||
} catch (e) {
|
||
console.warn(`[Formate] Konnte Directus-Formate nicht laden (nutze Defaults): ${e.message}`);
|
||
}
|
||
}
|
||
|
||
// Unbekanntes Format angefragt → sofort nachladen (max. alle 30 s, damit ein
|
||
// dauerhaft unbekanntes Format kein Dauerfeuer auslöst).
|
||
setFormatMissHandler((key) => {
|
||
if (Date.now() - lastFormatRefresh < 30 * 1000) return;
|
||
console.log(`[Formate] Unbekanntes Format "${key}" angefragt – lade Formate nach.`);
|
||
refreshRenderFormats();
|
||
});
|
||
|
||
const app = express();
|
||
|
||
// Middleware
|
||
app.use(cors(config.cors));
|
||
app.use(express.json({ limit: '10mb' }));
|
||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||
app.use(requestLogger);
|
||
|
||
// Routes
|
||
app.use('/health', healthRoutes);
|
||
app.use('/api/preview', previewRoutes);
|
||
app.use('/api/order', orderRoutes);
|
||
app.use('/api/charge', chargeRoutes);
|
||
|
||
// Format-Cache manuell auffrischen (Token-geschützt) – für „sofort übernehmen".
|
||
app.post('/api/formats/refresh', async (req, res) => {
|
||
const token = config.auth && config.auth.apiToken;
|
||
if (token && req.headers['x-api-token'] !== token) {
|
||
return res.status(401).json({ error: 'API token required' });
|
||
}
|
||
await refreshRenderFormats();
|
||
res.json({ ok: true });
|
||
});
|
||
|
||
// Error handling
|
||
app.use(errorHandler);
|
||
|
||
// Start server
|
||
app.listen(config.port, () => {
|
||
console.log('╔════════════════════════════════════════════════════════════╗');
|
||
console.log('║ Skrift Backend Server ║');
|
||
console.log('╚════════════════════════════════════════════════════════════╝');
|
||
console.log(`Environment: ${config.env}`);
|
||
console.log(`Port: ${config.port}`);
|
||
console.log(`Batch Size: Unlimited (auto-split to ${config.preview.scriptalizerBatchSize} for API)`);
|
||
console.log(`Cache: Disabled`);
|
||
console.log(`Rate Limit: Disabled`);
|
||
console.log(`Scriptalizer: ${config.scriptalizer.licenseKey ? 'Configured ✓' : 'Missing ✗'}`);
|
||
console.log('════════════════════════════════════════════════════════════');
|
||
console.log(`Server running at http://localhost:${config.port}`);
|
||
console.log('════════════════════════════════════════════════════════════\n');
|
||
// Formate initial laden und stündlich auffrischen (zentral aus Directus).
|
||
refreshRenderFormats();
|
||
setInterval(refreshRenderFormats, 60 * 60 * 1000);
|
||
});
|
||
|
||
// Graceful shutdown
|
||
process.on('SIGTERM', () => {
|
||
console.log('SIGTERM received, shutting down gracefully...');
|
||
process.exit(0);
|
||
});
|
||
|
||
process.on('SIGINT', () => {
|
||
console.log('\nSIGINT received, shutting down gracefully...');
|
||
process.exit(0);
|
||
});
|