- 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>
228 lines
9.9 KiB
Markdown
228 lines
9.9 KiB
Markdown
# 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):**
|
|
```ts
|
|
// 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.ts` as 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 via `GET /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:
|
|
|
|
```ts
|
|
// 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; never `console.log` progress in the happy path.
|
|
- Never connect to real infrastructure — use in-memory fixtures only.
|
|
- Wire into `package.json` scripts as `check:*` and into `npm run test` or `npm run lint`.
|