const express = require('express'); const router = express.Router(); const { getDb } = require('../db'); const CITY_COORDS = { 'Amsterdam':{lat:52.3676,lng:4.9041},'Rotterdam':{lat:51.9244,lng:4.4777}, 'Den Haag':{lat:52.0705,lng:4.3007},'Utrecht':{lat:52.0907,lng:5.1214}, 'Eindhoven':{lat:51.4416,lng:5.4697},'Groningen':{lat:53.2194,lng:6.5665}, 'Tilburg':{lat:51.5719,lng:5.0672},'Almere':{lat:52.3508,lng:5.2647}, 'Haarlem':{lat:52.3874,lng:4.6462},'Nijmegen':{lat:51.8126,lng:5.8372}, 'Arnhem':{lat:51.9969,lng:6.1832},'Amersfoort':{lat:52.1561,lng:5.3878}, 'Apeldoorn':{lat:52.2112,lng:5.9474},'Zwolle':{lat:52.5168,lng:6.0830}, 'Enschede':{lat:52.2215,lng:6.8937},'Maastricht':{lat:50.8514,lng:5.6900}, 'Leiden':{lat:52.1601,lng:4.4970},'Delft':{lat:51.9999,lng:4.3540}, 'Breda':{lat:51.5719,lng:4.7683},'Hengelo':{lat:52.2636,lng:6.7945}, 'Dronten':{lat:52.5689,lng:5.7175},'Schiphol-Rijk':{lat:52.2845,lng:4.7555}, 'Schiphol':{lat:52.3105,lng:4.7683},'Zaandam':{lat:52.4382,lng:4.8158}, 'Veldhoven':{lat:51.4184,lng:5.4030},'Deventer':{lat:52.2661,lng:6.1557}, 'Wageningen':{lat:51.9692,lng:5.6653},'Eygelshoven':{lat:50.7639,lng:6.0473}, 'Veghel':{lat:51.6665,lng:5.5556},'Leusden':{lat:52.1418,lng:5.4165}, 'Rosmalen':{lat:51.6699,lng:5.7867},'Eemshaven':{lat:53.4430,lng:6.8530}, 'Sliedrecht':{lat:51.8220,lng:4.7733} }; router.get('/', (req, res) => { const db = getDb(); const allDcs = db.prepare('SELECT * FROM datacenters').all(); const allCompanies = db.prepare('SELECT * FROM tech_companies').all(); const regions = [...new Set(allDcs.map(d => d.region).filter(Boolean))].sort(); const industries = [...new Set(allCompanies.map(c => c.industry).filter(Boolean))].sort(); const dwVendors = [...new Set(allCompanies.flatMap(c => (c.data_warehouse||'').split(',').map(s=>s.trim()).filter(Boolean)))].sort(); const allVendors = [...new Set(allDcs.flatMap(d => ((d.network_vendors||'')+','+(d.server_vendors||'')+','+(d.storage_vendors||'')).split(',').map(s=>s.trim()).filter(Boolean)))].sort(); const cities = [...new Set(allCompanies.map(c => c.city).filter(Boolean))].sort(); const totalPower = allDcs.reduce((s,d) => s + (d.power_mw||0), 0); res.render('market-intel', { datacenters: allDcs, companies: allCompanies, regions, industries, dwVendors, allVendors, cities, totalPower }); }); // Realtime API: search datacenters router.get('/search/dc', (req, res) => { const db = getDb(); const { search, vendor, region, type, sort } = req.query; let sql = 'SELECT * FROM datacenters WHERE 1=1'; const params = []; if (search) { sql += ' AND (name LIKE ? OR operator LIKE ? OR city LIKE ? OR network_vendors LIKE ? OR server_vendors LIKE ? OR storage_vendors LIKE ?)'; const s = '%'+search+'%'; params.push(s,s,s,s,s,s); } if (vendor) { sql += ' AND (network_vendors LIKE ? OR server_vendors LIKE ? OR storage_vendors LIKE ?)'; const v = '%'+vendor+'%'; params.push(v,v,v); } if (region) { sql += ' AND region LIKE ?'; params.push('%'+region+'%'); } if (type) { sql += ' AND type = ?'; params.push(type); } sql += ' ORDER BY ' + (sort === 'name' ? 'name' : 'power_mw DESC'); res.json(db.prepare(sql).all(...params)); }); // Realtime API: search companies router.get('/search/co', (req, res) => { const db = getDb(); const { search, industry, dw, city, sort } = req.query; let sql = 'SELECT * FROM tech_companies WHERE 1=1'; const params = []; if (search) { sql += ' AND (name LIKE ? OR industry LIKE ? OR city LIKE ? OR data_warehouse LIKE ? OR bi_tools LIKE ? OR cloud_provider LIKE ? OR ai_ml LIKE ? OR database_vendor LIKE ?)'; const s = '%'+search+'%'; params.push(s,s,s,s,s,s,s,s); } if (industry) { sql += ' AND industry LIKE ?'; params.push('%'+industry+'%'); } if (dw) { sql += ' AND data_warehouse LIKE ?'; params.push('%'+dw+'%'); } if (city) { sql += ' AND city LIKE ?'; params.push('%'+city+'%'); } sql += ' ORDER BY ' + (sort === 'name' ? 'name' : sort === 'employees' ? 'employees DESC' : 'lead_score DESC'); res.json(db.prepare(sql).all(...params)); }); // Map data router.get('/map.json', (req, res) => { const db = getDb(); const dcs = db.prepare('SELECT * FROM datacenters').all(); const companies = db.prepare('SELECT name, city, industry, employees, lead_score, data_warehouse FROM tech_companies').all(); const dcPoints = dcs.map(d => ({...d, lat: (CITY_COORDS[d.city]||{}).lat||52.0, lng: (CITY_COORDS[d.city]||{}).lng||5.0})); const compPoints = companies.map(c => ({name:c.name, city:c.city, lat:(CITY_COORDS[c.city]||{}).lat||52.0, lng:(CITY_COORDS[c.city]||{}).lng||5.0, industry:c.industry, employees:c.employees, lead_score:c.lead_score})); res.json({ datacenters: dcPoints, companies: compPoints }); }); // Filter options router.get('/filters.json', (req, res) => { const db = getDb(); const allDcs = db.prepare('SELECT * FROM datacenters').all(); const allCompanies = db.prepare('SELECT * FROM tech_companies').all(); res.json({ regions: [...new Set(allDcs.map(d => d.region).filter(Boolean))].sort(), industries: [...new Set(allCompanies.map(c => c.industry).filter(Boolean))].sort(), dwVendors: [...new Set(allCompanies.flatMap(c => (c.data_warehouse||'').split(',').map(s=>s.trim()).filter(Boolean)))].sort(), cities: [...new Set(allCompanies.map(c => c.city).filter(Boolean))].sort(), vendors: [...new Set(allDcs.flatMap(d => ((d.network_vendors||'')+','+(d.server_vendors||'')+','+(d.storage_vendors||'')).split(',').map(s=>s.trim()).filter(Boolean)))].sort() }); }); module.exports = router;