- Fix 1: UV_THREADPOOL_SIZE=24 via start_server.sh wrapper (libuv reads OS
environ; process.env and PM2 env blocks don't propagate on this system)
- Fix 2: Stale-while-revalidate for leaderboards — serve cached/stale data
instantly, refresh in background; dedicated aggregateCache isolated from
the 100-entry responseCache; single-flight dedup for concurrent computes
- Fix 3: Background warmer precomputes current + last-completed season
leaderboards at +20s boot and every 4 min
- Fix 5: Adaptive TTL (5 min live, 24 h completed) via aggregateCacheTtl
- Fixes 1+2 combined: player page stall 95s -> 3.6s under concurrent heavy
leaderboard load; warm hits served in 1-4ms (was 13-53s)
A player who changed squadrons could end up with two rows in
squadron_members (old + new clan). Without ORDER BY, LIMIT 1
returned whichever row the primary-key B-tree (clan_id, uid) put
first — i.e. the lowest clan_id, which was the stale entry. This
caused the player page to show the old squadron while the homepage
search (which only reads player_games_hist) showed the correct one.
Fix: add ORDER BY updated_at DESC to both the API roster lookup in
server.js and the web fallback lookup in web/server.js, so the most
recently synced membership always wins.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously sqKps = sumAllPlayerKills / games, inflating the value ~8x
since all 8 players' kills were summed before dividing by game count.
Now computed as the mean of each active player's individual kills/games.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds /api/tss/teams/* and /api/tss/leaderboard/teams to SREBOT/server.js,
reading tss_battles.db and tss_teams.db with queries adapted to the
team_id / team_name / teams_data schema. Mirrors the existing
/api/squadrons/* endpoints. SREBOT/web/server.js gains matching proxy
routes so the frontend can reach them via the website host.
TSSBOT/BOT/storage.py picks up the columns and table the endpoints need
to return meaningful data: teams_data.clanrating, team_members.points,
and a new teams_points history table. All idempotent under the existing
init_tss_dbs() call.
Co-authored-by: Heidi <clippii@protonmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Make .env the single source of truth for runtime config. Remove all
`env:` blocks from SREBOT/ecosystem.config.js and TSSBOT/ecosystem.config.js
so values can't silently shadow .env. Both ecosystem files load .env via
`require('dotenv').config()` and PM2 inherits the resolved environment.
- Rename SREBOT_STORAGE_VOL_PATH → STORAGE_VOL_PATH across all readers
(BOT/utils.py, BOT/receiver_bridge.py, BOT/render_recap.py, server.js,
web/server.js, dateindex.js, scripts/*, srebot.service, tests/, README,
and both .env files). STORAGE is shared between SREBOT and TSSBOT, so the
variable shouldn't carry one bot's prefix.
- Rename per-process PORT env vars to disambiguated names so .env can be
the source of truth without collisions:
PORT (api) → SREBOT_API_PORT (server.js)
PORT (web) → SREBOT_WEB_PORT (web/server.js)
WEBHOOK_PORT → SREBOT_WEBHOOK_PORT (github_webhook_updater.py)
SREBOT_EXTERNAL_HOST/PORT/UPSTREAM_URL were already uniquely named;
they just move from ecosystem env to .env.
- TSSBOT/.env: drop GITHUB_WEBHOOK_SECRET (only srebot-webhook consumes it)
and the stale SREBOT_DEPLOY_PATH. SREBOT/.env: also drop the obsolete
SREBOT_DEPLOY_PATH (ecosystem now hardcodes __dirname).
- ecosystem.config.js no longer references SREBOT_DEPLOY_PATH; deploy path
is always __dirname of the ecosystem file.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #1223 only staged the deletions of the old paths because the new
top-level directories were still untracked when the commit was authored.
This commit adds the actual restructured tree: SREBOT/ (existing bot),
SHARED/ (vromfs, data_parser, ICONS/MAPS/FONTS, DAGOR_FILES,
update_game_files), and TSSBOT/ (skeleton).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>