File size: 2,808 Bytes
14356bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
 * 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}`)
})