Files
chat-one-service/README.md
alboped bc13417efd feat: Prisma 用户落库、迁移与启动环境加载
- Prisma 7 + adapter-pg;prisma.config 与 users 初始迁移\n- AppModule 挂载 PrismaModule;PrismaService 仅依赖 DATABASE_URL\n- main 入口 dotenv/config,避免 Prisma 早于 Config 读 env\n- 短信登录 upsert User;默认昵称 Chat+手机号后四位\n- README / project-solution:目录、迁移规范、用户 avatar_url 说明\n- 依赖:dotenv、@prisma/adapter-pg、pg

Made-with: Cursor
2026-04-22 01:21:11 +08:00

320 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# chat-one-service
## TODO当前迭代
- [ ] client-app短信登录 + JWT 鉴权(接入真实短信服务前先 mock
- [ ] client-appChat 会话与消息持久化(接入 Prisma + 数据库)
- [ ] client-app按用户限流与基础风控基于 Redis 后续补上)
- [ ] admin-app邮箱登录与 RBAC角色/权限点基础能力)
- [ ] admin-app平台管理接口增删改查 + 开关 + 权重)
- [ ] admin-app用量统计与简单报表按平台 / 用户聚合)
---
ChatOne 服务端:基于 **NestJS 11** + **Fastify**,整合多厂商大模型对话能力,对外提供统一的 **SSEServer-Sent Events** 流式输出协议,便于 Web / App 接入。
更完整的架构说明见:`docs/project-solution.md`。JWT 最小示例见:`docs/jwt-minimal-nestjs.md`
## 目录
- [TODO当前迭代](#todo当前迭代)
- [技术栈](#技术栈)
- [目录结构(概要)](#目录结构概要)
- [环境要求](#环境要求)
- [安装依赖](#安装依赖)
- [环境变量](#环境变量)
- [常用脚本](#常用脚本)
- [数据库迁移规范Prisma](#数据库迁移规范prisma)
- [启动](#启动)
- [API 说明](#api-说明)
- [数据库与 Prisma](#数据库与-prisma)
- [安全提示](#安全提示)
- [许可证](#许可证)
---
## 技术栈
- **框架**NestJS 11`@nestjs/platform-fastify`
- **HTTP 客户端**`undici`(调用各厂商 OpenAI 兼容接口)
- **配置**`@nestjs/config`(可选环境校验见 `src/config/validation.ts`,默认可在 `AppModule` 中关闭)
- **日志**`nestjs-pino` + `pino-pretty`(开发环境美化输出)
- **文档**Swagger默认路径 `/docs`
- **安全头**`helmet`
---
## 目录结构(概要)
```text
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
---
## 安装依赖
```bash
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` |
### Spug 推送助手(短信验证码)
在 [Spug 推送助手](https://push.spug.cc) 创建「短信验证码」类消息模板复制模板编号URL 路径中的 ID。模板中可使用变量 **`number`**(有效期,单位:**分钟**);服务端会根据 `SMS_CODE_TTL_SECONDS` 换算后传入(向上取整,至少为 1与 Redis 中验证码 TTL 一致。
| 变量 | 说明 |
|------|------|
| `SPUG_PUSH_SMS_TEMPLATE_ID` | 消息模板编号(必填,非 mock 时) |
| `SPUG_PUSH_BASE_URL` | 可选,默认 `https://push.spug.cc` |
| `SPUG_SMS_NAME` | 可选,模板若要求 `name` 变量则配置(与官方示例一致) |
| `SMS_MOCK` | 可选,`true` 时跳过真实短信发送(本地联调用) |
| `SMS_CODE_TTL_SECONDS` | 可选,短信验证码 Redis TTL默认 `300` |
> 说明:当前各 Provider 对上游采用 **非流式** `chat/completions` 调用,由网关将完整回复 **切片** 后以 SSE 推给客户端。后续可升级为上游真流式。
---
## 常用脚本
| 命令 | 说明 |
|------|------|
| `yarn start:dev` | 开发模式(`tsx watch`,改代码自动重启) |
| `yarn build` | TypeScript 编译到 `dist/` |
| `yarn start` | 运行已编译产物 `dist/main.js` |
| `yarn lint` | ESLint需本地配置规则时生效 |
## 数据库迁移规范Prisma
### 开发环境变更流程
1. 修改 `prisma/schema.prisma`(新增表/字段/索引等)
1. 生成并执行迁移:
```bash
npx prisma migrate dev --name <migration_name>
```
1. 如需手动更新 Prisma Client
```bash
npx prisma generate
```
1. 本地验证接口与核心流程
1. 提交代码时必须包含:
- `prisma/schema.prisma`
- `prisma/migrations/**`
### 生产环境发布流程
生产环境禁止使用 `migrate dev`,仅执行:
```bash
npx prisma migrate deploy
```
### 迁移命名规范
迁移名统一使用:`动词_对象_说明`
例如:
- `init_users`
- `add_users_avatar_url`
- `add_chat_sessions`
- `alter_chat_messages_token_count_type`
### 风险控制建议
- 涉及删列、改类型、重命名时,先在测试库验证
- 可能影响历史数据的迁移,先做备份
- 大改动拆分为多次小迁移,避免一次性高风险变更
### 常用命令速查
```bash
# 生成并执行开发迁移
npx prisma migrate dev --name <name>
# 仅更新 Prisma Client
npx prisma generate
# 查看数据库状态
npx prisma migrate status
# 生产环境应用迁移
npx prisma migrate deploy
```
---
## 启动
开发:
```bash
yarn start:dev
```
默认监听:`http://localhost:3000`(可通过 `PORT` 修改)。
生产(先编译再启动):
```bash
yarn build
yarn start
```
---
## API 说明
### Swagger
浏览器打开:`http://localhost:3000/docs`
### 客户端认证MVP
- `POST /api/client/v1/auth/sms/send`
- 入参:`{ "phone": "13800000000", "scene": "login" }`
- 返回:`requestId``expireIn``provider`
- 说明:已接入 Spug 推送助手;非生产环境会额外返回 `testCode` 便于联调
- `POST /api/client/v1/auth/sms/login`
- 入参:`{ "phone": "13800000000", "code": "xxxxxx" }`
- 返回:`accessToken``refreshToken``user`
- `POST /api/client/v1/auth/refresh`
- 入参:`{ "refreshToken": "..." }`
- 返回:新的 `accessToken``refreshToken`
> 验证码当前已接入 Redis 存储key: `chatone:client:sms:code:{phone}:{scene}`TTL 300 秒)。
### 统一 SSE Chat用户端
- **路径**`POST /api/client/v1/chat/completions/stream`
- **Content-Type**`application/json`
- **响应**`text/event-stream`SSE
#### 请求体(示例)
```json
{
"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 示例(流式)
先获取 token
```bash
curl -s -H "Content-Type: application/json" -X POST \
-d '{"phone":"13800000000","code":"123456"}' \
http://localhost:3000/api/client/v1/auth/sms/login
```
再带 `Authorization` 调用 chat
```bash
curl -N \
-H "Authorization: Bearer 你的accessToken" \
-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`,避免启动时报缺少生成客户端的错误。
接入数据库时的典型步骤:
1. 编写 `prisma/schema.prisma` 并配置 `DATABASE_URL`
2. 执行 `npx prisma generate` / `yarn prisma generate`
3.`src/app.module.ts` 中按需 `imports: [PrismaModule]`
---
## 安全提示
- **切勿**将含真实 Key 的 `.env` 提交到版本库。
- 若密钥曾在公开场合暴露,请在对应云厂商控制台 **轮换 API Key**
---
## 许可证
MIT见仓库根目录 `LICENSE`)。