Skip to content

ProdigyTom/stocks

Repository files navigation

PaperTrade

A paper trading app — invest fake money in real stocks using live market data. Track your portfolio, research stocks with historical price charts, and practice trading without any financial risk.

Features

  • Google SSO — sign in with your Google account; each account gets its own independent portfolio
  • Portfolio dashboard — view all your holdings with live prices, 24h change, and total P&L
  • Stock search — search any US equity by name or ticker symbol
  • Stock detail page — interactive price history chart (1D / 5D / 1M / 3M / 1Y ranges) with buy and sell forms
  • Buy & sell — whole shares only; trades execute at the live market price
  • Deposit fake money — add up to $1,000,000 to your account at any time (new accounts start with $1,000)
  • Transaction history — paginated log of every buy, sell, and deposit
  • Price caching — stock prices are cached server-side for 5 minutes to stay within API limits

Tech stack

Layer Technology
Framework Next.js 16 (App Router)
Language TypeScript
Styling Tailwind CSS
Database SQLite via Prisma 7 + libsql adapter
Auth NextAuth v5 (Google OAuth, JWT sessions)
Stock data yahoo-finance2 (no API key required)
Charts Recharts
Unit tests Vitest + Testing Library
E2E tests Playwright

Running locally

Prerequisites

1. Clone and install

git clone <repo-url>
cd stocks
npm install

2. Configure environment variables

Copy .env and fill in your values:

cp .env .env.local
DATABASE_URL="file:./prisma/dev.db"

AUTH_SECRET="<generate with: openssl rand -base64 32>"
AUTH_GOOGLE_ID="<your Google client ID>"
AUTH_GOOGLE_SECRET="<your Google client secret>"

3. Set up Google OAuth

In your Google Cloud Console, add these to your OAuth 2.0 client:

Authorised JavaScript origins:

http://localhost:3000

Authorised redirect URIs:

http://localhost:3000/api/auth/callback/google

4. Set up the database

npx prisma migrate dev

This creates prisma/dev.db and runs all migrations.

5. Start the dev server

npm run dev

Open http://localhost:3000. You'll be redirected to the login page — sign in with Google to get started.


Available scripts

Command Description
npm run dev Start the development server with hot reload
npm run build Build for production
npm run start Start the production server (requires a build first)
npm test Run all unit tests
npm run test:watch Run unit tests in watch mode
npm run test:coverage Run unit tests with coverage report
npm run test:e2e Run end-to-end tests (requires a production build)
npm run test:e2e:ui Open Playwright's interactive test runner

Running tests

Unit tests

Unit tests use Vitest and mock all external dependencies (database, Yahoo Finance). No server or network access needed.

npm test

68 tests covering:

  • Stock data library (cache hit/miss, history, search)
  • All API route handlers (auth guards, validation, business logic)

End-to-end tests

E2E tests use Playwright and run against a real local server with a separate test database (prisma/test.db).

Step 1 — build the app:

npm run build

Step 2 — run the tests:

npm run test:e2e

The test suite will:

  1. Run Prisma migrations against prisma/test.db
  2. Seed a test user (test@papertrade.dev, $10,000 starting balance)
  3. Authenticate via the test credentials provider (only active outside production)
  4. Run all specs: auth redirects, portfolio, deposit, search, buy, sell, transactions

To open the interactive Playwright UI instead:

npm run test:e2e:ui

Project structure

src/
├── app/
│   ├── page.tsx                    # Portfolio dashboard
│   ├── login/page.tsx              # Login page
│   ├── stock/[ticker]/page.tsx     # Stock detail + chart + trade form
│   ├── search/page.tsx             # Stock search
│   ├── transactions/page.tsx       # Transaction history
│   └── api/
│       ├── auth/[...nextauth]/     # NextAuth handlers
│       ├── portfolio/              # GET portfolio + live prices
│       ├── trade/                  # POST buy/sell
│       ├── deposit/                # POST add fake money
│       ├── transactions/           # GET paginated history
│       └── stocks/
│           ├── quote/              # GET current price (cached)
│           ├── history/            # GET OHLC time series
│           └── search/             # GET symbol search
├── components/
│   ├── Header.tsx                  # Navigation bar
│   ├── StockChart.tsx              # Recharts area chart
│   ├── TradeForm.tsx               # Buy/sell form
│   ├── DepositModal.tsx            # Add funds modal
│   └── Providers.tsx               # SessionProvider wrapper
├── lib/
│   ├── db.ts                       # Prisma client singleton
│   └── stocks.ts                   # Yahoo Finance wrapper + price cache
├── auth.ts                         # Full NextAuth config (Node.js)
├── auth.config.ts                  # Lightweight auth config (Edge-safe)
└── proxy.ts                        # Next.js 16 middleware (route protection)

prisma/
├── schema.prisma                   # Database schema
├── migrations/                     # SQL migration history
├── dev.db                          # Development database
└── test.db                         # Test database (created on first test run)

tests/
├── unit/
│   ├── lib/stocks.test.ts
│   └── api/
│       ├── portfolio.test.ts
│       ├── trade.test.ts
│       ├── deposit.test.ts
│       ├── transactions.test.ts
│       └── stocks-routes.test.ts
└── e2e/
    ├── global.setup.ts             # DB seed + auth setup
    ├── seed.ts                     # Test user seeder
    ├── auth.spec.ts
    ├── portfolio.spec.ts
    ├── trade.spec.ts
    └── transactions.spec.ts

Database schema

Table Purpose
User Account with cash balance (default $1,000)
Account OAuth provider accounts (managed by NextAuth)
Session Auth sessions (managed by NextAuth)
Portfolio Current stock holdings per user
Transaction Immutable log of every BUY, SELL, and DEPOSIT
PriceCache Server-side cache of stock quotes (5-minute TTL)

AI Advisor (Phase 2)

A floating chat widget available on every page, powered by Google Gemini 2.0 Flash.

The bot has access to four tools it calls automatically as needed:

Tool What it does
get_stock_quote Live price, daily change, open/high/low
get_stock_history Price trend summary for a given time range
get_stock_news Recent news articles via Yahoo Finance search
get_portfolio User's current holdings and cash balance

The bot always knows your portfolio context but won't limit suggestions to stocks you can currently afford — you can always deposit more or sell existing positions.

Adding more news sources: Open src/lib/gemini.ts and append a new entry to the newsSources array. Each source is just an async function (query: string) => Promise<NewsArticle[]>.

To use the AI advisor, add your Gemini API key to .env:

GEMINI_API_KEY="your-key-here"

Get a free key at aistudio.google.com.

About

A paper trading app (fake money, real stocks) with a chat bot for advice

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages