437 lines
16 KiB
Markdown
437 lines
16 KiB
Markdown
<div align="center">
|
||
Checkout new amazing projects also, <a href="github.com/open-dev-society/openreadme" target="_blank">OpenReadme </a> is live
|
||
</div>
|
||
<a href="https://hellogithub.com/repository/Open-Dev-Society/OpenStock" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=5c4337a9e2dd4a8ba8aba87a88f04b8b&claim_uid=07HezcXv9puSGKQ&theme=neutral" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||
<a href="https://peerlist.io/ravixalgorithm/project/openstock" target="_blank" rel="noreferrer">
|
||
<img
|
||
src="https://peerlist.io/api/v1/projects/embed/PRJH8OED7MBL9MGB9HRMKAKLM66KNN?showUpvote=true&theme=light"
|
||
alt="OpenStock"
|
||
style="width: auto; height: 54px;"
|
||
/>
|
||
</a>
|
||
<div align="center">
|
||
<br />
|
||
<a href="#" target="_blank">
|
||
<img src="./public/assets/images/dashboard.png" alt="Project Banner" />
|
||
</a>
|
||
© Open Dev Society. This project is licensed under AGPL-3.0; if you modify, redistribute, or deploy it (including as a web service), you must release your source code under the same license and credit the original authors.
|
||
<br />
|
||
<br/>
|
||
|
||
<div>
|
||
<img src="https://img.shields.io/badge/-Next.js-black?style=for-the-badge&logoColor=white&logo=next.js&color=000000" alt="Next.js badge" />
|
||
<img src="https://img.shields.io/badge/-TypeScript-black?style=for-the-badge&logoColor=white&logo=typescript&color=3178C6"/>
|
||
<img src="https://img.shields.io/badge/-Tailwind%20CSS-black?style=for-the-badge&logoColor=white&logo=tailwindcss&color=38B2AC"/>
|
||
<img src="https://img.shields.io/badge/-shadcn/ui-black?style=for-the-badge&logoColor=white&logo=shadcnui&color=000000"/>
|
||
<img src="https://img.shields.io/badge/-Radix%20UI-black?style=for-the-badge&logoColor=white&logo=radixui&color=000000"/>
|
||
<img src="https://img.shields.io/badge/-Better%20Auth-black?style=for-the-badge&logoColor=white&logo=betterauth&color=000000"/>
|
||
<img src="https://img.shields.io/badge/-MongoDB-black?style=for-the-badge&logoColor=white&logo=mongodb&color=00A35C"/>
|
||
<img src="https://img.shields.io/badge/-Inngest-black?style=for-the-badge&logoColor=white&logo=inngest&color=000000"/>
|
||
<img src="https://img.shields.io/badge/-Nodemailer-black?style=for-the-badge&logoColor=white&logo=gmail&color=EA4335"/>
|
||
<img src="https://img.shields.io/badge/-TradingView-black?style=for-the-badge&logoColor=white&logo=tradingview&color=2962FF"/>
|
||
<img src="https://img.shields.io/badge/-Finnhub-black?style=for-the-badge&logoColor=white&color=30B27A"/>
|
||
<img src="https://img.shields.io/badge/-CodeRabbit-black?style=for-the-badge&logoColor=white&logo=coderabbit&color=9146FF"/>
|
||
</div>
|
||
</div>
|
||
|
||
# OpenStock
|
||
|
||
OpenStock is an open-source alternative to expensive market platforms. Track real-time prices, set personalized alerts, and explore detailed company insights — built openly, for everyone, forever free.
|
||
|
||
Note: OpenStock is community-built and not a brokerage. Market data may be delayed based on provider rules and your configuration. Nothing here is financial advice.
|
||
|
||
## 📋 Table of Contents
|
||
|
||
1. ✨ [Introduction](#introduction)
|
||
2. 🌍 [Open Dev Society Manifesto](#manifesto)
|
||
3. ⚙️ [Tech Stack](#tech-stack)
|
||
4. 🔋 [Features](#features)
|
||
5. 🤸 [Quick Start](#quick-start)
|
||
6. 🐳 [Docker Setup](#docker-setup)
|
||
7. 🔐 [Environment Variables](#environment-variables)
|
||
8. 🧱 [Project Structure](#project-structure)
|
||
9. 📡 [Data & Integrations](#data--integrations)
|
||
10. 🧪 [Scripts & Tooling](#scripts--tooling)
|
||
11. 🤝 [Contributing](#contributing)
|
||
12. 🛡️ [Security](#security)
|
||
13. 📜 [License](#license)
|
||
14. 🙏 [Acknowledgements](#acknowledgements)
|
||
|
||
## ✨ Introduction <a name="introduction"></a>
|
||
|
||
OpenStock is a modern stock market app powered by Next.js (App Router), shadcn/ui and Tailwind CSS, Better Auth for authentication, MongoDB for persistence, Finnhub for market data, and TradingView widgets for charts and market views.
|
||
|
||
## 🌍 Open Dev Society Manifesto <a name="manifesto"></a>
|
||
|
||
We live in a world where knowledge is hidden behind paywalls. Where tools are locked in subscriptions. Where information is twisted by bias. Where newcomers are told they’re not “good enough” to build.
|
||
|
||
We believe there’s a better way.
|
||
|
||
- Our Belief: Technology should belong to everyone. Knowledge should be open, free, and accessible. Communities should welcome newcomers with trust, not gatekeeping.
|
||
- Our Mission: Build free, open-source projects that make a real difference:
|
||
- Tools that professionals and students can use without barriers.
|
||
- Knowledge platforms where learning is free, forever.
|
||
- Communities where every beginner is guided, not judged.
|
||
- Resources that run on trust, not profit.
|
||
- Our Promise: We will never lock knowledge. We will never charge for access. We will never trade trust for money. We run on transparency, donations, and the strength of our community.
|
||
- Our Call: If you’ve ever felt you didn’t belong, struggled to find free resources, or wanted to build something meaningful — you belong here.
|
||
|
||
Because the future belongs to those who build it openly.
|
||
|
||
## ⚙️ Tech Stack <a name="tech-stack"></a>
|
||
|
||
Core
|
||
- Next.js 15 (App Router), React 19
|
||
- TypeScript
|
||
- Tailwind CSS v4 (via @tailwindcss/postcss)
|
||
- shadcn/ui + Radix UI primitives
|
||
- Lucide icons
|
||
|
||
Auth & Data
|
||
- Better Auth (email/password) with MongoDB adapter
|
||
- MongoDB + Mongoose
|
||
- Finnhub API for symbols, profiles, and market news
|
||
- TradingView embeddable widgets
|
||
|
||
Automation & Comms
|
||
- Inngest (events, cron, AI inference via Gemini)
|
||
- Nodemailer (Gmail transport)
|
||
- next-themes, cmdk (command palette), react-hook-form
|
||
|
||
Language composition
|
||
- TypeScript (~93.4%), CSS (~6%), JavaScript (~0.6%)
|
||
|
||
## 🔋 Features <a name="features"></a>
|
||
|
||
- Authentication
|
||
- Email/password auth with Better Auth + MongoDB adapter
|
||
- Protected routes enforced via Next.js middleware
|
||
- Global search and Command + K palette
|
||
- Fast stock search backed by Finnhub
|
||
- Popular stocks when idle; debounced querying
|
||
- Watchlist
|
||
- Per-user watchlist stored in MongoDB (unique symbol per user)
|
||
- Stock details
|
||
- TradingView symbol info, candlestick/advanced charts, baseline, technicals
|
||
- Company profile and financials widgets
|
||
- Market overview
|
||
- Heatmap, quotes, and top stories (TradingView widgets)
|
||
- Personalized onboarding
|
||
- Collects country, investment goals, risk tolerance, preferred industry
|
||
- Email & automation
|
||
- AI-personalized welcome email (Gemini via Inngest)
|
||
- Daily news summary emails (cron) personalized using user watchlists
|
||
- Polished UI
|
||
- shadcn/ui components, Radix primitives, Tailwind v4 design tokens
|
||
- Dark theme by default
|
||
- Keyboard shortcut
|
||
- Cmd/Ctrl + K for quick actions/search
|
||
|
||
## 🤸 Quick Start <a name="quick-start"></a>
|
||
|
||
Prerequisites
|
||
- Node.js 20+ and pnpm or npm
|
||
- MongoDB connection string (MongoDB Atlas or local via Docker Compose)
|
||
- Finnhub API key (free tier supported; real-time may require paid)
|
||
- Gmail account for email (or update Nodemailer transport)
|
||
- Optional: Google Gemini API key (for AI-generated welcome intros)
|
||
|
||
Clone and install
|
||
```bash
|
||
git clone https://github.com/Open-Dev-Society/OpenStock.git
|
||
cd OpenStock
|
||
|
||
# choose one:
|
||
pnpm install
|
||
# or
|
||
npm install
|
||
```
|
||
|
||
Configure environment
|
||
- Create a `.env` file (see [Environment Variables](#environment-variables)).
|
||
- Verify DB connectivity:
|
||
```bash
|
||
pnpm test:db
|
||
# or
|
||
npm run test:db
|
||
```
|
||
|
||
Run development
|
||
```bash
|
||
# Next.js dev (Turbopack)
|
||
pnpm dev
|
||
# or
|
||
npm run dev
|
||
```
|
||
|
||
Run Inngest locally (workflows, cron, AI)
|
||
```bash
|
||
npx inngest-cli@latest dev
|
||
```
|
||
|
||
Build & start (production)
|
||
```bash
|
||
pnpm build && pnpm start
|
||
# or
|
||
npm run build && npm start
|
||
```
|
||
|
||
Open http://localhost:3000 to view the app.
|
||
|
||
## 🐳 Docker Setup <a name="docker-setup"></a>
|
||
|
||
You can run OpenStock and MongoDB easily with Docker Compose.
|
||
|
||
1) Ensure Docker and Docker Compose are installed.
|
||
|
||
2) docker-compose.yml includes two services:
|
||
- openstock (this app)
|
||
- mongodb (MongoDB database with a persistent volume)
|
||
|
||
3) Create your `.env` (see examples below). For the Docker setup, use a local connection string like:
|
||
```env
|
||
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
|
||
```
|
||
|
||
4) Start the stack:
|
||
```bash
|
||
# from the repository root
|
||
docker compose up -d mongodb && docker compose up -d --build
|
||
```
|
||
|
||
5) Access the app:
|
||
- App: http://localhost:3000
|
||
- MongoDB is available inside the Docker network at host mongodb:27017
|
||
|
||
Notes
|
||
- The app service depends_on the mongodb service.
|
||
- Credentials are defined in Compose for the MongoDB root user; authSource=admin is required on the connection string for root.
|
||
- Data persists across restarts via the docker volume.
|
||
|
||
Optional: Example MongoDB service definition used in this project:
|
||
```yaml
|
||
services:
|
||
mongodb:
|
||
image: mongo:7
|
||
container_name: mongodb
|
||
restart: unless-stopped
|
||
environment:
|
||
MONGO_INITDB_ROOT_USERNAME: root
|
||
MONGO_INITDB_ROOT_PASSWORD: example
|
||
ports:
|
||
- "27017:27017"
|
||
volumes:
|
||
- mongo-data:/data/db
|
||
healthcheck:
|
||
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
|
||
volumes:
|
||
mongo-data:
|
||
```
|
||
|
||
## 🔐 Environment Variables <a name="environment-variables"></a>
|
||
|
||
Create `.env` at the project root. Choose either a hosted MongoDB (Atlas) URI or the local Docker URI.
|
||
|
||
Hosted (MongoDB Atlas):
|
||
```env
|
||
# Core
|
||
NODE_ENV=development
|
||
|
||
# Database (Atlas)
|
||
MONGODB_URI=mongodb+srv://<user>:<pass>@<cluster>/<db>?retryWrites=true&w=majority
|
||
|
||
# Better Auth
|
||
BETTER_AUTH_SECRET=your_better_auth_secret
|
||
BETTER_AUTH_URL=http://localhost:3000
|
||
|
||
# Finnhub
|
||
# Note: NEXT_PUBLIC_FINNHUB_API_KEY is required for Vercel deployment
|
||
NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key
|
||
FINNHUB_BASE_URL=https://finnhub.io/api/v1
|
||
|
||
# Inngest AI (Gemini)
|
||
GEMINI_API_KEY=your_gemini_api_key
|
||
# Inngest Signing Key (required for Vercel deployment)
|
||
# Get this from your Inngest dashboard: https://app.inngest.com/env/settings/keys
|
||
INNGEST_SIGNING_KEY=your_inngest_signing_key
|
||
|
||
# Email (Nodemailer via Gmail; consider App Passwords if 2FA)
|
||
NODEMAILER_EMAIL=youraddress@gmail.com
|
||
NODEMAILER_PASSWORD=your_gmail_app_password
|
||
```
|
||
|
||
Local (Docker Compose) MongoDB:
|
||
```env
|
||
# Core
|
||
NODE_ENV=development
|
||
|
||
# Database (Docker)
|
||
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
|
||
|
||
# Better Auth
|
||
BETTER_AUTH_SECRET=your_better_auth_secret
|
||
BETTER_AUTH_URL=http://localhost:3000
|
||
|
||
# Finnhub
|
||
# Note: NEXT_PUBLIC_FINNHUB_API_KEY is required for Vercel deployment
|
||
NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key
|
||
FINNHUB_BASE_URL=https://finnhub.io/api/v1
|
||
|
||
# Inngest AI (Gemini)
|
||
GEMINI_API_KEY=your_gemini_api_key
|
||
# Inngest Signing Key (required for Vercel deployment)
|
||
# Get this from your Inngest dashboard: https://app.inngest.com/env/settings/keys
|
||
INNGEST_SIGNING_KEY=your_inngest_signing_key
|
||
|
||
# Email (Nodemailer via Gmail; consider App Passwords if 2FA)
|
||
NODEMAILER_EMAIL=youraddress@gmail.com
|
||
NODEMAILER_PASSWORD=your_gmail_app_password
|
||
```
|
||
|
||
Notes
|
||
- Keep private keys server-side whenever possible.
|
||
- If using `NEXT_PUBLIC_` variables, remember they are exposed to the browser.
|
||
- In production, prefer a dedicated SMTP provider over a personal Gmail.
|
||
- Do not hardcode secrets in the Dockerfile; use `.env` and Compose.
|
||
|
||
## 🧱 Project Structure <a name="project-structure"></a>
|
||
|
||
```
|
||
app/
|
||
(auth)/
|
||
layout.tsx
|
||
sign-in/page.tsx
|
||
sign-up/page.tsx
|
||
(root)/
|
||
layout.tsx
|
||
page.tsx
|
||
help/page.tsx
|
||
stocks/[symbol]/page.tsx
|
||
api/inngest/route.ts
|
||
globals.css
|
||
layout.tsx
|
||
components/
|
||
ui/… # shadcn/radix primitives (button, dialog, command, input, etc.)
|
||
forms/… # InputField, SelectField, CountrySelectField, FooterLink
|
||
Header.tsx, Footer.tsx, SearchCommand.tsx, WatchlistButton.tsx, …
|
||
database/
|
||
models/watchlist.model.ts
|
||
mongoose.ts
|
||
lib/
|
||
actions/… # server actions (auth, finnhub, user, watchlist)
|
||
better-auth/…
|
||
inngest/… # client, functions, prompts
|
||
nodemailer/… # transporter, email templates
|
||
constants.ts, utils.ts
|
||
scripts/
|
||
test-db.mjs
|
||
types/
|
||
global.d.ts
|
||
next.config.ts # i.ibb.co image domain allowlist
|
||
postcss.config.mjs # Tailwind v4 postcss setup
|
||
components.json # shadcn config
|
||
public/assets/images/ # logos and screenshots
|
||
```
|
||
|
||
## 📡 Data & Integrations <a name="data--integrations"></a>
|
||
|
||
- Finnhub
|
||
- Stock search, company profiles, and market news.
|
||
- Set `NEXT_PUBLIC_FINNHUB_API_KEY` and `FINNHUB_BASE_URL` (default: https://finnhub.io/api/v1).
|
||
- Free tiers may return delayed quotes; respect rate limits and terms.
|
||
|
||
- TradingView
|
||
- Embeddable widgets used for charts, heatmap, quotes, and timelines.
|
||
- External images from `i.ibb.co` are allowlisted in `next.config.ts`.
|
||
|
||
- Better Auth + MongoDB
|
||
- Email/password with MongoDB adapter.
|
||
- Session validation via middleware; most routes are protected, with public exceptions for `sign-in`, `sign-up`, assets and Next internals.
|
||
|
||
- Inngest
|
||
- Workflows:
|
||
- `app/user.created` → AI-personalized Welcome Email
|
||
- Cron `0 12 * * *` → Daily News Summary per user
|
||
- Local dev: `npx inngest-cli@latest dev`.
|
||
|
||
- Email (Nodemailer)
|
||
- Gmail transport. Update credentials or switch to your SMTP provider.
|
||
- Templates for welcome and news summary emails.
|
||
|
||
## 🧪 Scripts & Tooling <a name="scripts--tooling"></a>
|
||
|
||
Package scripts
|
||
- `dev`: Next.js dev server with Turbopack
|
||
- `build`: Production build (Turbopack)
|
||
- `start`: Run production server
|
||
- `lint`: ESLint
|
||
- `test:db`: Validate DB connectivity
|
||
|
||
Developer experience
|
||
- TypeScript strict mode
|
||
- Tailwind CSS v4 (no separate tailwind.config needed)
|
||
- shadcn/ui components with Radix primitives
|
||
- cmdk command palette, next-themes, lucide-react icons
|
||
|
||
## 🤝 Contributing <a name="contributing"></a>
|
||
|
||
You belong here. Whether you’re a student, a self-taught dev, or a seasoned engineer — contributions are welcome.
|
||
|
||
- Open an issue to discuss ideas and bugs
|
||
- Look for “good first issue” or “help wanted”
|
||
- Keep PRs focused; add screenshots for UI changes
|
||
- Be kind, guide beginners, no gatekeeping — that’s the ODS way
|
||
|
||
## 🛡️ Security <a name="security"></a>
|
||
|
||
If you discover a vulnerability:
|
||
- Do not open a public issue
|
||
- Email: <a href="mailto:opendevsociety@cc.cc">opendevsociety@cc.cc</a>
|
||
- We'll coordinate responsible disclosure and patch swiftly
|
||
|
||
## 📜 License <a name="license"></a>
|
||
|
||
OpenStock is and will remain free and open for everyone. This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.
|
||
|
||
## 🙏 Acknowledgements <a name="acknowledgements"></a>
|
||
|
||
- Finnhub for accessible market data
|
||
- TradingView for embeddable market widgets
|
||
- shadcn/ui, Radix UI, Tailwind CSS, Next.js community
|
||
- Inngest for dependable background jobs and workflows
|
||
- Better Auth for simple and secure authentication
|
||
- All contributors who make open tools possible
|
||
|
||
— Built openly, for everyone, forever free. Open Dev Society.
|
||
|
||
> © Open Dev Society. This project is licensed under AGPL-3.0; if you modify, redistribute, or deploy it (including as a web service), you must release your source code under the same license and credit the original authors.
|
||
|
||
## Our Honourable Contributors
|
||
- [ravixalgorithm](https://github.com/ravixalgorithm) - Developed the entire application from the ground up, including authentication, UI design, API and AI integration, and deployment.
|
||
- [Priyanshuu00007](https://github.com/Priyanshuu00007) - Created the official OpenStock logo and contributed to the project’s visual identity.
|
||
- [chinnsenn](https://github.com/chinnsenn) - Set up Docker configuration for the repository, ensuring a smooth development and deployment process.
|
||
- [koevoet1221](https://github.com/koevoet1221) - Resolved MongoDB Docker build issues, improving the project’s overall stability and reliability.
|
||
- [ettoreciolli1](https://github.com/ettoreciolli1) - updated Readme
|
||
|
||
|
||
|
||
## ❤️ Partners & Backers
|
||
|
||
<a href="https://www.siray.ai/">
|
||
<img src="public/assets/icons/siray.svg" alt="Siray.ai Logo" width="100" />
|
||
</a>
|
||
|
||
**[Siray.ai](https://www.siray.ai/)** — The robust AI infrastructure backing OpenStock. Siray.ai ensures our market insights never sleep.
|
||
|
||
## Special thanks
|
||
Huge thanks to [Adrian Hajdin (JavaScript Mastery)](https://github.com/adrianhajdin) — his excellent Stock Market App tutorial was instrumental in building OpenStock for the open-source community under the Open Dev Society.
|
||
|
||
GitHub: [adrianhajdin](https://github.com/adrianhajdin)
|
||
YouTube tutorial: [Stock Market App Tutorial](https://www.youtube.com/watch?v=gu4pafNCXng)
|
||
YouTube channel: [JavaScript Mastery](https://www.youtube.com/@javascriptmastery)
|
||
|