Spaces:
Sleeping
Sleeping
| /** | |
| * Genesis AI β Price Elasticity Intelligence (React) | |
| * Express server for Hugging Face Spaces deployment | |
| * Serves the Vite-built React app + proxies /api/data/* from output/ JSONs | |
| */ | |
| const express = require('express') | |
| const path = require('path') | |
| const fs = require('fs') | |
| const app = express() | |
| const PORT = process.env.PORT || 7860 | |
| const ROOT = __dirname | |
| const DIST_DIR = path.join(ROOT, 'dist') | |
| const OUTPUT_DIR = path.join(ROOT, 'output') | |
| app.use(express.json()) | |
| // ββ Health check (Hugging Face pings this) ββββββββββββββββββββββββββββββββ | |
| app.get('/health', (req, res) => { | |
| res.json({ status: 'ok', timestamp: new Date().toISOString() }) | |
| }) | |
| // ββ API: serve individual JSON artefacts ββββββββββββββββββββββββββββββββββ | |
| const JSON_MAP = { | |
| models: 'models.json', | |
| recs: 'recs_full.json', | |
| trend: 'trend.json', | |
| ms: 'ms.json', | |
| vol_salience: 'vol_salience.json', | |
| val_share: 'val_share.json', | |
| freq_anchors: 'freq_anchors.json', | |
| ppa_mt: 'ppa_mt.json', | |
| ppa_tt: 'ppa_tt.json', | |
| comp_ms: 'comp_ms.json', | |
| vtm: 'vtm.json', | |
| interaction: 'interaction.json', | |
| growth_decomp:'growth_decomp.json', | |
| pgi: 'pgi.json', | |
| stats: 'stats.json', | |
| recs_full: 'recs_full.json', | |
| } | |
| app.get('/api/data/:key', (req, res) => { | |
| const fname = JSON_MAP[req.params.key] | |
| if (!fname) return res.status(404).json({ error: 'Unknown data key' }) | |
| const fpath = path.join(OUTPUT_DIR, fname) | |
| if (!fs.existsSync(fpath)) { | |
| return res.status(404).json({ error: `File not found: ${fname}` }) | |
| } | |
| res.setHeader('Content-Type', 'application/json') | |
| res.sendFile(fpath) | |
| }) | |
| // ββ API: status ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| app.get('/api/status', (req, res) => { | |
| const files = Object.entries(JSON_MAP).map(([key, fname]) => ({ | |
| key, | |
| file: fname, | |
| exists: fs.existsSync(path.join(OUTPUT_DIR, fname)), | |
| })) | |
| res.json({ artefacts: files }) | |
| }) | |
| // ββ Serve React build (must be last) βββββββββββββββββββββββββββββββββββββ | |
| app.use(express.static(DIST_DIR)) | |
| app.get('*', (req, res) => { | |
| const indexPath = path.join(DIST_DIR, 'index.html') | |
| if (fs.existsSync(indexPath)) { | |
| res.sendFile(indexPath) | |
| } else { | |
| res.status(503).send('React build not found. Run: npm run build') | |
| } | |
| }) | |
| app.listen(PORT, '0.0.0.0', () => { | |
| console.log(`Genesis AI React App β http://0.0.0.0:${PORT}`) | |
| console.log(`Output dir: ${OUTPUT_DIR}`) | |
| }) | |