154 lines
4.3 KiB
Markdown
154 lines
4.3 KiB
Markdown
# tssbot.web
|
|
|
|
React + Vite + Tailwind v4 web shell for Toothless' TSS Bot.
|
|
|
|
Routes:
|
|
|
|
- `/` landing page
|
|
- `/teams` TSS team leaderboard
|
|
- `/teams/:teamname` generated team profile with roster, summary, rating history, and battle results
|
|
- `/battle-logs` Battle Logs
|
|
- `/viewers` public consented viewer analytics dashboard
|
|
|
|
## Local development
|
|
|
|
```sh
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
The development server runs on <http://localhost:3001>.
|
|
|
|
By default, `/api/*` and `/health` requests are proxied to `http://localhost:6000`. Override
|
|
that with `VITE_API_TARGET`:
|
|
|
|
```sh
|
|
VITE_API_TARGET=http://localhost:8080 npm run dev
|
|
```
|
|
|
|
## Production with PM2
|
|
|
|
```sh
|
|
npm install
|
|
npm run build
|
|
pm2 start ecosystem.config.cjs
|
|
```
|
|
|
|
The production server runs on <http://localhost:3010>. It serves `/health`
|
|
locally and only proxies the API routes used by the app:
|
|
|
|
- `GET /api/tss/leaderboard/teams?limit=1..100`
|
|
- `GET /api/tss/teams/resolve?name=...`
|
|
- `GET /api/tss/teams/:team`
|
|
- `GET /api/tss/teams/:team/history`
|
|
- `GET /api/tss/teams/:team/games`
|
|
|
|
The proxy blocks cross-origin/API-navigation requests, strips CORS headers from
|
|
the upstream response, rate limits callers, and caches successful GET responses
|
|
briefly so public page traffic does not hammer the upstream API.
|
|
|
|
Override the API target before starting PM2 if needed:
|
|
|
|
```sh
|
|
API_UPSTREAM=http://127.0.0.1:8080 pm2 start ecosystem.config.cjs
|
|
```
|
|
|
|
Set `PUBLIC_ORIGIN` to the public site origin in production, especially behind a
|
|
reverse proxy:
|
|
|
|
```sh
|
|
PUBLIC_ORIGIN=https://your-domain.example pm2 start ecosystem.config.cjs
|
|
```
|
|
|
|
Optional API protection tuning:
|
|
|
|
```sh
|
|
API_CACHE_TTL_MS=15000
|
|
API_RATE_LIMIT_WINDOW_MS=60000
|
|
API_RATE_LIMIT_MAX=120
|
|
```
|
|
|
|
## Uptime snapshots
|
|
|
|
The production server samples uptime every 30 minutes and exposes the history at
|
|
`/api/uptime`. Snapshots are stored in SQLite under `~/tsswebstorage` by
|
|
default. Set `UPTIME_STORAGE_DIR` to choose a different folder:
|
|
|
|
```sh
|
|
UPTIME_STORAGE_DIR=~/tsswebstorage
|
|
UPTIME_DATABASE_FILE=uptime.sqlite
|
|
UPTIME_SAMPLE_INTERVAL_MS=1800000
|
|
UPTIME_HISTORY_LIMIT=336
|
|
```
|
|
|
|
The server creates the storage folder, SQLite database, and `uptime_snapshots`
|
|
table automatically.
|
|
|
|
## Viewer analytics
|
|
|
|
The site shows a GDPR-style consent banner before analytics start. If a visitor
|
|
allows analytics, the browser sends page-view and heartbeat events to
|
|
`POST /api/viewers/event`. The public `/viewers` page reads `GET /api/viewers`
|
|
and shows active pages, client/browser information, 24-hour page totals, and
|
|
top pages.
|
|
|
|
Viewer analytics are stored in SQLite under the same `UPTIME_STORAGE_DIR` by
|
|
default. Raw IP addresses are not stored in the public response; the server
|
|
stores a salted IP hash for deduplication and abuse review. Set a unique salt in
|
|
production:
|
|
|
|
```sh
|
|
ANALYTICS_DATABASE_FILE=viewers.sqlite
|
|
ANALYTICS_RETENTION_DAYS=30
|
|
ANALYTICS_ACTIVE_WINDOW_SECONDS=75
|
|
ANALYTICS_SALT=replace-with-a-random-secret
|
|
```
|
|
|
|
This is an implementation aid, not legal advice. For production GDPR compliance,
|
|
publish a privacy notice that matches the configured retention period and data
|
|
fields, and make sure the configured salt is secret.
|
|
|
|
## GitHub webhook
|
|
|
|
The webhook process listens on port `3011` at `/github`. Configure GitHub to send
|
|
push events there.
|
|
|
|
Set a webhook secret before starting PM2 if you want signature validation:
|
|
|
|
```sh
|
|
GITHUB_WEBHOOK_SECRET=your-secret pm2 start ecosystem.config.cjs
|
|
```
|
|
|
|
On PowerShell, set `$env:GITHUB_WEBHOOK_SECRET = "your-secret"` before starting
|
|
PM2, or put the value directly in `ecosystem.config.cjs`.
|
|
|
|
The default deploy flow is:
|
|
|
|
```sh
|
|
git pull --ff-only
|
|
npm install --production=false --include=dev --include=optional
|
|
npm run build
|
|
pm2 reload tssbot-web --update-env
|
|
```
|
|
|
|
Only processes listed in `PM2_RESTART_TARGETS` are reloaded. The default is
|
|
`tssbot-web`, so unrelated PM2 processes are left alone. The webhook exits after
|
|
24 hours so PM2 restarts it cleanly.
|
|
|
|
When webhook code changes are deployed, restart the webhook process once so PM2
|
|
loads the updated listener:
|
|
|
|
```sh
|
|
pm2 reload tssbot-webhook --update-env
|
|
```
|
|
|
|
The webhook listener reads `.env` on startup. To send Discord notifications for
|
|
listener restarts and GitHub push deploy start/success/failure events, set:
|
|
|
|
```sh
|
|
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
|
|
```
|
|
|
|
Deploy completion and failure notifications include a changed-file summary and a
|
|
truncated patch preview for the pushed diff.
|