1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# Repository Guidelines
## Project Structure & Module Organization
Prism v2 is split into a FastAPI backend and a Next.js frontend.
- `backend/app/` contains the API entrypoint, Pydantic schemas, SQLite watchlist storage, and data-service logic.
- `backend/tests/` contains pytest coverage for API and watchlist behavior.
- `frontend/app/` contains the Next.js App Router pages and global styles.
- `frontend/components/`, `frontend/lib/`, and `frontend/types/` hold reusable UI, API helpers, formatting utilities, and shared TypeScript types.
- `pytest.ini` sets `backend` on `pythonpath` so tests can import `app`.
## Build, Test, and Development Commands
Backend setup and local API:
```bash
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload
```
The API runs at `http://localhost:8000`.
Frontend setup and local UI:
```bash
cd frontend
npm install
npm run dev
```
The UI runs at `http://localhost:3000`. Use `npm run build` to validate the production Next.js build and `npm run lint` to run ESLint.
Run backend tests from the repository root:
```bash
pytest
```
## Coding Style & Naming Conventions
Python code uses type hints, small FastAPI route functions, and snake_case for modules, functions, and variables. Keep service logic in `backend/app/services/` and persistence concerns in `backend/app/db/`.
TypeScript uses React function components, PascalCase component names, camelCase values, and the `@/` import alias for frontend modules. Keep shared API shapes in `frontend/types/api.ts` and formatting helpers in `frontend/lib/format.ts`. Frontend linting is configured in `frontend/eslint.config.mjs`.
## Testing Guidelines
Backend tests use pytest and should be named `test_*.py`. Prefer focused tests that mock external market-data calls with `monkeypatch`, as existing tests do. Add tests when changing FastAPI routes, watchlist persistence, or data normalization behavior. There is no frontend test runner yet, so use `npm run lint` and `npm run build` for frontend validation.
## Commit & Pull Request Guidelines
This checkout has no existing commit history. Use concise, imperative commit subjects such as `Add watchlist tests` or `Fix ticker history error handling`.
Pull requests should include a short summary, test results (`pytest`, `npm run lint`, `npm run build` when relevant), linked issues if applicable, and screenshots or screen recordings for visible UI changes. Note any required environment variables such as `FMP_API_KEY` or `FINNHUB_API_KEY`.
## Design System (`design-system/`)
The repo includes a full personal-brand design system at `design-system/`. All frontend work must follow it — never invent colors, radii, or type choices.
**Token entry point:** `design-system/colors_and_type.css` (also mirrored into `frontend/public/design-system/` for serving). Import it for all new components; it declares every CSS custom property: ink surfaces, fg tints, brass/champagne accent, oxford navy, burgundy, semantic gain/loss/caution/info colors, spacing scale, radii, shadows, and font stacks.
**Typefaces:**
- `--font-serif` — EB Garamond (variable). Display + body serif; italic at large sizes is the signature move.
- `--font-sans` — IBM Plex Sans. UI labels, eyebrows, buttons, badges.
- `--font-mono` — IBM Plex Mono. All prices, percentages, and tabular numerics (`font-variant-numeric: tabular-nums`).
**Visual rules that must not be broken:**
- Background is `#0B0E13` (ink-0), never pure black. Text is `#F2ECDC` (fg-0), never pure white.
- Primary accent is champagne `#C2AA7A` — for links, focus rings, eyebrows, button fills. Never as a large background fill.
- Semantic colors: gain `#4F8C5E`, loss `#B5494B`, caution `#C49545`, info `#4A78B5`.
- Card radius is 6px; buttons are 2px. No radius above 6px except capsule chips (999px). No bubbly rounding.
- Hairline `1px` borders only (`#232934`). No gradients except the chart area fill. No glass effects.
- Transitions are 150ms ease. No bounces, springs, or scroll-jacking.
- No emoji — ever. Use SVG icons from `design-system/assets/icons/` or unicode geometrics (`▲ ▼ ◈ ✦ ↗ ·`).
**Prism UI kit:** `design-system/ui_kits/prism/` is a forward-looking redesign showing the target component shapes: `<Sidebar>`, `<TopBar>`, `<TickerHeader>`, `<KPIStrip>`, `<ChartCard>`, `<QuoteTable>`, `<ValuationPanel>`, `<FilingsList>`, `<InsiderRow>`. Read `parts{1,2,3}.jsx` and `prism.css` before building new dashboard surfaces.
## Reference: Prism v1 (`../prism`)
The old Streamlit-based app at `../prism` is the canonical reference for finance logic being ported into v2. Do not import from it at runtime, but read it when implementing new financial features.
Key source files to consult:
- **`services/data_service.py`** — yfinance wrappers for price history, financials (income/balance/cash flow), options chain, insider transactions, SEC filings, market indices, and analyst targets. Contains `compute_ttm_ratios()` which self-computes P/E, P/B, P/S, EV/EBITDA, margins, ROE/ROA/ROIC, leverage ratios, and dividend metrics from raw quarterly statements (avoiding FMP quota). Includes outlier safeguards (e.g. P/B and EV/Sales capped at 100).
- **`services/valuation_service.py`** — DCF engine (`run_dcf()`) using Gordon Growth Model: projects FCF with median historical growth (capped ±50%, skips sign flips), computes terminal value, bridges enterprise value to equity per share via net debt/preferred equity/minority interest. Also has `run_ev_ebitda()`, `run_ev_revenue()`, `run_price_to_book()`.
- **`services/fmp_service.py`** — FMP REST calls for peers, forward analyst estimates, historical ratios, and news. Falls back to yfinance when FMP is unavailable.
- **`services/news_service.py`** — Finnhub sentiment wrapper.
- **`components/overview.py`** — signal badge logic (6 signals), 52-week range bar, short interest rendering.
- **`utils/formatters.py`** — number formatting helpers (market cap abbreviations, percent display, etc.).
**Caching strategy in v1:** `@st.cache_data` with staggered TTLs — financials at 1 h, indices at 5 min, search at 60 s. Mirror these TTLs when adding new cached endpoints in v2's `data_service.py`.
**Data source hierarchy in v1:** yfinance primary → FMP fallback → Finnhub for news/sentiment. FMP free tier is 250 req/day; `FMP_API_KEY` and `FINNHUB_API_KEY` are set via `.env`.
## Security & Configuration Tips
Do not commit API keys, local virtual environments, `node_modules/`, or generated SQLite data files. Optional market-data keys should be provided through the environment or a local `.env` file.
|