- Max drawdown was double-broken: the backend built the equity curve on a
hardcoded $10k baseline (understating a small account's drawdown ~20x) and
the frontend multiplied the already-percent value by 100 again (0.87% shown
as -86.9%). The curve now starts from the trader's real initial balance
(10k fallback when unknown) and the UI renders the percent once; the demo
engine and type docs are aligned to percent semantics.
- Header now separates equity-based 'Total P/L (incl. unrealized)' from
'Realized P/L (closed trades)' so it no longer contradicts profit factor /
win rate, and the stats strip shows the fee-drag chain
(gross - fees = net) plus a per-trade-labelled sharpe.
- Risk radar read a non-existent account field (total_unrealized_profit) so
unrealized PnL always showed $0; small PnLs also render with cents now.
- Nav 'Connect Hyperliquid' turns into a green connected chip when the server
already holds a fully-authorized exchange, instead of nagging forever from
a browser without the localStorage flow state.
- config: require JWT_SECRET >=32 bytes and reject the historical
default fallback; MustInit aborts startup under an insecure config
- api: CORS now uses CORS_ALLOWED_ORIGINS allowlist with safe
localhost defaults instead of returning Access-Control-Allow-Origin: *
- api: /api/reset-password and /api/reset-account stay public so
recovery still works, but require an explicit confirm phrase in the
body to block accidental and drive-by triggers
- api: drop adoptOrphanRecords so wiping the account no longer hands
the next registrant the previous owner's wallet keys and exchange
API credentials
- api: getTraderFromQuery now does a soft ownership check; equity-history
is restricted to traders with show_in_competition=true and
GetOrderFills joins on trader_id
- telegram: bot api_request tool uses a default-deny method+path
allowlist so prompt injection cannot reach password, exchange key,
AI provider or wallet endpoints
- ci: drop @master / @main on trivy-action and trufflehog; pin to
released versions with a TODO to move to SHA + Dependabot
- web: reset flows send the required confirm phrase; "Forgot account"
copy (en/zh/id) warns that wallet and exchange keys will be lost
- docker-compose: keep ./.env mount for onboarding wallet persistence
with an inline note on the tradeoff, drop the host-exposed pprof port