OpenStock
OpenStock 是一个免费的开源市场平台替代方案。实时追踪价格、设置个性化提醒、探索详细的公司洞察 — 开放构建,为所有人,永远免费。
注意:OpenStock 是社区构建的,并非经纪公司。市场数据可能因提供者规则和你的配置而延迟。这里没有任何财务建议。
📋 目录
- ✨ 简介
- 🌍 Open Dev Society 宣言
- ⚙️ 技术栈
- 🔋 功能
- 🤸 快速入门
- 🐳 Docker 设置
- 🔐 环境变量
- 🧱 项目结构
- 📡 数据与集成
- 🧪 脚本与工具
- 🤝 贡献
- 🛡️ 安全
- 📜 许可证
- 🙏 致谢
✨ 简介
OpenStock 是一款由 Next.js (App Router)、shadcn/ui 和 Tailwind CSS、Better Auth 用于认证、MongoDB 用于持久化、Finnhub 用于市场数据、TradingView 小部件用于图表和市场视图的现代股票市场应用。
🌍 Open Dev Society 宣言
我们生活在一个知识被付费墙隐藏的世界里。工具被订阅锁定。信息被偏见扭曲。新手被告知他们“不够好”才能构建。
我们相信有更好的方式。
- 我们的信念:技术应该属于每个人。知识应该是开放、免费且可访问的。社区应该以信任而非排斥来欢迎新人。
- 我们的使命:构建真正有影响力的免费开源项目:
- 专业人士和学生可以无障碍使用的工具。
- 学习永远免费的知平台。
- 每个初学者都受到指导而非评判的社区。
- 依赖信任而非利润的资源。
- 我们的承诺:我们永远不会封锁知识。我们永远不会为访问收费。我们永远不会用金钱换取信任。我们基于透明度、捐赠和社区的力量运行。
- 我们的号召:如果你曾觉得自己不属于这里,难以找到免费资源,或想构建有意义的东西 — 你属于这里。
因为未来属于那些开放构建的人。
⚙️ 技术栈
核心
- Next.js 15 (App Router), React 19
- TypeScript
- Tailwind CSS v4 (通过 @tailwindcss/postcss)
- shadcn/ui + Radix UI 基础组件
- Lucide 图标
认证与数据
- Better Auth (邮箱/密码) + MongoDB 适配器
- MongoDB + Mongoose
- Finnhub API 用于符号、资料和市场新闻
- TradingView 可嵌入小部件
自动化与通信
- Inngest (事件、cron、通过 Gemini 的 AI 推理)
- Nodemailer (Gmail 传输)
- next-themes, cmdk (命令面板), react-hook-form
语言组合
- TypeScript (~93.4%), CSS (~6%), JavaScript (~0.6%)
🔋 功能
- 认证
- 使用 Better Auth + MongoDB 适配器的邮箱/密码认证
- 通过 Next.js 中间件强制执行受保护路由
- 全局搜索和 Command + K 面板
- 基于 Finnhub 的快速股票搜索
- 空闲时显示热门股票;防抖查询
- 观察列表
- 存储在 MongoDB 中的每个用户的观察列表(每个用户一个唯一符号)
- 股票详情
- TradingView 符号信息、K线图/高级图表、基准线、技术指标
- 公司资料和财务小部件
- 市场概览
- 热图、报价和顶级新闻(TradingView 小部件)
- 个性化引导
- 收集国家、投资目标、风险承受能力、偏好行业
- 邮件与自动化
- AI 定制的欢迎邮件(通过 Inngest 的 Gemini)
- 每日新闻摘要邮件(cron)使用用户观察列表进行个性化
- 精美 UI
- shadcn/ui 组件、Radix 基础组件、Tailwind v4 设计令牌
- 默认深色主题
- 键盘快捷键
- Cmd/Ctrl + K 用于快速操作/搜索
🤸 快速入门
先决条件
- Node.js 20+ 和 pnpm 或 npm
- MongoDB 连接字符串(MongoDB Atlas 或 Docker Compose 本地)
- Finnhub API 密钥(支持免费层级;实时可能需要付费)
- Gmail 账户用于邮件(或更新 Nodemailer 传输)
- 可选:Google Gemini API 密钥(用于 AI 生成的欢迎介绍)
克隆并安装
git clone https://github.com/Open-Dev-Society/OpenStock.git
cd OpenStock
# 选择一个:
pnpm install
# 或
npm install
配置环境
- 创建一个
.env文件(见 环境变量)。 - 验证数据库连接:
pnpm test:db
# 或
npm run test:db
运行开发
# Next.js 开发(Turbopack)
pnpm dev
# 或
npm run dev
本地运行 Inngest(工作流、cron、AI)
npx inngest-cli@latest dev
构建并启动(生产)
pnpm build && pnpm start
# 或
npm run build && npm start
访问 http://localhost:3000 查看应用。
🐳 Docker 设置
你可以使用 Docker Compose 轻松运行 OpenStock 和 MongoDB。
-
确保 Docker 和 Docker Compose 已安装。
-
docker-compose.yml 包含两个服务:
- openstock(此应用)
- mongodb(带有持久卷的 MongoDB 数据库)
- 创建你的
.env(见示例)。对于 Docker 设置,使用本地连接字符串,如:
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
- 启动堆栈:
# 从仓库根目录
docker compose up -d mongodb && docker compose up -d --build
- 访问应用:
- 应用:http://localhost:3000
- MongoDB 可在 Docker 网络中通过主机 mongodb:27017 访问
注意
- 应用服务依赖于 mongodb 服务。
- 凭据在 Compose 中定义为 MongoDB 根用户的定义;连接字符串需要 authSource=admin 才能用于根用户。
- 通过 Docker 卷实现数据跨重启持久化。
可选:本项目使用的 MongoDB 服务示例定义:
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:
🔐 环境变量
在项目根目录创建 .env。选择托管的 MongoDB (Atlas) URI 或本地 Docker URI。
托管的 MongoDB (Atlas):
# 核心
NODE_ENV=development
# 数据库 (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
# 注意:NEXT_PUBLIC_FINNHUB_API_KEY 对于 Vercel 部署是必需的
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 签名密钥(对于 Vercel 部署是必需的)
# 从你的 Inngest 仪表板获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=your_inngest_signing_key
# 邮件 (Nodemailer 通过 Gmail;如果启用 2FA 考虑应用密码)
NODEMAILER_EMAIL=youraddress@gmail.com
NODEMAILER_PASSWORD=your_gmail_app_password
本地的 Docker Compose MongoDB:
# 核心
NODE_ENV=development
# 数据库 (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
# 注意:NEXT_PUBLIC_FINNHUB_API_KEY 对于 Vercel 部署是必需的
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 签名密钥(对于 Vercel 部署是必需的)
# 从你的 Inngest 仪表板获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=your_inngest_signing_key
# 邮件 (Nodemailer 通过 Gmail;如果启用 2FA 考虑应用密码)
NODEMAILER_EMAIL=youraddress@gmail.com
NODEMAILER_PASSWORD=your_gmail_app_password
注意
- 尽可能将私钥保存在服务器端。
- 如果使用
NEXT_PUBLIC_变量,请记住它们会暴露给浏览器。 - 生产环境中,优先使用专用 SMTP 提供商而非个人 Gmail。
- 不要在 Dockerfile 中硬编码密钥;使用
.env和 Compose。
🧱 项目结构
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 基础组件(按钮、对话框、命令、输入等)
forms/… # InputField, SelectField, CountrySelectField, FooterLink
Header.tsx, Footer.tsx, SearchCommand.tsx, WatchlistButton.tsx, …
database/
models/watchlist.model.ts
mongoose.ts
lib/
actions/… # 服务器动作(认证、Finnhub、用户、观察列表)
better-auth/…
inngest/… # 客户端、函数、提示
nodemailer/… # 传输器、邮件模板
constants.ts, utils.ts
scripts/
test-db.mjs
types/
global.d.ts
next.config.ts # i.ibb.co 图片域名允许列表
postcss.config.mjs # Tailwind v4 postcss 设置
components.json # shadcn 配置
public/assets/images/ # logo 和截图
📡 数据与集成
-
Finnhub
- 股票搜索、公司资料和市场新闻。
- 设置
NEXT_PUBLIC_FINNHUB_API_KEY和FINNHUB_BASE_URL(默认:https://finnhub.io/api/v1)。 - 免费层级可能返回延迟报价;尊重速率限制和条款。
-
TradingView
- 用于图表、热图、报价和时间的可嵌入市场小部件。
- 来自
i.ibb.co的外部图片在next.config.ts中允许。
-
Better Auth + MongoDB
- 邮箱/密码 + MongoDB 适配器。
- 通过中间件验证会话;大多数路由受保护,
sign-in、sign-up、资源及 Next 内部除外。
-
Inngest
- 工作流:
app/user.created→ AI 定制的欢迎邮件- Cron
0 12 * * *→ 每日新闻摘要按用户
- 本地开发:
npx inngest-cli@latest dev.
- 工作流:
-
邮件 (Nodemailer)
- Gmail 传输。更新凭证或切换到你的 SMTP 提供商。
- 欢迎和新闻摘要邮件的模板。
🧪 脚本与工具
包脚本
dev:Next.js 开发服务器(Turbopack)build:生产构建(Turbopack)start:运行生产服务器lint:ESLinttest:db:验证数据库连接
开发者体验
- TypeScript 严格模式
- Tailwind CSS v4(无需单独的 tailwind.config)
- shadcn/ui 组件 + Radix 基础组件
- cmdk 命令面板、next-themes、lucide-react 图标
🤝 贡献
你属于这里。无论你是学生、自学开发者还是资深工程师 — 欢迎任何贡献。
- 打开问题讨论想法和错误
- 查找“好第一问题”或“需要帮助”
- 保持 PR 聚焦;UI 变更添加截图
- 友善待人,指导新手,无门槛 — 这是 ODS 的方式
🛡️ 安全
如果你发现漏洞:
- 不要公开问题
- 邮件:opendevsociety@cc.cc
- 我们将协调负责任的披露并迅速修复
📜 许可证
OpenStock 将永远免费且开放给所有人。本项目根据 AGPL-3.0 许可证授权 — 详细内容请见 LICENSE 文件。
🙏 致谢
- Finnhub 提供可访问的市场数据
- TradingView 提供可嵌入市场小部件
- shadcn/ui、Radix UI、Tailwind CSS、Next.js 社区
- Inngest 提供可靠的背景作业和工作流
- Better Auth 提供简单安全的认证
- 所有使开源工具成为可能的贡献者
— 开放构建,为所有人,永远免费。Open Dev Society。
© Open Dev Society. 本项目根据 AGPL-3.0 许可证授权;如果你修改、分发或部署它(包括作为网络服务),你必须以相同的许可证发布你的源代码并注明原作者。
我们杰出的贡献者
- ravixalgorithm - 从零开始开发整个应用,包括认证、UI 设计、API 和 AI 集成以及部署。
- Priyanshuu00007 - 创建官方 OpenStock logo 并为项目的视觉身份做出贡献。
- chinnsenn - 为仓库设置 Docker 配置,确保开发部署流程顺畅。
- koevoet1221 - 解决 MongoDB Docker 构建问题,提高项目的整体稳定性和可靠性。
- ettoreciolli1 - 更新 Readme
❤️ 合作伙伴与支持者
Siray.ai — 支撑 OpenStock 的强大 AI 基础设施。Siray.ai 确保我们的市场洞察永不休息。
特别感谢
巨大感谢 Adrian Hajdin (JavaScript Mastery) — 他出色的 Stock Market App 教程对为 Open Dev Society 开源社区构建 OpenStock 起到了关键作用。
GitHub: adrianhajdin YouTube 教程: Stock Market App Tutorial YouTube 频道: JavaScript Mastery