Investment trading learning app
Go to file
Devin a48187da83 refactor(web): extract repeated inline-style patterns to classes (UI audit #8)
Per-pattern, per-file analysis found 191 inline-style blocks across the
3 landing-view files (OverviewTab 72, MyStrategiesTab 64, HomeView 55).
155 are unique one-offs already using design tokens (var(--bl-*)) — those
stay inline since converting them to single-use classes would just relocate
code without reducing drift.

This commit extracts the **repeated patterns** (count >= 2 plus structural
container shapes) — 39 occurrences — into either Tailwind utilities or a
new web/src/styles/landing-views.css partial:

  Tailwind replacements:
    textAlign: 'right'                                           → text-right
    marginBottom: '32px' / '24px'                                → mb-8 / mb-6
    fontWeight: 700                                              → font-bold
    flex+justify-between+items-center                            → flex justify-between items-center

  CSS partial (.lv-* classes, all token-driven):
    .lv-card, .lv-card-lg, .lv-icon-tag, .lv-surface, .lv-eyebrow,
    .lv-section-title, .lv-section-sub, .lv-empty-text,
    .lv-divider-row, .lv-meta-faint

Per-file deltas:
    tabs/OverviewTab.tsx       72 -> 53 inline blocks (19 conversions)
    tabs/MyStrategiesTab.tsx   64 -> 55 inline blocks ( 9 conversions)
    views/HomeView.tsx         55 -> 44 inline blocks (11 conversions)

The remaining 152 inline-style blocks are unique one-offs (one usage each)
and already token-driven — extracting them yields no drift reduction.
docs/ui/UI_AUDIT.md §5 #8 updated with this rationale.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-05-10 09:39:31 +00:00
.vscode fix(vscode): make alpaca mcp launcher sh-compatible 2026-05-06 09:37:44 -07:00
.windsurf/workflows chore(workflows): improve onboard-trading-product — relative paths, push steps, idempotency, git guards 2026-05-09 20:28:28 -07:00
backend fix(web): global layout fixes for overlap, clipping, responsive reflow 2026-05-10 07:14:50 +00:00
docs chore(web): hex-color audit + annotate intentional shadows (UI audit #10) 2026-05-10 09:33:54 +00:00
mobile chore(build): add switchable bytelyst package source 2026-05-05 19:47:41 +00:00
scripts docs: add Docker deployment guide and update smoke script 2026-05-10 00:27:17 +00:00
shared fix(platform): use settings kill-switch route 2026-05-05 22:14:41 +00:00
web refactor(web): extract repeated inline-style patterns to classes (UI audit #8) 2026-05-10 09:39:31 +00:00
.dockerignore feat: migrate web to Gitea registry, add /api/devops/info, fix role drift 2026-05-10 04:57:09 +00:00
.env.example feat(backend): WebSocket namespaces, audit persistence, tab flags, telemetry 2026-04-29 19:35:00 -04:00
.gitignore chore: remove leftover tarball deps, gitignore docker-deps dirs 2026-05-10 01:52:35 +00:00
.npmrc Polish trading UI and add launch roadmap 2026-05-08 20:58:00 -07:00
.npmrc.docker feat: migrate web to Gitea registry, add /api/devops/info, fix role drift 2026-05-10 04:57:09 +00:00
docker-compose.dev.yml chore(build): add switchable bytelyst package source 2026-05-05 19:47:41 +00:00
docker-compose.yml chore: enforce local ByteLyst package resolution 2026-05-08 21:09:14 -07:00
package.json chore: enforce local ByteLyst package resolution 2026-05-08 21:09:14 -07:00
pnpm-lock.yaml test(ui): add Playwright and Storybook testing infrastructure 2026-05-09 13:19:14 -07:00
pnpm-workspace.yaml feat: scaffold trading monorepo foundation 2026-04-04 11:18:21 -07:00
README.md chore: enforce local ByteLyst package resolution 2026-05-08 21:09:14 -07:00
tsconfig.base.json feat: scaffold trading monorepo foundation 2026-04-04 11:18:21 -07:00
vercel.json feat: make backend Docker-ready and web Vercel-ready 2026-04-05 19:05:35 -07:00

ByteLyst Investment Trading

Canonical monorepo for the ByteLyst trading product. Contains the backend trading engine, web dashboard, and Expo mobile app under a single pnpm workspace.

Workspaces

Package Path Description
@bytelyst/trading-backend backend/ Node.js trading engine, REST API, Socket.IO
@bytelyst/trading-web web/ React 19 dashboard (Vite)
@bytelyst/trading-mobile mobile/ Expo 54 React Native companion app
shared types shared/ Cross-surface constants, interfaces, and helpers

Core Principles

  • Backend-authoritative state — all trading state (orders, positions, capital) lives in the backend; web/mobile only read and display
  • Platform-service for auth (platform JWT), kill-switch, telemetry, and feature flags
  • Cosmos DB is primary — Azure Cosmos DB is the production control-plane store; Supabase is legacy fallback only
  • No duplicated bootstrap — auth, kill-switch, and telemetry bootstrap run once per surface via shared contracts
  • Trading domain stays product-owned — strategy logic, risk rules, and execution never move to common-platform packages

Quick Start

pnpm run install:common-plat
cp .env.example .env               # root — used by Docker Compose and CI
cp backend/.env.example backend/.env  # backend — fill in Cosmos, exchange, and AI credentials
cp web/.env.example web/.env.local    # web — Vite build-time API URLs
cp mobile/.env.example mobile/.env.local  # mobile — Expo build-time API URLs
pnpm verify            # typecheck + test + strict UI audit + build — must be green before any deploy

Common Commands

# Verification (run before every merge / deploy)
pnpm verify            # typecheck + test + strict UI audit + build across all surfaces
pnpm lint              # backend contract + security guards + web/mobile lint
pnpm smoke:release     # auth + kill-switch smoke tests

# Development
pnpm --filter @bytelyst/trading-backend dev   # backend hot-reload (tsx)
pnpm --filter @bytelyst/trading-web dev       # web Vite dev server
pnpm --filter @bytelyst/trading-mobile dev    # Expo dev server

# Docker
pnpm docker:up         # production — build images, start backend + web
pnpm docker:dev        # dev overlay — hot-reload for backend and web
pnpm docker:down       # stop all containers

Backend Verification Scripts

Beyond pnpm verify, the backend has targeted contract and safety checks:

cd backend
npm run check:api-contract          # feature-flag shapes, audit events, namespace constants
npm run check:websocket-contract    # BotState lifecycle consistency
npm run check:security-guards       # tenant isolation
npm run check:tenant-isolation      # row-level access scoping
npm run check:strict-capital-guard  # capital invariant enforcement
npm run check:lifecycle-regressions # trade lifecycle regression suite

Full list in backend/package.json under scripts.

Architecture

The backend trading loop polls every POLLING_INTERVAL (default 60 s). For each user → profile → symbol it runs the 7-rule ProStrategyEngine, then routes signals through AutoTraderriskEngineTradeExecutor → exchange connector.

7-Rule Pipeline (backend/src/strategies/rules/):

  1. TrendBiasRule — EMA 50/200 trend filter
  2. SessionRule — market hours gating
  3. ZoneRule — price proximity to S/R zones
  4. MomentumRule — RSI confirmation
  5. EntryTriggerRule — EMA reclaim / pattern detection
  6. RiskManagementRule — ATR-based stop sizing
  7. AIAnalysisRule — LLM sentiment (Perplexity → OpenAI → Gemini fallback)

WebSocket namespaces (shared/realtime.ts):

  • /trading — all authenticated users; user-scoped BotState
  • /admin — admin-only; full cross-user state; non-admins rejected at connect
  • / (root) — backward-compatible default

Persistence — Azure Cosmos DB (primary) for all runtime paths. Supabase is a legacy fallback for one-off reconciliation scripts only (documented in docs/BACKEND_LEGACY_SUPABASE_SCRIPTS.md).

Documentation

Doc Purpose
docs/PRD.md Product vision, scope, and platform integration boundaries
docs/ROADMAP.md Phase tracker and implementation snapshot
docs/OPERATIONS.md Local dev, Docker, verification, staged cutover, rollback rules
docs/CONVENTIONS.md Naming, directory structure, and import boundary rules
docs/BACKEND_AUDIT_SCHEMA.md TradeAuditEvent schema and event catalogue
docs/BACKEND_API_DEPRECATION.md Full endpoint catalogue, WebSocket namespaces, deprecation policy
docs/BACKEND_LEGACY_SUPABASE_SCRIPTS.md Legacy Supabase script inventory
docs/CUTOVER_WEB.md Stage 2 — internal web adoption checklist
docs/CUTOVER_MOBILE.md Stage 3 — mobile internal beta checklist
docs/AZURE_INFRASTRUCTURE.md Azure resource and Key Vault setup

Environment Setup

Each surface has its own .env.example. The root .env.example is the comprehensive reference covering all surfaces and is used by Docker Compose and CI:

File Usage
.env.example Root — Docker Compose, CI, complete reference for all variables
backend/.env.example Copy to backend/.env — trading engine config, secrets, feature flags
web/.env.example Copy to web/.env.local — Vite build-time vars (API URLs, feature overrides)
mobile/.env.example Copy to mobile/.env.local — Expo build-time vars (API URLs)

Minimum backend variables to run locally:

Variable Required Description
COSMOS_ENDPOINT / COSMOS_KEY / COSMOS_DATABASE Yes Primary data store (see docs/AZURE_INFRASTRUCTURE.md)
PLATFORM_API_URL Yes Platform-service base URL
PLATFORM_AUTH_ENABLED true for platform JWT (RS256); false for local dev with JWT_SECRET
PLATFORM_JWT_PUBLIC_KEY or PLATFORM_JWT_JWKS_URL Prod Platform JWT verification key
JWT_SECRET Dev Legacy/local JWT secret when PLATFORM_AUTH_ENABLED=false
ALPACA_API_KEY / ALPACA_API_SECRET For trading Exchange credentials
FMP_API_KEY For research/screener Financial Modeling Prep key required by /api/research/* and /api/screener; the shared demo key is intentionally rejected by the backend
OPENAI_API_KEY For AI rules Primary LLM provider
ENABLE_TRADING Set true to enable live order execution (default false)
PAPER_TRADING Set true for paper mode
AZURE_KEYVAULT_URL Prod Enables auto-resolution of invttrdg-* secrets at startup

Financial Modeling Prep requires apikey query-string authentication, so the backend keeps all FMP calls server-side, rejects the shared demo key, caches FMP responses for 30 minutes, hashes cache keys instead of storing raw URLs, and uses redacted URL helpers for any future FMP log output.

Shared Dependencies

Package resolution is controlled by BYTELYST_PACKAGE_SOURCE through .pnpmfile.cjs.

  • common-plat (default): resolve @bytelyst/* directly from the sibling learning_ai_common_plat checkout, or from BYTELYST_COMMON_PLAT_ROOT.
  • vendor: prefer vendor/bytelyst/*, then fall back to the sibling learning_ai_common_plat checkout.

Examples:

pnpm run install:common-plat
pnpm run install:vendor
pnpm run check:packages

Override the sibling repo location with BYTELYST_COMMON_PLAT_ROOT=/path/to/learning_ai_common_plat.

Release Checklist

pnpm verify && pnpm lint && pnpm smoke:release

All three must be green. See docs/OPERATIONS.md for the full go/no-go criteria and the staged cutover sequence (backend → web → mobile → production).