# GIADEC Market Dashboard

Real-time market dashboard for Ghana Integrated Aluminium Development Corporation.

## Features

- **Live commodity prices** scraped from LME, Westmetall, Metal.com
- **DXY, Brent Crude, Baltic Dry Index** from TradingEconomics
- **SOFR rates** from the New York Fed
- **FX rates** (USD/GBP/EUR/CNY vs GHS) — static from BoG snapshot
- **Ghana macroeconomic indicators** table
- **AI-powered market brief** using Anthropic's Claude with live web search
- **5-minute cache** to avoid rate limiting
- **Auto-refresh** every 5 minutes

---

## Quick Start

### Requirements
- Node.js 16+ (uses only built-in modules — no npm install needed)

### Run
```bash
node server.js
```

Then open: **http://localhost:3000**

---

## Data Sources

| Data | Source URL |
|------|-----------|
| US Dollar Index (DXY) | tradingeconomics.com/dxy:cur |
| Brent Crude Oil | tradingeconomics.com/commodity/brent-crude-oil |
| Baltic Dry Index | tradingeconomics.com/commodity/baltic |
| LME Aluminium | lme.com/en/metals/non-ferrous/lme-aluminium |
| LME Alumina | lme.com/en/metals/minor-and-specialty/lme-alumina |
| LME Copper | lme.com/en/metals/non-ferrous/lme-copper |
| LME Nickel | lme.com/en/metals/non-ferrous/lme-nickel |
| Westmetall (Al Cash) | westmetall.com/en/markdaten.php?action=table&field=LME_Al_cash |
| Metal.com Aluminium | metal.com/Aluminum/202102010001 |
| SOFR Rates | newyorkfed.org/markets/reference-rates/sofr |
| AI Brief | Anthropic API with web_search tool |

---

## API Endpoints

| Endpoint | Description |
|----------|-------------|
| `GET /api/market` | All live market data (JSON) |
| `GET /api/health` | Server health + cache status |
| `GET /api/cache/clear` | Force-clear the 5-min cache |

### Example response (`/api/market`):
```json
{
  "fetchedAt": "2026-04-13T10:00:00.000Z",
  "fromCache": false,
  "dxy": { "value": 98.45, "name": "US Dollar Index", "source": "te" },
  "brent": { "value": 95.20, "name": "Brent Crude Oil", "unit": "US$/bbl" },
  "aluminium": {
    "lme": { "cash": 3480.0, "threeMonth": 3498.5, "source": "lme" },
    "westmetall": { "date": "2026-04-13", "cashPrice": 3475.0 }
  },
  "sofr": { "overnight": 3.57, "oneMonth": 3.64, "threeMonth": 3.66, "sixMonth": 3.83 },
  ...
}
```

---

## Deployment Options

### Option A — Run locally
```bash
node server.js
# Open http://localhost:3000
```

### Option B — Run on a VPS (e.g. DigitalOcean, Render, Railway)
```bash
PORT=8080 node server.js
```

### Option C — PM2 (keep alive)
```bash
npm install -g pm2
pm2 start server.js --name giadec-dashboard
pm2 startup && pm2 save
```

### Option D — Docker
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
```
```bash
docker build -t giadec-dashboard .
docker run -p 3000:3000 giadec-dashboard
```

---

## Notes on Scrapers

Some sites (LME, TradingEconomics) serve data dynamically via JavaScript. If scrapers
return null values, it means the page uses client-side rendering. In that case:

1. **Upgrade to Puppeteer** (headless Chrome) for JS-rendered pages:
   ```bash
   npm install puppeteer
   ```
   Then replace the `fetch()` calls in `server.js` with `puppeteer.launch()`.

2. **Use official APIs** where available:
   - LME Data: https://www.lme.com/en/Market-Data/APIs
   - TradingEconomics API: https://tradingeconomics.com/api

The dashboard gracefully falls back to the Apr 13, 2026 snapshot values when
live scraping is unavailable, keeping the dashboard always usable.

---

## File Structure

```
giadec-dashboard/
├── server.js          ← Node.js backend (zero dependencies)
├── README.md          ← This file
└── public/
    └── index.html     ← Full dashboard frontend (self-contained)
```
