243 lines
14 KiB
Markdown
243 lines
14 KiB
Markdown
# Workspace System Scan Report
|
||
|
||
Date: 2026-02-21
|
||
Scope:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web`
|
||
|
||
## Method
|
||
- Static review of source, config, workflows, docs, and tests.
|
||
- Runtime checks executed:
|
||
- Bot: `npm run build`, `npm run test`
|
||
- Web: `npm install`, `npm run build`, `npm run lint`, `npm run test`
|
||
|
||
## Executive Summary
|
||
- The platform has strong functional coverage and many tests on the web repo, but there are several critical security and contract-integration issues that can cause unsafe trading behavior or admin controls to fail silently.
|
||
- Most urgent issues:
|
||
1. Secrets committed to git in tracked `.env` files.
|
||
2. Bot API/socket layer has no auth enforcement.
|
||
3. Frontend-backend API/event contract drift (frontend calls endpoints/events not implemented by backend).
|
||
4. Manual trade endpoint can route to the wrong account when `user_id` is omitted.
|
||
|
||
## Confirmed Runtime Results
|
||
- Bot build: pass (`tsc`).
|
||
- Bot test: fail by design (no tests configured): `package.json:8`.
|
||
- Web build: pass, but Node runtime warning (`Node.js 19.7.0`; Vite expects 20.19+).
|
||
- Web lint: pass.
|
||
- Web tests: fail with 33 worker errors (`ERR_REQUIRE_ESM` chain via jsdom/html-encoding-sniffer under current Node runtime).
|
||
- `npm install` in web reported `11 vulnerabilities (1 moderate, 10 high)`.
|
||
|
||
## Findings (By Severity)
|
||
|
||
### Critical
|
||
|
||
1) Secret exposure in tracked env files
|
||
- Evidence:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/.env:4`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/.env:5`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/.env.production:2`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/.env.production:3`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/.env:12`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/.env:13`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/.env:35`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/.env:53`
|
||
- Tracked in git:
|
||
- web: `git ls-files .env .env.production` returns both
|
||
- bot: `git ls-files .env .env.example` returns `.env`
|
||
- Risk:
|
||
- Credential leakage and unauthorized access.
|
||
- Recommendation:
|
||
- Rotate all exposed keys immediately.
|
||
- Remove tracked env files from git history and keep only sanitized examples.
|
||
- Enforce pre-commit + CI secret scanning on both repos.
|
||
|
||
2) Bot API and socket server expose privileged actions without auth checks
|
||
- Evidence:
|
||
- Wildcard CORS: `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:109`, `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:187`
|
||
- No auth middleware before routes: `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:191`
|
||
- Trade endpoint lacks token verification: `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:255`
|
||
- Chat endpoint lacks token verification: `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:285`
|
||
- Socket connection accepts all clients, no token verification: `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:365`
|
||
- Risk:
|
||
- Any reachable client can call trading/chat APIs and subscribe to live state.
|
||
- Recommendation:
|
||
- Add JWT verification middleware for HTTP and `io.use()` auth guard for socket.
|
||
- Restrict CORS origins and disable wildcard in production.
|
||
|
||
3) Cross-account/manual routing risk in `/api/trade`
|
||
- Evidence:
|
||
- Endpoint fallback to first available manager when `user_id` is missing:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:263`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:265`
|
||
- Frontend call omits `user_id` in payload:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/components/EntryForm.tsx:112`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/components/EntryForm.tsx:137`
|
||
- Risk:
|
||
- A user can accidentally execute against another user’s manager/account.
|
||
- Recommendation:
|
||
- Require authenticated user identity on backend; derive `user_id` from verified token claims, not request body.
|
||
- Reject requests without resolvable account context.
|
||
|
||
4) Frontend-backend contract drift breaks admin and position operations
|
||
- Evidence (frontend expects endpoints/events):
|
||
- Pause/Resume: `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/AdminTab.tsx:120`, `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/AdminTab.tsx:149`
|
||
- Clear events: `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/AdminTab.tsx:178`
|
||
- Close position: `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/PositionsTab.tsx:1093`
|
||
- WebSocket events expected: `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/hooks/useWebSocket.ts:298`, `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/hooks/useWebSocket.ts:329`, `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/hooks/useWebSocket.ts:336`, `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/hooks/useWebSocket.ts:347`
|
||
- Evidence (backend implemented routes/events are different/limited):
|
||
- Routes only in current server include `/health`, `/api/status`, `/api/alerts`, `/api/symbol/:symbol`, `/api/config`, `/api/trade`, `/api/chat`:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:192`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:255`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:285`
|
||
- Socket emits only `state` on connect plus symbol/order/history/settings updates:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:367`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:413`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:439`
|
||
- Risk:
|
||
- UI controls appear present but fail at runtime (admin toggles, square-off, health panes).
|
||
- Recommendation:
|
||
- Create and enforce a shared API/event contract (OpenAPI + typed socket event map) consumed by both repos.
|
||
|
||
### High
|
||
|
||
5) Per-profile rule parameters are not applied during execution
|
||
- Evidence:
|
||
- Profile rules include params in input type:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/ProStrategyEngine.ts:46`
|
||
- Engine only uses `enabled` and rule order; each rule is called as `rule.check(context)` with no profile params:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/ProStrategyEngine.ts:73`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/ProStrategyEngine.ts:105`
|
||
- Rules pull thresholds from global config:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/rules/MomentumRule.ts:20`
|
||
- Risk:
|
||
- UI-configured per-profile tuning appears saved but has little/no effect except rule enablement.
|
||
- Recommendation:
|
||
- Pass effective per-profile params into each rule evaluation and validate fallback behavior.
|
||
|
||
6) Dashboard signal can be nondeterministic across profiles
|
||
- Evidence:
|
||
- Parallel profile evaluation and first-completing result chosen for global display:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/index.ts:266`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/index.ts:276`
|
||
- Risk:
|
||
- Dashboard signal may flip depending on async completion order, not deterministic policy.
|
||
- Recommendation:
|
||
- Replace “first result wins” with deterministic aggregation (e.g., profile priority, quorum, or dedicated display profile).
|
||
|
||
7) Order feed/state is overwritten with single-order arrays
|
||
- Evidence:
|
||
- TradeExecutor sends one-element order array each update:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/TradeExecutor.ts:257`
|
||
- API server replaces full order state:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/apiServer.ts:437`
|
||
- Risk:
|
||
- Dashboard order history loses prior orders unless DB backfill covers it.
|
||
- Recommendation:
|
||
- Append/update by order ID server-side rather than full replacement.
|
||
|
||
### Medium
|
||
|
||
8) Dynamic config assignment has no type coercion or validation
|
||
- Evidence:
|
||
- Raw values copied directly into typed config:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/config/index.ts:132`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/config/index.ts:135`
|
||
- Risk:
|
||
- Numeric/boolean configs become strings and alter runtime behavior.
|
||
- Recommendation:
|
||
- Use a schema (zod/io-ts) with explicit per-key parsing and validation.
|
||
|
||
9) Admin tab opens a second socket connection
|
||
- Evidence:
|
||
- Root app already opens socket:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/App.tsx:58`
|
||
- Admin tab opens another:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/AdminTab.tsx:42`
|
||
- Risk:
|
||
- Extra connection load, duplicate subscriptions, racey debug log behavior.
|
||
- Recommendation:
|
||
- Lift socket instance into context and reuse one connection app-wide.
|
||
|
||
10) Potential divide-by-zero/NaN edge cases in signal and PnL logic
|
||
- Evidence:
|
||
- Wick calculation divides by candle size without zero guard:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/rules/EntryTriggerRule.ts:35`
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/rules/EntryTriggerRule.ts:37`
|
||
- `entryPrice` can be `0` on open:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/TradeExecutor.ts:94`
|
||
- PnL% divides by entryPrice:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/services/TradeExecutor.ts:190`
|
||
- Risk:
|
||
- Bad metrics, noisy alerts, invalid DB rows.
|
||
- Recommendation:
|
||
- Add guards for zero/NaN price paths and reject invalid candles/prices.
|
||
|
||
11) AI prompt is symbol-hardcoded
|
||
- Evidence:
|
||
- Prompt always references `BTC/USD`:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/src/strategies/rules/AIAnalysisRule.ts:77`
|
||
- Risk:
|
||
- AI output quality degrades for non-BTC symbols.
|
||
- Recommendation:
|
||
- Inject `ctx.symbol` in prompt and include timeframe/source metadata.
|
||
|
||
12) Frontend currently fetches and stores broker secrets in client profile
|
||
- Evidence:
|
||
- Profile query requests broker key/secret fields:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/components/AuthContext.tsx:100`
|
||
- Settings tab edits and writes key/secret fields from browser:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/src/tabs/SettingsTab.tsx:91`
|
||
- Risk:
|
||
- Higher blast radius if browser/session compromised.
|
||
- Recommendation:
|
||
- Move credential write/read to server-side proxy functions with strict role checks.
|
||
|
||
### Low / Maintainability
|
||
|
||
13) Toolchain/version alignment gap
|
||
- Evidence:
|
||
- No explicit Node version pin file (`.nvmrc`/`.node-version`) in either repo.
|
||
- CI uses Node 20 for web: `/Users/saravana/BytelystAI/trading/bytelyst-trading-dashboard-web/.github/workflows/ci.yml:23`
|
||
- Local run on Node 19 caused warnings and test worker failures.
|
||
- Recommendation:
|
||
- Add `engines` + `.nvmrc` in both repos; enforce in CI and local docs.
|
||
|
||
14) Bot repo lacks meaningful automated test script
|
||
- Evidence:
|
||
- `npm test` is placeholder:
|
||
- `/Users/saravana/BytelystAI/trading/bytelyst-trading-bot-service/package.json:8`
|
||
- Recommendation:
|
||
- Introduce unit tests for strategy/risk/execution and a mocked integration test for route auth and trade routing.
|
||
|
||
## Gaps / Capability Caps
|
||
- Missing shared contract package causes drift between UI expectations and bot implementation.
|
||
- Per-profile strategy customization currently behaves as partial customization (enable/order only, not full parameterization).
|
||
- Operational controls (pause/resume/events clear/square-off) are present in UI but not guaranteed by backend.
|
||
- Security model is inconsistent: frontend sends bearer tokens, backend largely ignores them.
|
||
|
||
## Priority Plan (Pragmatic)
|
||
|
||
### Phase 0 (Immediate: same day)
|
||
1. Rotate all exposed secrets and remove them from tracked files/history.
|
||
2. Disable unsecured production endpoints until auth middleware is in place.
|
||
3. Block `/api/trade` if backend cannot map verified user to a single manager.
|
||
|
||
### Phase 1 (1-2 days)
|
||
1. Implement HTTP + socket auth middleware with role checks for admin routes.
|
||
2. Add missing backend endpoints/events or remove dead UI controls behind feature flags.
|
||
3. Fix order-state replacement semantics and preserve rolling order history.
|
||
|
||
### Phase 2 (2-4 days)
|
||
1. Introduce typed shared contract for REST + socket events.
|
||
2. Apply per-profile rule params in strategy engine/rules.
|
||
3. Add config schema validation/coercion for dynamic config.
|
||
|
||
### Phase 3 (Hardening)
|
||
1. Pin Node runtime (`engines`, `.nvmrc`) and stabilize Vitest across environments.
|
||
2. Expand bot automated tests beyond scripts and external/live checks.
|
||
3. Add security gates in bot repo (gitleaks + dependency audit + auth tests).
|
||
|
||
## Final Assessment
|
||
- The foundation is workable, but production safety depends on resolving auth, secrets, and contract drift first.
|
||
- After those are fixed, the main performance/quality gains come from deterministic aggregation, full profile-parameter support, and better test reliability.
|