Add LAMP web dashboard: bot→MySQL publisher, PHP API, numbers-only page

- webapp/: deployable LAMP app for /var/www/ — ingest.php (token-gated
  writes), api.php (public read-only), schema.sql (live_price +
  signal_reports), vanilla-JS dashboard with plain-English indicator
  readings, .htaccess, deploy README
- web_publisher.py: fire-and-forget publisher (bounded queue + daemon
  thread) with plain-English payload builder; public API contractually
  never raises; disabled unless WEBAPP_INGEST_URL/TOKEN are set
- telegram_bot.py: publish hooks (tick in WS loop, report in
  _update_level_cache); _candle_loop per-iteration guard so a failing
  scan can never kill an auto-scan loop; quiet heartbeat teardown
- test_all.py: Module 13 — 6 resilience tests (never-raise contract,
  worker survival, candle-loop survival); suite 189/189
- .gitignore: webapp/config.php (server-side secrets)

Verified end-to-end on a scratch MariaDB 10.11 + PHP 8.3 built-in
server incl. headless-Firefox render of the live page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KYNEHBuwwy6sgRM9f9sPx5
This commit is contained in:
Harwinder Sekhon
2026-07-17 11:41:03 -04:00
parent 85b7567677
commit 85a5ba09b8
13 changed files with 1437 additions and 4 deletions
+65
View File
@@ -0,0 +1,65 @@
# ForexBot2 web dashboard (LAMP)
Numbers-only live dashboard: latest XAU/USD price plus each timeframe's
signal, indicator values, and a plain-English reading of every one.
## How it flows
```
telegram_bot.py (owns the single Twelve Data WebSocket)
├─ every tick ──► POST ingest.php ──► MySQL live_price (throttled 1/s)
└─ every scan ──► POST ingest.php ──► MySQL signal_reports
│
browser ──► index.html + app.js ──► GET api.php ┘
(price poll 2 s · reports poll 15 s)
```
The dashboard needs **no Python on the web server** — only PHP + MySQL.
The bot can run anywhere with outbound HTTPS to the site.
## Server setup (once)
1. Copy this directory to the web root, e.g. `/var/www/html/webapp/`.
2. Create DB + tables: `mysql -u root -p < schema.sql`
(also create the app user — commands at the bottom of schema.sql).
3. `cp config.sample.php config.php` and fill in DB credentials and a
fresh `ingest_token` (`openssl rand -hex 32`).
4. Apache must allow `.htaccess` (`AllowOverride FileInfo Limit` or
`All`) so config/schema stay unreachable — or copy those deny rules
into the vhost. Verify: `curl -I https://site/webapp/config.php`
must return 403.
## Bot setup
Set two environment variables where `telegram_bot.py` runs:
```bash
export WEBAPP_INGEST_URL="https://your-site/webapp/ingest.php"
export WEBAPP_INGEST_TOKEN="<same token as config.php>"
```
Unset = publishing is disabled and the bot behaves exactly as before.
Publishing is fire-and-forget (bounded queue + daemon thread): a dead
web server can never block or slow the bot.
## Security notes (public access)
- `api.php` is read-only and public by design; `ingest.php` requires the
shared token (use HTTPS so it isn't sent in the clear).
- `config.php` / `schema.sql` are denied by `.htaccess`.
- Optional hardening: rate-limit `api.php` (mod_evasive/fail2ban), and
restrict `ingest.php` to the bot host's IP in the vhost.
## Data growth
- `live_price`: 1 row per symbol (upserted in place).
- `signal_reports`: ~400 rows/day for XAU (M5+M15+H1+H4) — ~150k
rows/year, no retention job needed. It doubles as a durable log of
every signal the engine produced (the `payload` column holds the full
report JSON).
## Local smoke test (no Apache needed)
```bash
php -S 127.0.0.1:8090 -t webapp/ # then open http://127.0.0.1:8090/
```