Web dashboard v2: static publisher + Apache, with calendar & news panels

- dashboard_publisher.py: standalone candle-close daemon that atomically
  writes snapshot.json/news.json/dashboard.html to an Apache-served dir
  (DASHBOARD_OUT_DIR). Fully independent of telegram_bot/oanda_daemon —
  local confirmation map + boundary math, no imports either way, no new
  deps, no open port. Due-TF classification from the RAW wake time.
- static/dashboard.html: self-contained dark page — hero rail, four TF
  cards (score bar, 3x3 indicator grid, MTF, setup, reasons), DeepSeek
  market context, week economic calendar, scored newswire. Clock offset
  from the HTTP Date header (publish-time epoch is stale between closes).
- news_engine.get_week_events(): additive read-only accessor over the
  cached FF week; no signal path calls it.
- deploy/: systemd unit + live-server (LAMP/SELinux) checklist.
- test_all.py: Module 20 (9 tests) + get_week_events test; 296 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wc9ZoqKLYBT2QJcpRWKoGm
This commit is contained in:
Harwinder Sekhon
2026-08-03 17:10:29 -04:00
parent 356a09e5ab
commit 4efe30508b
7 changed files with 1574 additions and 1 deletions
+90
View File
@@ -0,0 +1,90 @@
# Deploying the web dashboard (live LAMP server)
The dashboard is a **static publisher**: `dashboard_publisher.py` runs as its
own daemon, scans XAU/USD at candle closes, and atomically writes
`dashboard.html` + `snapshot.json` + `news.json` into a folder Apache already
serves. Apache does all web serving — no new port, no Python web server, and
the telegram bot process is completely unaffected by anything that happens
here (see the module docstring for the independence rules).
All steps below run **on the live server** (`/home/Forex/ForexBot2`).
## 1. Get the code
```bash
cd /home/Forex/ForexBot2
git pull
venv/bin/python test_all.py # optional sanity: suite must be green
```
No new Python dependencies are required.
## 2. Create the web folder
```bash
sudo mkdir -p /var/www/html/gold-dashboard
sudo chown Forex: /var/www/html/gold-dashboard # the user the daemon runs as
```
RHEL/Alma/CentOS with SELinux enforcing — label the folder so httpd may read it
(the daemon writes as a normal user; only httpd is SELinux-confined):
```bash
sudo semanage fcontext -a -t httpd_sys_content_t '/var/www/html/gold-dashboard(/.*)?'
sudo restorecon -R /var/www/html/gold-dashboard
```
## 3. Smoke-test once
```bash
venv/bin/python dashboard_publisher.py --once
ls /var/www/html/gold-dashboard # dashboard.html snapshot.json news.json
```
Then open `http://<server>/gold-dashboard/dashboard.html` — all four
timeframe cards, the calendar, and the newswire should populate.
## 4. Install the daemon
```bash
sudo cp deploy/gold-dashboard.service /etc/systemd/system/
# edit User= if the repo owner is not "Forex"
sudo systemctl daemon-reload
sudo systemctl enable --now gold-dashboard
systemctl status gold-dashboard
tail -f logs/dashboard.log
```
The daemon scans all four timeframes at boot, then wakes at every M5
boundary (+10 s) and rescans whichever timeframes just closed. Logs rotate
every 3 h (240 backups), same scheme as the bot.
## 5. Optional Apache polish
The page cache-busts its JSON fetches (`?t=<epoch>`), so no Apache config is
strictly needed. To be explicit anyway:
```apache
<Directory "/var/www/html/gold-dashboard">
<FilesMatch "\.json$">
Header set Cache-Control "no-cache"
</FilesMatch>
</Directory>
```
The page is deliberately public (owner decision 2026-08-03). To restrict it
later, add standard Apache basic auth (`htpasswd` + `Require valid-user`) on
that directory — no code changes needed.
## Operational notes
- **Updating**: `git pull` + `systemctl restart gold-dashboard`. The daemon
re-copies `static/dashboard.html` into the web folder at startup.
- **If the daemon dies**, systemd restarts it in 30 s; worst case the page
shows stale data with its own "updated N min ago" evidence. Apache and the
telegram bot are unaffected.
- **DeepSeek**: the publisher process has its own daily request cap
(`deepseek.daily_request_cap`, default 500) separate from the bot's —
expect roughly up to ~430 extra calls/day worst case, V4-Flash pricing.
- **Credentials**: uses the same env/.env/config.json resolution as the rest
of the platform (Oanda candles feed; news needs no key; DeepSeek optional).