Files

69 lines
3.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const cache = require('../cache');
async function getSupplyChainData() {
const flows = [
{ from: 'China', to: 'Rotterdam', value: 42.5, delay: 2.1, mode: 'Sea' },
{ from: 'VS', to: 'Rotterdam', value: 18.2, delay: 1.4, mode: 'Sea' },
{ from: 'Duitsland', to: 'Amsterdam', value: 12.8, delay: 0.6, mode: 'Road' },
{ from: 'België', to: 'Rotterdam', value: 9.4, delay: 0.4, mode: 'Road' },
{ from: 'VK', to: 'Rotterdam', value: 7.1, delay: 1.8, mode: 'Sea' },
{ from: 'India', to: 'Rotterdam', value: 5.2, delay: 3.2, mode: 'Sea' }
];
const throughput = Array.from({ length: 12 }, (_, i) => ({
month: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'][i],
rotterdam: Math.round(820 + Math.sin(i / 2) * 40 + i * 3),
amsterdam: Math.round(95 + Math.sin(i / 3) * 8 + i * 0.5),
antwerp: Math.round(210 + Math.cos(i / 2) * 15)
}));
const modeSplit = [
{ name: 'Zee', value: 68, fill: '#f59e0b' },
{ name: 'Weg', value: 22, fill: '#00d4ff' },
{ name: 'Spoor', value: 7, fill: '#22c55e' },
{ name: 'Lucht', value: 3, fill: '#7c3aed' }
];
const delayByRoute = flows.map(f => ({ route: `${f.from}${f.to}`, delay: f.delay, volume: f.value }));
const portLocations = [
{ name: 'Rotterdam', lat: 51.95, lng: 4.12, throughput: 868, risk: 34 },
{ name: 'Amsterdam', lat: 52.37, lng: 4.90, throughput: 98, risk: 22 },
{ name: 'Moerdijk', lat: 51.72, lng: 4.62, throughput: 45, risk: 18 }
];
const insights = [
{ type: 'warn', label: 'Risico', text: '72% import via top-3 landen — concentratierisico zichtbaar in flow view.' },
{ type: 'info', label: 'Haven', text: 'Rotterdam 868M ton — koppel ETA-data voor proactieve vertraging-alerts.' },
{ type: 'ok', label: 'Actie', text: 'Multimodaal split toont waar rail/barge investering ROI heeft.' },
{ type: 'warn', label: 'Vertraging', text: `Gem. vertraging ${+(flows.reduce((a, f) => a + f.delay, 0) / flows.length).toFixed(1)} d — India-route 3.2d monitor.` },
{ type: 'info', label: 'Throughput', text: 'Rotterdam +3% YoY — Antwerpen concurrentie in zelfde view.' },
{ type: 'ok', label: 'Integratie', text: 'ERP/WMS ETA feed → SSE alerts — zelfde Global Ops shell als andere verticals.' }
];
const contextBlocks = [
{ title: 'Waarom Supply Chain Tower?', body: 'Logistiek directeuren missen vaak één view op havens, routes, vertraging en concentratierisico — tot er disruption is.' },
{ title: 'Wat u hier ziet', body: 'Import flows, haven throughput trends, multimodaal split, route delays — refresh elke 2,5 seconden.' },
{ title: 'Technische aanpak Mek-Tech', body: 'Eurostat COMEXT + haven open data + eigen ERP koppeling. Lightweight SSE i.p.v. zware SCM suite.' },
{ title: 'ROI voor uw organisatie', body: 'Proactieve vertraging-alerts, betere modal shift beslissingen, lagere voorraad-buffer.' },
{ title: 'Productie-architectuur', body: 'Port API + AIS + ERP → event hub → dit dashboard. Drill-down per shipment optioneel.' },
{ title: 'Volgende stap', body: 'Pilot Rotterdamwarehouse corridor met ETA alerts — live binnen 4 weken.' }
];
return {
ts: new Date().toISOString(),
refreshMs: 2500,
totalThroughput: 868, throughputYoy: 3.2, flows, throughput,
riskScore: 34, concentrationTop3: 72.5, modeSplit, delayByRoute, portLocations, insights, contextBlocks,
avgDelay: +(flows.reduce((a, f) => a + f.delay, 0) / flows.length).toFixed(1),
activeRoutes: flows.length,
delayedRoutes: flows.filter(f => f.delay > 2).length,
context: {
pitch: 'Global Supply Chain Control Tower — havens, flows & risico live.',
deployment: 'Eurostat COMEXT · Port of Rotterdam · CBS Logistiek'
}
};
}
module.exports = { getSupplyChainData };