From a85dc0f4b9148d945fba6b8ef751ed2139e887ab Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Wed, 10 Jun 2026 00:28:09 -0700 Subject: Simplify deploy script and docs --- README.md | 153 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 76 insertions(+), 77 deletions(-) (limited to 'README.md') diff --git a/README.md b/README.md index cf2eecb..8e35ef2 100644 --- a/README.md +++ b/README.md @@ -1,134 +1,133 @@ # Prism v2 -Financial overview app. FastAPI backend (yfinance + SQLite watchlist) and Next.js frontend (Plotly chart, ticker search, market bar, watchlist). +Financial overview app with a FastAPI backend and a Next.js frontend. ## Stack - Backend: Python 3.14+, FastAPI, uvicorn, yfinance, SQLite -- Frontend: Node 20+, Next.js (App Router), TypeScript -- Production: systemd + nginx (TLS via certbot) +- Frontend: Node 20+, Next.js App Router, TypeScript ## Layout - `backend/app/` — FastAPI app, services, SQLite watchlist +- `backend/tests/` — pytest suite - `frontend/app/` — Next.js App Router; shared types in `frontend/types/api.ts` -- `systemd/` — service units (`prismv2-backend.service`, `prismv2-frontend.service`) -- `nginx/` — TLS server block (`/api/` → :8001, `/` → :3001) -- `scripts/stack.sh` — local dev start/stop/restart/status +- `scripts/deploy.sh` — installs dependencies and builds the app for running +- `scripts/stack.sh` — local dev start/stop/restart/status helper +- `systemd/`, `nginx/` — optional reference templates if you want to wire the app into your own server setup - `design-system/` — brand tokens + Prism UI kit (mirrored to `frontend/public/design-system/`) -## Environment +## Quick Start -Copy `.env.example` → `.env`. Current feature set works without keys. +### 1. Clone the repo -- `NEXT_PUBLIC_API_BASE_URL` — leave empty in production (same-origin `/api/*` via nginx) -- `FMP_API_KEY`, `FINNHUB_API_KEY` — reserved for future enrichment +```bash +git clone +cd prism-v2 +``` -## Local Development +### 2. Optional environment setup ```bash -# Backend -cd backend && python -m venv .venv && .venv/bin/pip install -r requirements.txt -.venv/bin/uvicorn app.main:app --reload --host 127.0.0.1 --port 8001 - -# Frontend -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 +cp .env.example .env ``` -Or use `./scripts/stack.sh {start|stop|restart|status}` (logs in `.run/logs/`). +Current features work without API keys. -## API +- `NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8001` for local frontend-to-backend requests +- `FMP_API_KEY` and `FINNHUB_API_KEY` are optional -- `GET /health` -- `GET /api/search?q=` -- `GET /api/market/indices` -- `GET /api/tickers/{symbol}/overview` -- `GET /api/tickers/{symbol}/history?period=1m|3m|6m|1y|5y` -- `GET|POST|DELETE /api/watchlist[/{symbol}]` (uppercase, capped at 10) +### 3. Run the backend + +```bash +python -m venv backend/.venv +backend/.venv/bin/pip install -r backend/requirements.txt +backend/.venv/bin/uvicorn app.main:app --reload --host 127.0.0.1 --port 8001 --app-dir backend +``` + +Backend health check: -SQLite lives at `backend/data/prism.db`. Backend seeds a `default` profile on startup. +```bash +curl http://127.0.0.1:8001/health +``` -## Production Deployment +### 4. Run the frontend -Target topology: +```bash +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 +``` -- Bare repo at `/srv/git/prism-v2.git` (push target) -- Working tree at `/var/www/prism-v2/` owned by `www-data` (no `.git/` — populated by post-receive hook via `git --work-tree=... checkout -f`) -- Backend on `127.0.0.1:8001`, frontend on `127.0.0.1:3001` -- nginx terminates TLS and reverse-proxies `/api/` → backend, `/` → frontend +Open `http://127.0.0.1:3001`. -Workflow: `git push prod master` on your laptop → post-receive hook checks out the tree into `/var/www/prism-v2/` and runs `scripts/deploy.sh`, which builds + restarts. +### 5. Optional one-command build prep -### First-time setup +If you want the repo to prepare dependencies and build artifacts for you: ```bash -# 1. Create bare repo -sudo mkdir -p /srv/git && sudo git init --bare /srv/git/prism-v2.git +./scripts/deploy.sh +``` -# 2. Create working tree dir -sudo install -d -o www-data -g www-data /var/www/prism-v2 +This script: -# 3. Push from your laptop so the working tree gets populated -# (add the remote on your laptop: git remote add prod user@host:/srv/git/prism-v2.git) -# git push prod master +- creates `backend/.venv` if needed +- installs backend requirements +- runs `npm ci` in `frontend/` +- runs `npm run build` in `frontend/` -# 4. On the server: install systemd units + nginx site + build + start -cd /var/www/prism-v2 -sudo ./scripts/deploy.sh --install +It does not start services, install `systemd`, configure `nginx`, or manage deployment hooks. -# 5. First-time TLS (Certbot edits the nginx server block in-place) -sudo certbot --nginx -d prism.tylerhoang.xyz -sudo systemctl reload nginx +## Running The Stack -# 6. Install the post-receive hook so future pushes auto-deploy -sudo cp /var/www/prism-v2/scripts/post-receive.sample /srv/git/prism-v2.git/hooks/post-receive -sudo chmod +x /srv/git/prism-v2.git/hooks/post-receive +### Development mode -# 7. Sudoers entry so the git-push user can run deploy.sh without a password -# (replace GIT_USER with the account that owns /srv/git or receives the push) -echo 'GIT_USER ALL=(root) NOPASSWD: /var/www/prism-v2/scripts/deploy.sh' | sudo tee /etc/sudoers.d/prism-v2-deploy -sudo chmod 0440 /etc/sudoers.d/prism-v2-deploy -``` +Run these in separate terminals: -### Subsequent deploys +```bash +backend/.venv/bin/uvicorn app.main:app --reload --host 127.0.0.1 --port 8001 --app-dir backend +NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8001 npm --prefix frontend run dev -- --hostname 127.0.0.1 --port 3001 +``` -From your laptop: +Or use: ```bash -git push prod master # post-receive hook checks out + runs deploy.sh +./scripts/stack.sh start ``` -Manual deploy on the server (e.g. retry after a failed build, or to refresh systemd/nginx): +### Production-style local run + +Build first, then run: ```bash -cd /var/www/prism-v2 -sudo ./scripts/deploy.sh # build + restart + smoke check -sudo ./scripts/deploy.sh --install # also refresh systemd units / nginx site +./scripts/deploy.sh +backend/.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8001 --app-dir backend +NEXT_PUBLIC_API_BASE_URL=http://127.0.0.1:8001 npm --prefix frontend run start -- --hostname 127.0.0.1 --port 3001 ``` -`deploy.sh` is idempotent: ensures ownership, builds the backend venv and `npm ci && npm run build` as `www-data` (with `HOME` + `NPM_CONFIG_CACHE` set), restarts both services, and curls `/health` and `/` before exiting. It does NOT touch git — the post-receive hook owns checkout. +If you put Prism behind a reverse proxy, leave `NEXT_PUBLIC_API_BASE_URL` empty so browser requests use same-origin `/api/*`. -### Ops +## API -```bash -sudo systemctl status prismv2-backend.service prismv2-frontend.service --no-pager -sudo journalctl -u prismv2-backend.service -f -sudo journalctl -u prismv2-frontend.service -f +- `GET /health` +- `GET /api/search?q=` +- `GET /api/market/indices` +- `GET /api/tickers/{symbol}/overview` +- `GET /api/tickers/{symbol}/history?period=1m|3m|6m|1y|5y` +- `GET|POST|DELETE /api/watchlist[/{symbol}]` -curl -i http://127.0.0.1:8001/health -curl -i https://prism.tylerhoang.xyz/api/search?q=AAPL -``` +SQLite lives at `backend/data/prism.db`. The backend seeds a `default` profile on startup. ## Verification ```bash -pytest # backend tests (pytest.ini sets pythonpath) -cd frontend && npm run lint && npm run build +backend/.venv/bin/pytest +npm --prefix frontend run lint +npm --prefix frontend run build ``` -## Production Rules +## Notes -- Do not hardcode a localhost API base in frontend browser code. `frontend/lib/api.ts` must default to empty so the browser hits same-origin `/api/*`. +- Browser code should not hardcode a localhost API base. `frontend/lib/api.ts` should default to empty so browser requests can use same-origin `/api/*` when you deploy behind your own proxy. - Never commit `.env`, `node_modules/`, `backend/.venv/`, or `backend/data/prism.db`. -- Watchlist is normalized to uppercase and capped at 10 symbols. +- Watchlist symbols are normalized to uppercase and capped at 10. -- cgit v1.3-2-g0d8e