Auth.tsx and Profile.tsx read import.meta.env.VITE_BOT_USERNAME — a Vite
build-time constant. This ЛК frontend is a single static bundle built
once in CI and served identically by both prod and dev (no
server-rendering to re-inject a value per environment, unlike the
Next.js landing fix from earlier). So the Telegram Login Widget on the
dev stand was rendering with whatever bot the CI build happened to be
compiled with — in practice the fallback default, the prod bot's
username — and Telegram correctly refused it with "Bot domain invalid"
since that bot's registered domain is the prod domain, not
dev.netrunner-vpn.com.
Added GET /api/v1/config (unauthenticated, reads BOT_USERNAME from the
server's actual environment on every request) and switched both files to
fetch it at runtime instead of reading the baked-in env var. Verified
locally: the dev container's /api/v1/config correctly returns its own
dev bot's username, and a real headless Chrome run confirms the Login
Widget script tag gets that value, not the hardcoded fallback.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>