- shared/realtime.ts: add SOCKET_NAMESPACES constants (/trading, /admin, root) - shared/feature-flags.ts: add tabs.marketplace and tabs.membership to TradingFeatureFlagsResponse; add FEATURE_FLAG_KEYS constants - .env.example: remove /api suffix from VITE/NEXT_PUBLIC trading URL vars (web appends /api itself); add tab visibility flag vars with comments - web: add useTabFeatureFlags hook + DOM test; wire tab visibility into App.tsx - web/vite.config.ts: finalize build config - mobile/providers/TradingDataProvider.tsx: deriveSocketParams for proxy-safe socket origin/path resolution (already landed upstream, conflict resolved) - docs: add CUTOVER_WEB.md, CUTOVER_MOBILE.md checklists; update OPERATIONS.md with Docker commands and resolved gap log; update ROADMAP.md to Done; add BACKEND_AUDIT_SCHEMA.md, BACKEND_API_DEPRECATION.md, CONVENTIONS.md; add audit-events container entry to AZURE_INFRASTRUCTURE.md - README.md: full rewrite with workspace table, arch summary, env var reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9.9 KiB
Repository Conventions
Purpose
This document defines naming conventions, directory structure rules, and import boundaries
for learning_ai_invt_trdg. It is the authoritative reference for where code lives and
what each package is allowed to import.
Package Names
| Package | Name in package.json |
pnpm --filter alias |
|---|---|---|
| Backend | @bytelyst/trading-backend |
trading-backend |
| Web | @bytelyst/trading-web |
trading-web |
| Mobile | @bytelyst/trading-mobile |
trading-mobile |
| Shared | @bytelyst/trading-shared (internal — not published) |
— |
Directory Structure
learning_ai_invt_trdg/
├── backend/
│ ├── src/
│ │ ├── backtest/ # Backtesting engine and guards
│ │ ├── config/ # Environment config loader (config/index.ts is the only place process.env is read)
│ │ ├── connectors/ # Exchange connectors (Alpaca, CCXT) + factory
│ │ ├── domain/ # Trading domain enums, value types, and pure domain logic
│ │ ├── repositories/ # Cosmos DB data-access layer (one file per entity)
│ │ ├── scripts/ # Internal one-time scripts and verification contracts (not imported by src/)
│ │ ├── services/ # Application services (apiServer, TradeExecutor, aiClient, etc.)
│ │ ├── strategies/ # 7-rule ProStrategyEngine and individual rule implementations
│ │ └── utils/ # Generic utilities (logger, symbolMapper, etc.)
│ ├── *.ts # Root-level verification / reconciliation scripts (not part of the runtime)
│ └── package.json
├── web/
│ └── src/
│ ├── backtest/ # Backtest feature: hook, flags, UI components
│ ├── components/ # Shared React components (AuthContext, Login, ChatControl, etc.)
│ ├── hooks/ # React hooks (useWebSocket, useTabFeatureFlags, etc.)
│ ├── lib/ # Utility modules: authSession, runtime, profileApi, etc.
│ ├── tabs/ # Top-level tab components (one file per tab)
│ ├── test/ # Vitest test setup and fixtures
│ ├── App.tsx # Root component: tab routing, auth gate, feature flags
│ └── main.tsx # Vite entry point
├── mobile/
│ ├── app/ # Expo Router file-based routes
│ │ ├── (tabs)/ # Tab screens: index, positions, history, strategies, settings
│ │ ├── _layout.tsx # Root layout (auth gate, kill-switch)
│ │ ├── chat.tsx # AI chat surface
│ │ └── marketplace.tsx # Marketplace surface
│ ├── components/ # React Native shared components
│ ├── hooks/ # React Native hooks
│ ├── lib/ # runtime, telemetry, authSession equivalents
│ ├── providers/ # MobileAuthProvider, TradingDataProvider
│ └── utils/ # Utility functions
├── shared/ # Cross-surface constants and TypeScript interfaces
│ ├── feature-flags.ts # TradingFeatureFlagsResponse, TabFeatureFlags, BacktestFeatureFlags
│ ├── realtime.ts # SOCKET_NAMESPACES, buildTradingSocketOptions, isUnauthorizedSocketError
│ ├── request-id.ts # createRequestId()
│ ├── runtime.ts # getRuntimeEnvironment()
│ ├── product.ts # productConfig — canonical product identity
│ ├── control-plane.ts # Control-plane state types
│ ├── platform-web.ts # Web-specific platform helpers
│ └── platform-mobile.ts # Mobile-specific platform helpers
├── docs/ # All project documentation
├── scripts/ # Root-level build/verify scripts
└── vendor/ # Local vendored @bytelyst/* packages (symlinked or copied)
Import Boundary Rules
Rule 1 — shared/ is the only cross-surface code
No surface may import directly from another surface's src/.
| Importer | May import from |
|---|---|
backend/src/ |
shared/, vendor/bytelyst/*, npm packages |
web/src/ |
shared/, vendor/bytelyst/*, npm packages |
mobile/ |
shared/, vendor/bytelyst/*, npm packages |
shared/ |
npm packages only — never from backend, web, or mobile |
Violation example (never do this):
// In web/src — WRONG
import { TradeExecutor } from '../../../backend/src/services/TradeExecutor.js';
Rule 2 — config/index.ts is the only process.env reader in the backend
All environment variable access in backend/src/ goes through config/index.ts.
No other file calls process.env directly. This makes the config surface auditable
and testable in isolation.
Rule 3 — domain/ contains no I/O
backend/src/domain/ is pure TypeScript: enums, value types, and functions with no
database calls, no HTTP, and no filesystem access. It may be imported by any other
backend module.
Rule 4 — repositories/ only talk to Cosmos
backend/src/repositories/ (or services/*Repository.ts) are the only files that
import @azure/cosmos or call Cosmos client methods. Services and strategies call
repositories; they do not call Cosmos directly.
Rule 5 — scripts/ are not imported at runtime
backend/src/scripts/ contains verification contracts (e.g., verifyWebsocketContract.ts)
that run as standalone processes. They are never import-ed by backend/src/index.ts
or any other runtime module. Root-level backend/*.ts scripts follow the same rule.
Rule 6 — shared/ exports must be serialisable
Everything exported from shared/ must be importable in all three environments:
Node.js (backend), browser (web), and React Native (mobile). No Node.js built-ins,
no DOM APIs, no React Native-specific APIs.
Rule 7 — Trading domain logic stays in the backend
No trading strategy logic, risk rules, capital guard calculations, or execution logic
may be moved into shared/, web/, or mobile/. Backend is authoritative.
Naming Conventions
Files
| Context | Convention | Example |
|---|---|---|
| TypeScript source | camelCase.ts |
apiServer.ts, healthTracker.ts |
| React components | PascalCase.tsx |
OverviewTab.tsx, AuthContext.tsx |
| React hooks | use prefix, camelCase.ts |
useWebSocket.ts, useTabFeatureFlags.ts |
| Test files | .test.ts / .test.tsx |
App.dom.test.tsx |
| Verification scripts | verify*.ts / test*.ts |
verifyApiContract.ts |
| Docs | SCREAMING_SNAKE.md |
CONVENTIONS.md, OPERATIONS.md |
Identifiers
| Context | Convention | Example |
|---|---|---|
| Classes | PascalCase |
ApiServer, TradeExecutor |
| Interfaces / types | PascalCase |
TradingFeatureFlagsResponse, BotState |
| Constants (module-level) | SCREAMING_SNAKE_CASE |
SOCKET_NAMESPACES, BACKTEST_FLAG_KEYS |
| Functions | camelCase |
buildTradingSocketOptions, createRequestId |
| React components | PascalCase |
OverviewTab, LivePulseTicker |
| Environment variables | SCREAMING_SNAKE_CASE |
COSMOS_ENDPOINT, TAB_MARKETPLACE_ENABLED |
API Endpoints
| Scope | Prefix | Auth |
|---|---|---|
| Public product API | /api/ |
requireAuth (platform JWT) |
| Internal operator tooling | /internal/ |
requireAuth — firewall-restrict in prod |
| Admin-only mutations | /api/admin/ |
requireAuth + requireAdmin |
| Health / observability | /health, /metrics |
None — firewall-restrict in prod |
Socket.IO Events (backend → client)
| Event | Payload type | Notes |
|---|---|---|
state |
BotState |
Full state on connect |
symbol_update |
{ symbol, data } |
Per-symbol signal/indicator update |
positions_update |
Position[] |
Full position list replacement |
orders_update |
Order[] |
Full order list replacement |
history_update |
HistoryRow |
Single new closed trade |
new_alert |
Alert |
Single new alert |
health_update |
HealthSnapshot |
Loop health and trading control state |
account_snapshot |
AccountSnapshot |
Exchange account balance snapshot |
order_failure |
OrderFailureRecord |
Single order failure notification |
operational_event |
OperationalEvent |
Structured operational log entry |
operational_event_cleared |
— | Signals log has been cleared |
Feature Flag Conventions
- Feature flags are defined in
shared/feature-flags.tsas TypeScript interfaces. - Flag key constants (
BACKTEST_FLAG_KEYS,TAB_FLAG_KEYS) are the single source of truth for env var names — never hardcode the string elsewhere. - Backend reads env vars via
config/index.ts; web/mobile read viaGET /api/feature-flags. - Admin accounts bypass all feature flags — they always see everything.
- New flags default to enabled (opt-out model) unless gating a genuinely unreleased feature.
Request Tracing Convention
Every HTTP request from web or mobile must include:
x-request-id: <createRequestId('surface-context')>
Authorization: Bearer <accessToken>
Backend echoes x-request-id in all responses. Use this header as the primary correlation
key when tracing a request across client logs and backend logs.
Test / Verification Script Convention
Backend verification scripts follow this pattern:
// verify*.ts or test*.ts at backend/ root or backend/src/scripts/
import assert from 'node:assert/strict';
function main() {
// ... assertions ...
console.log('[PASS] Description of what passed.');
}
main();
- Exit with a non-zero code on
AssertionError(Node.js default behaviour). - Print
[PASS] ...on success; neverconsole.logprogress in the happy path. - Never connect to real infrastructure — use in-memory fixtures only.
- Wire into
package.jsonscripts ascheck:*and intonpm run testornpm run lint.