Remove the silent shared demo-key fallback for FMP-backed research and screener routes, document the required key, and make backend/.env.example trackable so setup guidance has one source of truth.
Refs: docs/AUDIT_REDESIGN.md item C6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Normalize and limit /api/news symbols before proxying to Alpaca so only bounded, expected symbol characters reach the upstream news endpoint.
Refs: docs/AUDIT_REDESIGN.md item C4.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Reject unsupported /api/screener sector values before building the FMP query so only known sector labels reach the upstream stock screener.
Refs: docs/AUDIT_REDESIGN.md item C3.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Reject inline JavaScript strategy payloads before backtest execution, both at the API boundary and inside runBacktest, so saved profiles and direct internal calls cannot route unsandboxed code into replay handling.
Refs: docs/AUDIT_REDESIGN.md item C1.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add static contract coverage for the dashboard market data and research proxy routes so auth, upstream URL construction, response normalization, and FMP cache usage stay guarded by the backend test gate.
Refs: docs/AUDIT_REDESIGN.md item F6.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Centralize the HomeView research profile fetch so the ticker header and research cards share one FMP profile request, preserving the B3 company-name behavior without doubling profile traffic. Wire the FMP cache regression into the backend test script and fix the stale API-contract shared import so backend tests can run through the new cache check.
Refs: docs/AUDIT_REDESIGN.md items B2, B3, and C2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Add a 30-minute in-memory cache keyed by the complete Financial Modeling Prep upstream URL so repeated profile, metrics, earnings, and screener requests do not burn the free-tier quota. The cache keeps non-OK responses out of storage so transient rate-limit or provider errors can recover on the next request.
Refs: docs/AUDIT_REDESIGN.md item C2.
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Wires the new dashboard to real market data and adds the strategy
builder & screener UIs that were stubbed in the previous commit.
Frontend (web/src/):
- lib/marketApi.ts: authenticated fetch helpers for chart bars,
market indices, news, and FMP research endpoints
- views/HomeView.tsx: StockChart now fetches live OHLCV via
fetchChartBars on symbol/period change with loading/error states;
ResearchCards replaces the static placeholder with live FMP
profile/metrics/earnings (next-earnings + last 3 historical)
- components/layout/Header.tsx: live SPY/DIA/QQQ price + change%
via fetchMarketIndices, refreshing every 60s; removed unused
static sparkline placeholder
- components/strategy/VisualRuleBuilder.tsx: drag-and-drop IF/THEN
rule composer using @dnd-kit (RSI/MACD/EMA/Price/Volume,
above/below/crosses, BUY/SELL with shares or % of capital);
saves via POST /api/profiles
- components/strategy/CodeStrategyEditor.tsx: Monaco editor with
JS strategy template; "Run Backtest" posts to /api/backtest and
renders return/win-rate/Sharpe/drawdown plus trade log
- views/ResearchView.tsx: adds "Visual Builder" and "Code Editor"
sub-tabs alongside Strategies / Signals / Backtesting
- views/ScreenerView.tsx: live FMP screener with market-cap and
sector filters, sortable columns, click-to-load-symbol routing
- index.css: light theme background; @keyframes spin for loaders
- App.dom.test.tsx: rewritten for router-based AppShell (was
asserting on the removed tab UI; fixes 5 prior failures)
Backend (backend/src/services/apiServer.ts):
- /api/chart/bars: detects crypto symbols (contains "/") and
routes to Alpaca v1beta3/crypto/us/bars; equities use
v2/stocks/{symbol}/bars with iex feed
- (existing) /api/news, /api/market/indices, /api/research/{
profile,metrics,earnings}, /api/screener proxy endpoints
Build/config:
- web/vite.config.ts: dedupe react / react/jsx-runtime /
react-router-dom so the vendored react-auth dist resolves the
same React instance (fixes "Cannot resolve react/jsx-runtime"
Rollup error)
- web/tsconfig.app.json: exclude shared/platform-clients.ts and
shared/platform-mobile.ts (mobile-only, missing RN SDK)
- web/package.json: add react-router-dom, @monaco-editor/react,
@dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities
Verification: `npm run build` in web/ → clean (✓ built in 3s);
backend tsc --noEmit → clean. Test suite: 151/155 pass; the 4
remaining failures are pre-existing (3 useTabFeatureFlags module
cache leaks, 1 EntryForm), not introduced here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the 12-tab dashboard with a 3-column layout matching the
investing app mockup (sidebar nav, main chart area, right panel).
Web changes:
- New context/AppContext.tsx — shared botState/auth across all views
- New layout: Sidebar, Header (with market index sparklines), RightPanel
- New views: Home, Portfolio, Research, Markets, Screener, Watchlist, Alerts, Settings
- AppShell wires React Router routes to all views
- App.tsx refactored to use AppContext.Provider + BrowserRouter
Backend changes:
- 6 new proxy endpoints: /api/news, /api/market/indices,
/api/research/profile, /api/research/metrics,
/api/research/earnings, /api/screener
- config/index.ts: FMP_API_KEY env var added
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Upgrade Dockerfile base from node:18 to node:20 (fixes crypto global)
- Map host port 4025 → container 4018 (4018 taken by actiontrail)
- Join learning_ai_common_plat_default Docker network for platform service
- Switch all @bytelyst/* link: deps to registry versions
- Bump @bytelyst/llm to ^0.1.1 (adds createFallbackChain, GeminiProvider etc)
- Regenerate pnpm-lock.yaml against Gitea registry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add bootstrap.ts as new entry point — resolves Key Vault secrets via
DefaultAzureCredential before config/index.ts is evaluated, so all
process.env reads pick up KV values (Azure CLI in dev, Managed Identity
in prod). Falls back to .env if AZURE_KEYVAULT_URL is not set.
- Define INVTTRDG_SECRETS mappings for Cosmos, Azure OpenAI, product-id
- Add AZURE_OPENAI_ENDPOINT / KEY / DEPLOYMENT to config
- aiClient: prefer AzureOpenAIProvider (AI Foundry) when Azure OpenAI
config is present; falls back to direct OpenAI if not configured
- Add @azure/identity, @azure/keyvault-secrets, @bytelyst/config deps
- Update dev/start scripts to use bootstrap.ts entry point
- Document AZURE_KEYVAULT_URL and Azure OpenAI vars in .env.example
Key Vault: https://kv-mywisprai.vault.azure.net/
Secrets prefix: invttrdg-*
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Import PerplexityProvider, OpenAIProvider, GeminiProvider from @bytelyst/llm
- Use createFallbackChain() instead of manual axios fallback loop
- Remove axios and @types/axios — no longer needed
- Preserve AIClient class interface (generateAnalysis, getProviderHealth) —
no changes required in apiServer.ts or AIAnalysisRule.ts
- Fallback order still driven by config.AI.FALLBACK_LIST
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Call loadDynamicConfig() without dead supabaseService argument (Cosmos-backed).
- Use getLegacySupabaseClient() for raw .from() queries in maintenance scripts.
- manualOverrideCloseTrades: typed imports + legacy client for lifecycle SELECT.
- verify_realtime: ESM .js imports and comment for subscribeToProfiles.
- verifyTenantIsolation: comment for singleton monkey-patch.
Made-with: Cursor