Deployment Spec — trading.boas.dev

Date: 2026-04-16

Status: Approved design — ready for implementation planning

Owner: Plutus (coordinator), Apollo (frontend), Proteus (infrastructure)


Decision Summary

DecisionChoice
Domaintrading.boas.dev (dedicated subdomain)
Frontend hostingCloudflare Pages
API proxy hostingVPS (Hostinger) behind Cloudflare Tunnel
API domainapi.trading.boas.dev (tunnel route)
Demo modeSingle app, data source fallback — bundled demo JSON when API/R2 unreachable
TradingView MCPNot adopted — no Pine scripts. Webhooks remain primary TV integration.

Architecture

                     ┌─────────────────────────────────┐
                     │        Cloudflare Edge           │
                     │                                  │
   Browser ──────────┤  trading.boas.dev ──► CF Pages   │
                     │  api.trading.boas.dev ──► Tunnel │
                     └──────────┬───────────────────────┘
                                │ tunnel
                     ┌──────────▼───────────────────────┐
                     │        Hostinger VPS              │
                     │                                  │
                     │  :8100 FastAPI proxy              │
                     │    └── Alpaca Paper API           │
                     │    └── SQLite (trading.db joins)  │
                     │                                  │
                     │  :5678 n8n (trading-spoke)        │
                     │    └── R2 writes (pipelines)      │
                     └──────────────────────────────────┘

   Data sources:
     Static pages  ──► R2 JSON (fallback: public/data/demo/*.json)
     Live pages    ──► FastAPI proxy (fallback: public/data/demo/*.json)
     Market page   ──► TradingView widgets (always live, no auth)

Frontend — React App

Stack

Already scaffolded at apps/dashboard/:

Design System

Apollo's HTML mockups define the visual language. The existing scaffold uses generic Tailwind

classes — this must be replaced with the mockup design system:

The mockups are the source of truth for visual design. React components must match them

pixel-for-pixel in layout, color, and typography.

Reference mockups:

Pages

RouteData Source (live)Data Source (demo)Key Components
/R2: market summarydemo/overview.jsonP&L card, position count, thesis, last alert, status indicator
/positionsAPI: /api/positions + /api/accountdemo/positions.jsonPosition table, risk badges, account summary bar
/strategyR2: thesis JSONdemo/strategy.jsonCurrent thesis, bias assessment, watchlist signals
/analyticsAPI: /api/history + R2: performancedemo/analytics.jsonEquity curve (Recharts), drawdown chart, metrics cards
/logR2: trade log JSONdemo/trade-log.jsonTrade list with decision chains, Lightweight Charts
/alertsR2: watchdog alertsdemo/alerts.jsonAlert feed, L1/L2/L3 classification, filter controls
/marketTradingView widgets (always live)Same — widgets need no authEmbedded TradingView widgets, VIX via VIXY proxy

Demo Data Fallback

Each data-fetching hook follows this pattern:

async function fetchWithFallback<T>(url: string, demoPath: string): Promise<T> {
  try {
    const res = await fetch(url)
    if (!res.ok) throw new Error(res.statusText)
    return await res.json()
  } catch {
    const demo = await fetch(demoPath)
    return await demo.json()
  }
}

Demo JSON files live in public/data/demo/ and ship with the build. They contain

realistic placeholder data matching the API response schemas.

Environment Variables

VariableDevProduction
VITE_API_URLhttp://localhost:8100https://api.trading.boas.dev
VITE_R2_URL(empty — use demo data)R2 public bucket URL

Build & Deploy

cd apps/dashboard
npm install
npm run build          # outputs to dist/
# CF Pages picks up dist/ via git push or wrangler pages deploy

CF Pages project name: trading-dashboard

Custom domain: trading.boas.dev

Build command: cd apps/dashboard && npm install && npm run build

Build output directory: apps/dashboard/dist

SPA routing: add _redirects file or [[redirects]] in wrangler.toml:

/* /index.html 200

Backend — FastAPI Proxy

Already Built (apps/api/main.py)

3 endpoints implemented:

Needs Completion

Per the FastAPI proxy spec (04_launch/fastapi-proxy-spec.md):

1. GET /api/history — equity curve from Alpaca portfolio history API

- Computed fields: P&L, high watermark, max drawdown

- Query params: period, timeframe

2. Computed fields on /positions — stop_level, target_level, risk_badge

- Requires SQLite join against trade_log table

- Currently returns 0 for stop/target

3. Computed fields on /account — daily P&L, exposure %, drawdown status

- Currently returns raw Alpaca data without enrichment

4. CORS update — add https://trading.boas.dev to allowed origins

5. Error handling — per spec (503 for auth failure, 429 passthrough, 502/504)

6. Env var alignment — use ALPACA_API_KEY_ID / ALPACA_API_SECRET_KEY (nono profile names),

not ALPACA_API_KEY / ALPACA_SECRET_KEY (current code)

Deployment


Infrastructure — Proteus Scope

1. CF Pages project — create trading-dashboard project, wire trading.boas.dev CNAME

2. Tunnel route — add api.trading.boas.devlocalhost:8100 to existing CF Tunnel config

3. FastAPI systemd service — create unit file, deploy apps/api/ to VPS

4. R2 public access — configure public read for the plutus-trading bucket (or proxy via Worker)


Work Distribution (War Room)

AgentDeliverable
ApolloConvert 7 HTML mockups → React components. Match mockup design system exactly. Wire data fetching hooks with demo fallback.
ProteusCF Pages project + DNS. Tunnel route for api.trading.boas.dev. FastAPI systemd service on VPS. R2 public read config.
Trading-spokeActivate R2 writes in Market Data Pipeline + Trade Log Pipeline (currently stubbed).
PlutusCreate demo JSON fixtures. Complete FastAPI proxy (history endpoint, computed fields, CORS). Coordinate and verify.

Not In Scope (This Spec)