Open Dev Society 新作: kitbash。在动手构建之前,先看看 GitHub 上已经有哪些现成的部件——拿来用、改造它,或者把剩下的部分写出来。

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(事件、定时任务、通过 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 线/高级图表、基线、技术指标
- 公司资料与财务数据组件
- 可选的跨源情绪洞察,覆盖 Reddit、X.com、新闻与 Polymarket
- 市场概览
- 热力图、行情报价与头条新闻(TradingView 组件)
- 个性化引导
- 收集国家、投资目标、风险偏好与感兴趣的行业
- 邮件与自动化
- 由 AI 生成的个性化欢迎邮件(通过 Inngest 调用 Gemini)
- 每日新闻摘要邮件(定时任务),根据用户自选股个性化推送
- 精致的 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(工作流、定时任务、AI)
npx inngest-cli@latest dev
构建并启动(生产环境)
pnpm build && pnpm start
# 或
npm run build && npm start
访问 http://localhost:3000 即可查看应用。
🐳 Docker 部署
你可以通过 Docker Compose 轻松启动 OpenStock 与 MongoDB。
1) 确保已安装 Docker 与 Docker Compose。
2) docker-compose.yml 包含两个服务:
- openstock(本应用)
- mongodb(MongoDB 数据库,带持久化卷)
3) 创建 .env 文件(参见下方的示例)。在 Docker 部署中使用形如以下的本地连接字符串:
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin
4) 启动整个服务栈:
# 在仓库根目录下执行
docker compose up -d mongodb && docker compose up -d --build
5) 访问应用:
- 应用:http://localhost:3000
- MongoDB 在 Docker 网络中可通过主机名
mongodb:27017访问
注意事项
openstock服务通过depends_on依赖mongodb服务。- MongoDB root 用户的凭据定义在 Compose 文件中;连接字符串中必须包含
authSource=admin以便 root 用户认证。 - 数据通过 Docker 卷实现重启后持久化。
可选:本项目使用的 MongoDB 服务定义示例
services:
mongodb:
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
# 注意:在 Vercel 部署时必须配置 NEXT_PUBLIC_FINNHUB_API_KEY
NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key
FINNHUB_BASE_URL=https://finnhub.io/api/v1
# 情绪洞察(可选)
ADANOS_API_KEY=your_adanos_api_key
# ADANOS_API_BASE_URL=https://api.adanos.org
# AI 提供方(可选,默认:"gemini")
# 支持:"gemini"、"minimax"、"siray"
# AI_PROVIDER=gemini
# Gemini
GEMINI_API_KEY=your_gemini_api_key
# MiniMax(可选,当 AI_PROVIDER=minimax 时使用,或作为兜底)
# 在 https://platform.minimaxi.com 获取密钥
# MINIMAX_API_KEY=your_minimax_api_key
# Inngest 签名密钥(在 Vercel 部署时必须)
# 从 Inngest 控制台获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=your_inngest_signing_key
# 邮件(Nodemailer 通过 Gmail;若开启两步验证请使用应用专用密码)
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
# 注意:在 Vercel 部署时必须配置 NEXT_PUBLIC_FINNHUB_API_KEY
NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key
FINNHUB_BASE_URL=https://finnhub.io/api/v1
# 情绪洞察(可选)
ADANOS_API_KEY=your_adanos_api_key
# ADANOS_API_BASE_URL=https://api.adanos.org
# AI 提供方(可选,默认:"gemini")
# 支持:"gemini"、"minimax"、"siray"
# AI_PROVIDER=gemini
# Gemini
GEMINI_API_KEY=your_gemini_api_key
# MiniMax(可选,当 AI_PROVIDER=minimax 时使用,或作为兜底)
# 在 https://platform.minimaxi.com 获取密钥
# MINIMAX_API_KEY=your_minimax_api_key
# Inngest 签名密钥(在 Vercel 部署时必须)
# 从 Inngest 控制台获取:https://app.inngest.com/env/settings/keys
INNGEST_SIGNING_KEY=your_inngest_signing_key
# 邮件(Nodemailer 通过 Gmail;若开启两步验证请使用应用专用密码)
NODEMAILER_EMAIL=youraddress@gmail.com
NODEMAILER_PASSWORD=your_gmail_app_password
注意事项
- 尽可能将私钥保留在服务端。
- 若使用
NEXT_PUBLIC_前缀的变量,请注意它们会被暴露到浏览器。 - 在生产环境中,建议使用专用的 SMTP 服务商,而非个人 Gmail。
- 不要在 Dockerfile 中硬编码密钥;请使用
.env与 Compose 管理。