phase-1: optimize code

This commit is contained in:
saikiranvella
2026-06-04 01:36:28 -04:00
committed by GitHub
parent 4ebf3e618d
commit d87f0b8427
89 changed files with 11189 additions and 845 deletions
+114
View File
@@ -0,0 +1,114 @@
# Market Screener UI
SvelteKit 5 dashboard for the [Market Screener](../market_screener) API. Provides an interactive interface for screening stocks, ETFs, and bonds — and tracking your portfolio with live hold/sell/add advice.
---
## Quick Start
This UI requires the Market Screener API running on port 3000.
```bash
# Recommended: start both from the API repo
cd ../market_screener
npm run dev # starts API (:3000) + this UI (:5173) together
# Or start the UI independently
npm install
npm run dev # http://localhost:5173
```
---
## Pages
### Screener (`/`)
- Enter any tickers (comma or space separated) and click **Screen**
- Click **📰 Catalysts** to load today's news-driven tickers and screen them automatically (one click)
- Market context strip shows live benchmarks: 10Y yield, VIX, S&P 500, P/E ratios, rate regime
- Signal Summary table ranks all assets by signal strength
- Drill-down tables for Stocks, ETFs, and Bonds with **Mkt-Adjusted** / **Graham** tab toggle
- Ticker column stays pinned while scrolling wide tables
### Portfolio (`/portfolio`)
- Reads `portfolio.json` from the API server
- Shows total value, cost basis, and unrealised G/L
- Per-holding advice: ✅ Hold & Add, 🟡 Reduce, 🔴 Sell
- If SimpleFIN is configured: net worth, account balances, 30-day spending breakdown
---
## Signals Explained
| Signal | Meaning |
|---|---|
| ✅ Strong Buy | Passes both Market-Adjusted AND Fundamental gates |
| ⚡ Momentum | Passes market-adjusted, holds fundamentally |
| ⚠️ Speculation | Passes market-adjusted, fails fundamental — priced for perfection |
| 🔄 Neutral | Hold territory in one or both lenses |
| ❌ Avoid | Fails both gates |
The **Mkt-Adjusted** tab uses gates derived from live market data (e.g. S&P P/E × 1.5 for the P/E gate). The **Graham** tab uses strict historical value-investing gates (P/E < 15×, PEG < 1.0).
---
## Tech Stack
| Layer | Choice |
|---|---|
| Framework | SvelteKit 2 + Svelte 5 |
| Build tool | Vite 6 |
| Adapter | `@sveltejs/adapter-auto` |
| Rendering | Client-side only (SSR disabled) |
| API | Proxied via Vite dev server → Fastify on :3000 |
---
## Project Structure
```
src/
app.html HTML shell
app.css Global reset + dark theme base
routes/
+layout.js ssr = false
+layout.svelte Nav bar
+page.svelte Screener page
portfolio/
+page.js load() → fetches /api/finance/portfolio
+page.svelte Portfolio + SimpleFIN page
lib/
api.js All API fetch functions
SignalBadge.svelte Signal pill component
MarketContext.svelte Benchmark strip component
vite.config.js /api proxy → localhost:3000
svelte.config.js SvelteKit config
```
---
## Configuration
### API URL
In `vite.config.js`, the Vite dev server proxies `/api/*` to `http://localhost:3000`. To point at a different API host, update the `proxy` target there.
For production, configure your reverse proxy (nginx, Caddy, etc.) to route `/api/*` to the Fastify server.
### CORS
The Fastify API allows `http://localhost:5173` by default. If you deploy the UI to a different origin, set `CLIENT_ORIGIN` in the API's `.env`:
```
CLIENT_ORIGIN=https://your-deployed-ui.example.com
```
---
## Development Notes
- Uses Svelte 5 runes: `$state`, `$derived`, `$derived.by`, `$props`
- `onclick={handler}` not `on:click` — Svelte 5 syntax
- Page data loaded via `+page.js` `load()` function, not `onMount`
- Global CSS lives in `src/app.css` — no `:global()` in component `<style>` blocks
- `asset.displayMetrics` (plain object from API) — never call `getDisplayMetrics()` in the browser