61ac181b8320845b0ee2fda1d0abbda3a53c33fc
chat-one-service
TODO(当前迭代)
- client-app:短信登录 + JWT 鉴权(接入真实短信服务前先 mock)
- client-app:Chat 会话与消息持久化(接入 Prisma + 数据库)
- client-app:按用户限流与基础风控(基于 Redis 后续补上)
- admin-app:邮箱登录与 RBAC(角色/权限点基础能力)
- admin-app:平台管理接口(增删改查 + 开关 + 权重)
- admin-app:用量统计与简单报表(按平台 / 用户聚合)
ChatOne 服务端:基于 NestJS 11 + Fastify,整合多厂商大模型对话能力,对外提供统一的 SSE(Server-Sent Events) 流式输出协议,便于 Web / App 接入。
更完整的架构说明见:docs/project-solution.md。JWT 最小示例见:docs/jwt-minimal-nestjs.md。
技术栈
- 框架:NestJS 11,
@nestjs/platform-fastify - HTTP 客户端:
undici(调用各厂商 OpenAI 兼容接口) - 配置:
@nestjs/config(可选环境校验见src/config/validation.ts,默认可在AppModule中关闭) - 日志:
nestjs-pino+pino-pretty(开发环境美化输出) - 文档:Swagger,默认路径
/docs - 安全头:
helmet
目录结构(概要)
src/
├── main.ts # 入口:Fastify + 全局前缀 api + Swagger
├── app.module.ts # 根模块
├── config/ # 配置加载与环境校验
├── apps/
│ ├── client-app/ # 用户端(当前含 Chat SSE)
│ ├── admin-app/ # 管理端(占位模块,后续扩展)
│ └── shared-domain/
│ └── ai-gateway/ # 多平台 Provider 与路由
├── prisma/ # Prisma 封装(按需接入数据库时再挂回 AppModule)
docs/
├── project-solution.md
└── jwt-minimal-nestjs.md
环境要求
- Node.js:建议 20 LTS 及以上
- 包管理:本项目使用 Yarn(存在
yarn.lock);亦可用 npm
安装依赖
yarn install
环境变量
在项目根目录创建 .env(该文件已在 .gitignore 中,不要提交到 Git)。
服务
| 变量 | 说明 | 示例 |
|---|---|---|
PORT |
监听端口 | 3000 |
NODE_ENV |
运行环境 | development / production |
千问(DashScope OpenAI 兼容)
| 变量 | 说明 |
|---|---|
QWEN_API_KEY |
千问 API Key |
QWEN_BASE_URL |
可选,默认 https://dashscope.aliyuncs.com/compatible-mode/v1 |
DeepSeek
| 变量 | 说明 |
|---|---|
DEEPSEEK_API_KEY |
DeepSeek API Key |
DEEPSEEK_BASE_URL |
可选,默认 https://api.deepseek.com/v1 |
火山引擎(方舟 OpenAI 兼容形态,具体以你控制台为准)
| 变量 | 说明 |
|---|---|
VOLC_API_KEY |
火山引擎 API Key |
VOLC_BASE_URL |
可选,默认 https://ark.cn-beijing.volces.com/api/v3 |
说明:当前各 Provider 对上游采用 非流式
chat/completions调用,由网关将完整回复 切片 后以 SSE 推给客户端。后续可升级为上游真流式。
常用脚本
| 命令 | 说明 |
|---|---|
yarn start:dev |
开发模式(tsx watch,改代码自动重启) |
yarn build |
TypeScript 编译到 dist/ |
yarn start |
运行已编译产物 dist/main.js |
yarn lint |
ESLint(需本地配置规则时生效) |
启动
开发:
yarn start:dev
默认监听:http://localhost:3000(可通过 PORT 修改)。
生产(先编译再启动):
yarn build
yarn start
API 说明
Swagger
浏览器打开:http://localhost:3000/docs
统一 SSE Chat(用户端)
- 路径:
POST /api/client/v1/chat/completions/stream - Content-Type:
application/json - 响应:
text/event-stream(SSE)
请求体(示例)
{
"model": "qwen-plus",
"platform": "qwen",
"messages": [
{ "role": "system", "content": "你是一个乐于助人的助手" },
{ "role": "user", "content": "你好" }
]
}
platform:qwen|deepseek|volc|auto(或不传,由路由按model简单匹配)model:各平台实际模型名或 Endpoint ID(火山侧请填你在控制台配置的模型标识)
SSE 事件约定
| 事件名 | data 字段含义 |
|---|---|
meta |
请求元信息:requestId、platform、model |
delta |
文本增量:{"delta":"..."} |
usage |
Token 用量:promptTokens / completionTokens / totalTokens |
done |
结束:finishReason |
curl 示例(流式)
curl -N \
-H "Content-Type: application/json" \
-X POST \
-d '{"platform":"qwen","model":"qwen-plus","messages":[{"role":"user","content":"你是谁"}]}' \
http://localhost:3000/api/client/v1/chat/completions/stream
数据库与 Prisma
仓库内已包含 src/prisma/ 模块骨架。若尚未准备好 PostgreSQL 或未执行 prisma generate,请勿在 AppModule 中导入 PrismaModule,避免启动时报缺少生成客户端的错误。
接入数据库时的典型步骤:
- 编写
prisma/schema.prisma并配置DATABASE_URL - 执行
npx prisma generate/yarn prisma generate - 在
src/app.module.ts中按需imports: [PrismaModule]
安全提示
- 切勿将含真实 Key 的
.env提交到版本库。 - 若密钥曾在公开场合暴露,请在对应云厂商控制台 轮换 API Key。
许可证
MIT(见仓库根目录 LICENSE)。