# 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

```bash
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

```bash
# 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:

```bash
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 `AutoTrader` → `riskEngine` → `TradeExecutor` → 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:

```bash
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

```bash
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).
