# lulab_backend **Repository Path**: proflu/lulab_backend_nest ## Basic Information - **Project Name**: lulab_backend - **Description**: No description available - **Primary Language**: NodeJS - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-10 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

LuLab Backend

基于 NestJS 的企业级会议与用户服务后端。提供完整的用户认证体系(JWT + Token 黑名单)、多渠道验证码(邮箱/短信)、异步邮件队列、会议记录管理与统计分析,并深度集成腾讯会议 Webhook/开放 API、飞书多维表格(Bitable)同步与 OpenAI 智能能力。数据层采用 Prisma ORM + PostgreSQL,支持 GraphQL 与 RESTful 双协议。 运行环境:Node.js 18+、pnpm、PostgreSQL、Redis。 ## 功能特性 ### 认证与账户 - JWT 双 Token 机制(Access Token + Refresh Token) - 基于 JTI 的 Token 黑名单撤销(支持登出后立即失效) - 多种登录方式:邮箱/短信验证码、密码登录 - 用户资料管理、密码重置、登录日志与失败限流 ### 验证码与通知 - 邮箱验证码:基于 BullMQ 的异步邮件队列,支持 SMTP 连通性校验 - 短信验证码:阿里云短信服务,支持注册/登录/重置密码等场景模板化 - 验证码防刷与过期管理 ### 会议管理 - 会议记录 CRUD、统计分析、批量操作 - 会议数据重处理与同步机制 - 支持 RESTful API 与 GraphQL 查询 ### 第三方集成 - **腾讯会议**:Webhook 事件接收(URL 校验/签名验证)、开放 API(录制/参会/转写/智能纪要) - **飞书**:多维表格 Bitable 双向同步(支持 upsert 去重)、Webhook 事件处理 - **OpenAI**:智能摘要、内容分析等 AI 能力集成 - **阿里云**:短信服务(Dysmsapi) ### 任务调度 - 基于 BullMQ 的异步任务队列(邮件发送、数据同步等) - 定时任务调度(@nestjs/schedule) ## 技术栈 - **框架**:NestJS 11 + TypeScript 5.7 - **数据库**:Prisma ORM 6 + PostgreSQL - **缓存/队列**:Redis + BullMQ + IORedis - **认证**:Passport + JWT + bcryptjs - **API 协议**:RESTful + GraphQL (Apollo Server) - **文档**:Swagger/OpenAPI 3.0(`/api`) - **测试**:Jest + Supertest(unit/integration/system/e2e,覆盖率 ≥80%) - **第三方 SDK**: - 腾讯会议 API - 飞书开放平台 SDK (@larksuiteoapi/node-sdk) - 阿里云短信 SDK (@alicloud/dysmsapi20170525) - OpenAI SDK - Nodemailer (邮件) ## 项目结构 ``` src/ ├── auth/ # 认证模块(按用例拆分服务) │ ├── services/ # register/login/password/token/auth-policy │ ├── strategies/ # JWT 策略、用户查询、Token 黑名单 │ ├── repositories/ # refresh-token/login-log │ ├── guards/ # JWT 守卫 │ ├── decorators/ # Public/CurrentUser 等装饰器 │ ├── dto/ # 请求/响应 DTO │ └── enums/ # auth-type/login-type/verification-type ├── user/ # 用户模块 │ ├── services/ # profile.service │ └── repositories/ # user.repository ├── verification/ # 验证码模块 │ ├── verification.service.ts │ ├── repositories/ # verification.repository │ └── enums/ # verification-type/scene ├── meeting/ # 会议业务模块 │ ├── meeting.service.ts │ ├── repositories/ # meeting.repository │ ├── dto/ # 会议 CRUD DTO │ └── utils/ # 数据转换工具 ├── hook-tencent-mtg/ # 腾讯会议 Webhook 模块 │ ├── controllers/ # webhook.controller(URL 校验/事件接收) │ ├── services/ # 事件处理服务 │ ├── interceptors/ # 签名验证拦截器 │ └── dto/ # Webhook 事件 DTO ├── lark-meeting/ # 飞书会议模块 │ ├── controllers/ # lark-webhook.controller │ ├── service/ # Bitable 同步服务 │ ├── adapter/ # 数据适配器 │ └── queue/ # 异步任务队列 ├── integrations/ # 第三方平台集成 │ ├── tencent-meeting/ # 腾讯会议 API 客户端 │ ├── lark/ # 飞书 SDK 封装(Bitable/Auth) │ ├── aliyun/ # 阿里云短信服务 │ ├── email/ # 邮件服务(Nodemailer) │ └── openai/ # OpenAI 服务 ├── mail/ # 邮件队列模块 │ ├── mail.service.ts # 邮件发送服务 │ └── mail.processor.ts # BullMQ 消费者 ├── task/ # 任务调度模块 │ ├── tasks.service.ts # 定时任务服务 │ └── task.processor.ts # 任务队列处理器 ├── redis/ # Redis 模块 ├── prisma/ # Prisma 服务 ├── configs/ # 配置文件(jwt/redis/aliyun/lark/tencent/openai) ├── common/ # 公共工具/枚举/邮件模板 ├── app.module.ts # 根模块 ├── app.resolver.ts # GraphQL Resolver └── main.ts # 应用入口 prisma/ ├── schema.prisma # 数据模型定义 ├── migrations/ # 数据库迁移 └── seed.ts # 数据填充脚本 test/ ├── unit/ # 单元测试(src/**/*.spec.ts) ├── integration/ # 集成测试(*.int-spec.ts) ├── system/ # 系统测试(*.spec.ts) └── e2e/ # 端到端测试(*.e2e-spec.ts) ``` **路径别名**:`@/` → `src/` ## 快速开始 1) 安装依赖 ```bash pnpm install ``` 2) 配置环境变量 复制 `.env.example` 为 `.env`,并按环境补充: 3) 初始化数据库 ```bash pnpm db:generate pnpm db:push # 或 pnpm db:migrate pnpm db:seed # 可选 ``` 4) 启动服务 ```bash pnpm start:dev # 开发 pnpm build && pnpm start:prod ``` 启动后: - 应用:`http://localhost:3000` - Swagger:`http://localhost:3000/api` ## 常用脚本 ```bash # 开发与构建 pnpm start:dev # 开发模式(watch) pnpm start:debug # 调试模式 pnpm build # 构建生产版本 pnpm start:prod # 运行生产版本 # 代码质量 pnpm lint # ESLint 检查并自动修复 pnpm format # Prettier 格式化 pnpm compodoc # 生成代码文档 # 测试(覆盖率阈值 ≥80%) pnpm test # 运行所有单元测试 pnpm test:unit # 仅单元测试 pnpm test:integration # 仅集成测试 pnpm test:system # 仅系统测试 pnpm test:e2e # 仅端到端测试 pnpm test:all # 运行所有测试套件 pnpm test:ci # CI 模式(all + coverage) pnpm test:cov # 生成覆盖率报告 pnpm test:watch # 监听模式 # 数据库管理 pnpm db:generate # 生成 Prisma Client pnpm db:push # 推送 schema 到数据库(开发) pnpm db:migrate # 创建并应用迁移(生产) pnpm db:studio # 打开 Prisma Studio pnpm db:seed # 填充种子数据 pnpm db:reset # 重置数据库(危险) pnpm db:drop # 删除所有数据 pnpm db:drop:force # 强制删除(跳过确认) pnpm db:seed:reset # 重置并重新填充 pnpm db:cleandata # 清理数据 pnpm db:backup # 备份数据库 # 工具脚本 pnpm validate:tencent-api # 验证腾讯会议 API 配置 ``` ## API 概览 ### 文档地址 - **Swagger UI**:`http://localhost:3000/api` - **GraphQL Playground**:`http://localhost:3000/graphql` ### RESTful API 端点 #### 认证模块 (`/api/auth`) - `POST /auth/register` - 用户注册(邮箱/手机号) - `POST /auth/login` - 用户登录(密码/验证码) - `POST /auth/refresh-token` - 刷新访问令牌 - `POST /auth/logout` - 登出(撤销 Token) - `POST /auth/reset-password` - 重置密码 #### 用户模块 (`/api/user`) - `GET /user/profile` - 获取当前用户资料 🔒 - `PUT /user/profile` - 更新用户资料 🔒 #### 验证码模块 (`/api/verification`) - `POST /verification/send` - 发送验证码(邮箱/短信) - `POST /verification/verify` - 验证验证码 #### 会议模块 (`/api/meeting`) - `GET /meeting` - 查询会议列表 🔒 - `GET /meeting/:id` - 获取会议详情 🔒 - `POST /meeting` - 创建会议记录 🔒 - `PUT /meeting/:id` - 更新会议记录 🔒 - `DELETE /meeting/:id` - 删除会议记录 🔒 - `GET /meeting/stats` - 会议统计分析 🔒 #### 邮件模块 (`/api/mail`) - `POST /mail/send` - 发送邮件(异步队列)🔒 - `GET /mail/test-connection` - 测试 SMTP 连接 🔒 #### Webhook 端点 - `GET /webhooks/tencent` - 腾讯会议 URL 校验 - `POST /webhooks/tencent` - 腾讯会议事件接收 - `POST /webhooks/lark` - 飞书事件接收 - `POST /webhooks/feishu` - 飞书事件接收(兼容别名) 🔒 = 需要 JWT Bearer Token 认证 ### Token 撤销机制(黑名单) 本项目实现了基于 JTI(JWT ID)的 Token 黑名单机制: - **工作原理**:每个 Access Token 和 Refresh Token 都包含唯一的 `jti` 标识 - **登出流程**:调用 `POST /auth/logout` 时,当前 Token 的 `jti` 会被加入黑名单,直至 Token 自然过期 - **验证流程**:所有受保护的接口都会检查 Token 的 `jti` 是否在黑名单中 - **刷新流程**:刷新 Token 前会验证 Refresh Token 是否已被撤销 - **存储方案**: - 默认:基于 Redis 的分布式黑名单(推荐生产环境) - 可选:内存黑名单(仅适用于单实例开发环境) - **过期清理**:黑名单条目会在 Token 过期后自动清理,避免内存泄漏 **多实例部署注意**:生产环境必须使用 Redis 等共享存储来同步黑名单状态。 ## 第三方集成说明 ### 腾讯会议 - **Webhook 事件**:支持 URL 校验、签名验证、事件解密 - **开放 API**:已封装录制管理、参会人员、转写服务、智能纪要等接口 - **IP 白名单**:腾讯 API 存在调用方 IP 限制,若遇到错误码 `500125`,需在腾讯会议后台添加服务器出口 IP - **验证工具**:运行 `pnpm validate:tencent-api` 测试 API 配置 ### 飞书(Lark) - **Bitable 同步**:支持双向数据同步,自动去重(基于唯一键 upsert) - **Webhook 事件**:接收飞书事件推送(兼容 `/webhooks/lark` 和 `/webhooks/feishu` 两个路径) - **认证方式**:使用 App ID + App Secret 获取 Tenant Access Token ### 阿里云短信 - **场景模板**:支持注册、登录、重置密码等多场景模板配置 - **防刷机制**:验证码发送频率限制与过期管理 - **SDK 版本**:使用 `@alicloud/dysmsapi20170525` 4.1.2 ### OpenAI - **集成能力**:智能摘要、内容分析等 AI 功能 - **配置灵活**:支持自定义 Base URL(兼容 Azure OpenAI 等代理服务) ## 开发规范 ### 代码风格 - **格式化**:Prettier(2 空格缩进、单引号、尾随逗号) - **Lint**:ESLint + @typescript-eslint + typescript-eslint 8.20 - **命名约定**: - 文件名:kebab-case(`user-profile.service.ts`) - 类/接口:PascalCase(`UserProfileService`) - 变量/函数:camelCase(`getUserProfile`) - 常量:UPPER_SNAKE_CASE(`JWT_SECRET`) - DTO 后缀:`CreateUserDto`、`UpdateUserDto` - 守卫后缀:`JwtAuthGuard` - 装饰器后缀:`@Public()`、`@CurrentUser()` ### 模块组织 - **按领域分组**:每个功能模块包含 controller/service/repository/dto/enums - **服务拆分**:按用例拆分服务(如 auth 模块拆分为 register/login/password/token 等服务) - **路径别名**:使用 `@/` 引用 `src/` 下的模块,避免相对路径地狱 - **共享代码**:可复用的集成适配器放在 `src/integrations/` ### 测试规范 - **测试框架**:Jest + Supertest - **测试分层**: - Unit:`src/**/*.spec.ts`(单元测试,覆盖率 ≥80%) - Integration:`test/integration/**/*.int-spec.ts`(集成测试) - System:`test/system/**/*.spec.ts`(系统测试) - E2E:`test/e2e/**/*.e2e-spec.ts`(端到端测试) - **覆盖率要求**:statements/branches/functions/lines 均 ≥80% - **CI 检查**:PR 前必须运行 `pnpm test:ci` 确保所有测试通过 ### Git 提交规范 遵循 Conventional Commits: ``` feat(meeting): 新增会议统计分析接口 fix(auth): 修复刷新令牌过期判断逻辑 refactor(user): 重构用户资料更新服务 test(verification): 补充验证码发送单元测试 chore(deps): 升级 Prisma 到 6.10.1 docs(readme): 更新 API 文档说明 ``` ### Pull Request 规范 - **标题**:遵循 Conventional Commits 格式 - **描述**:关联 Issue、说明变更内容、附上测试证据 - **检查清单**: - [ ] 通过 `pnpm lint` 检查 - [ ] 通过相关测试套件 - [ ] 更新 `.env.example`(如有新配置) - [ ] 运行数据库迁移(如有 schema 变更) - [ ] 更新 API 文档(如有接口变更) ## 安全与部署建议 - 切勿提交 `.env`;基于 `.env.example` 新增配置 - 生产环境务必更换并管理好 `JWT_*` 与第三方 Secret - 腾讯会议开放 API 建议配置服务器出口 IP 白名单 ## 安全与部署 ### 安全最佳实践 - **环境变量**:切勿提交 `.env` 文件,所有敏感配置基于 `.env.example` 管理 - **密钥管理**:生产环境必须更换所有默认密钥(`JWT_*`、第三方 Secret) - **Token 安全**: - Access Token 短期有效(推荐 15 分钟) - Refresh Token 长期有效(推荐 7 天) - 登出后立即撤销 Token(黑名单机制) - **IP 白名单**:腾讯会议 API 需配置服务器出口 IP - **密码策略**:使用 bcryptjs 加密,salt rounds ≥10 - **验证码防刷**:限制发送频率(60 秒/次)与有效期(5 分钟) ### 部署建议 - **多实例部署**:使用 Redis 共享 Token 黑名单与会话状态 - **数据库连接池**:配置合理的 Prisma 连接池大小 - **日志管理**:生产环境建议接入日志收集系统(如 ELK) - **监控告警**:监控 API 响应时间、错误率、队列积压等指标 - **备份策略**:定期备份数据库(`pnpm db:backup`) ### Docker 部署 ```bash # 构建镜像 docker build -t lulab-backend . # 使用 docker-compose 启动 docker-compose up -d # 阿里云环境 docker-compose -f docker-compose.aliyun.yml up -d ``` ## 许可 MIT License ## 贡献指南 欢迎提交 Issue 和 Pull Request! - 新功能开发:请先创建 Issue 讨论需求与设计 - Bug 修复:请附上复现步骤与环境信息 - 代码规范:遵循项目的 ESLint 与 Prettier 配置 - 测试覆盖:新增代码必须包含单元测试(覆盖率 ≥80%) 如需补充飞书 Webhook 的签名校验与完整事件处理,或添加新的会议平台接入,请创建 Issue 讨论与排期。