diff options
| author | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-30 00:16:53 -0700 |
|---|---|---|
| committer | Tyler Hoang <tyler@tylerhoang.xyz> | 2026-05-30 00:16:53 -0700 |
| commit | 66acc6f7d18c93f4b7960682bea5bd5ff1545802 (patch) | |
| tree | c34458c8e53470cf80b32ec15c16f5940ebcb954 /AGENTS.md | |
| parent | 2222d8a5fac6850d7d924e9404a44a65cb10f68f (diff) | |
docs: tighten README, AGENTS, CLAUDE with production deploy instructions
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS.md')
| -rw-r--r-- | AGENTS.md | 115 |
1 files changed, 46 insertions, 69 deletions
@@ -1,100 +1,77 @@ # Repository Guidelines -## Project Structure & Module Organization +## Structure -Prism v2 is split into a FastAPI backend and a Next.js frontend. +- `backend/app/` — FastAPI entrypoint (`main.py`), Pydantic schemas, `services/data_service.py` (yfinance + TTL cache), `db/watchlist.py` (SQLite). +- `backend/tests/` — pytest. `pytest.ini` puts `backend/` on `pythonpath`. +- `frontend/app/` — Next.js App Router. `frontend/components/`, `frontend/lib/`, `frontend/types/api.ts` (shared types — keep in sync with `backend/app/schemas.py`). +- `systemd/`, `nginx/` — production deployment templates. +- `design-system/` — brand tokens (`colors_and_type.css`) and Prism UI kit. Mirrored into `frontend/public/design-system/`. -- `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: +## Development ```bash -cd backend -python -m venv .venv -source .venv/bin/activate +# Backend (port 8001) +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 -``` +uvicorn app.main:app --reload --host 127.0.0.1 --port 8001 -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. +# Frontend (port 3001) +cd frontend && npm install +NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8001 npm run dev -- --hostname 127.0.0.1 --port 3001 -Run backend tests from the repository root: - -```bash +# Tests + lint pytest +cd frontend && npm run lint && npm run build ``` -## Coding Style & Naming Conventions +## Production -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/`. +Topology: uvicorn on `127.0.0.1:8001`, `next start` on `127.0.0.1:3001`, nginx TLS reverse-proxy (`/api/` → backend, `/` → frontend). See `README.md` for the full deploy and redeploy commands. Service user is `www-data`; code lives at `/var/www/prism-v2/`. -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`. +Redeploy in one shot: -## Testing Guidelines +```bash +cd /var/www/prism-v2 && sudo -u www-data git pull origin master +sudo -u www-data backend/.venv/bin/pip install -r backend/requirements.txt +sudo -u www-data env HOME=/var/www/prism-v2/frontend NPM_CONFIG_CACHE=/var/www/prism-v2/frontend/.npm npm --prefix frontend ci +sudo -u www-data env HOME=/var/www/prism-v2/frontend NPM_CONFIG_CACHE=/var/www/prism-v2/frontend/.npm npm --prefix frontend run build +sudo systemctl restart prismv2-backend.service prismv2-frontend.service +``` -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. +## Coding Style -## Commit & Pull Request Guidelines +- Python: type hints, snake_case, small route functions. Service logic under `backend/app/services/`, persistence under `backend/app/db/`. +- TypeScript: React function components, PascalCase components, camelCase values, `@/` alias. Shared API shapes in `frontend/types/api.ts`; formatters in `frontend/lib/format.ts`. -This checkout has no existing commit history. Use concise, imperative commit subjects such as `Add watchlist tests` or `Fix ticker history error handling`. +## Testing -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`. +Backend tests are `test_*.py` under `backend/tests/`. Stub `data_service` with `monkeypatch` — never hit live yfinance. Use `tmp_path` for any test that touches SQLite. No frontend test runner; rely on `npm run lint` and `npm run build`. -## Design System (`design-system/`) +## Commits & PRs -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. +Concise imperative subjects (`Add watchlist tests`, `Fix history error handling`). PRs include: short summary, `pytest`/`npm run lint`/`npm run build` results, UI screenshots when relevant, and any env vars touched. -**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. +## Design System -**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`). +All frontend work must follow `design-system/`. Import `design-system/colors_and_type.css` (CSS custom properties for ink/fg/champagne/semantic colors, spacing, radii, fonts). Hard rules: -**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 (`▲ ▼ ◈ ✦ ↗ ·`). +- Background `#0B0E13`, text `#F2ECDC` — never pure black/white. +- Champagne `#C2AA7A` for links/focus/eyebrows/buttons; never a large background. +- Semantic: gain `#4F8C5E`, loss `#B5494B`, caution `#C49545`, info `#4A78B5`. +- Card radius 6px, button radius 2px, capsule chips 999px. Nothing else rounded. +- Hairline `1px` borders only (`#232934`). No gradients except chart fill. No glass effects. +- Fonts: `--font-serif` EB Garamond (display/body), `--font-sans` IBM Plex Sans (UI), `--font-mono` IBM Plex Mono (all numerics, with `font-variant-numeric: tabular-nums`). +- 150ms ease transitions. No bounces. No emoji — use SVGs in `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. +Read `design-system/ui_kits/prism/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`. +Read-only reference for finance logic — do not import at runtime. Key files: `services/data_service.py` (TTM ratios, options, filings), `services/valuation_service.py` (`run_dcf`, `run_ev_ebitda`, `run_ev_revenue`, `run_price_to_book`), `services/fmp_service.py`, `services/news_service.py`, `components/overview.py` (signal badges, 52w range, short interest), `utils/formatters.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`. +v1 caching TTLs to mirror: financials 1 h, indices 5 min, search 60 s. Data hierarchy: yfinance → FMP fallback → Finnhub for sentiment. -## Security & Configuration Tips +## Security -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. +Never commit API keys, `.env`, `node_modules/`, `backend/.venv/`, or `backend/data/prism.db`. Optional keys (`FMP_API_KEY`, `FINNHUB_API_KEY`) come from `.env` or the environment. |
