Files
plates-server/.kilocode/rules/memory-bank/tech.md
richarjiang 1fe969aa97 feat(diet-records): 修复营养成分分析记录查询参数验证和类型转换
修复GET请求查询参数验证装饰器缺失问题,添加正确的class-validator装饰器
在控制器中实现查询参数类型转换,确保数字参数正确处理
更新技术文档,添加DTO验证装饰器编写规范和GET请求参数处理指南
2025-10-16 16:26:58 +08:00

12 KiB
Raw Blame History

技术栈与开发环境

核心技术栈

后端框架

  • NestJS 11.x: TypeScript 原生支持的企业级 Node.js 框架
  • TypeScript 5.7+: 类型安全的 JavaScript 超集
  • Express.js: 底层 HTTP 服务器框架NestJS 内置)

数据库与 ORM

  • MySQL 8.0: 主数据库,支持 JSON 字段和全文索引
  • Sequelize 6.x: ORM 框架,支持 TypeScript 和迁移
  • Sequelize-typescript: TypeScript 类型定义和装饰器支持

认证与安全

  • JWT (jsonwebtoken): 无状态身份认证
  • Apple Sign-In: iOS 生态登录集成
  • crypto-js: 客户端/服务端加密工具
  • AES-256-GCM: 敏感数据加密标准

AI 与机器学习

  • OpenAI SDK: AI 模型调用统一接口
  • 通义千问 (阿里云): 主要 AI 模型服务
  • qwen-vl-max: 视觉识别专用模型
  • qwen-flash: 快速对话模型

文件存储与云服务

  • 腾讯云 COS: 对象存储服务
  • qcloud-cos-sts: 临时访问凭证管理
  • APNs (Apple Push Notification): iOS 推送服务
  • @parse/node-apn: APNs 服务端 SDK

开发工具与环境

包管理与构建

  • yarn: 包管理器(支持工作空间)
  • npm: 备用包管理器
  • SWC: 快速 TypeScript 编译器
  • ts-node: 开发时 TypeScript 执行

代码质量与规范

  • ESLint 9.x: 代码质量检查
  • Prettier: 代码格式化
  • TypeScript: 静态类型检查
  • Husky: Git hooks 管理(未配置但推荐)

测试框架

  • Jest 29.x: 单元测试和集成测试
  • Supertest: HTTP 接口测试
  • ts-jest: TypeScript 测试支持

部署与运维

  • PM2: Node.js 进程管理器
  • Docker: 容器化部署(未完全实现)
  • Nginx: 反向代理和负载均衡
  • Winston: 结构化日志记录

项目配置文件

核心配置

  • package.json: 项目依赖和脚本定义
  • tsconfig.json: TypeScript 编译配置
  • nest-cli.json: NestJS CLI 配置
  • ecosystem.config.js: PM2 集群配置

环境配置

  • .env: 开发环境变量(不提交到版本控制)
  • .env.glm.example: 环境变量模板
  • eslint.config.mjs: ESLint 配置

部署配置

  • deploy.sh: 完整部署脚本
  • deploy-optimized.sh: 优化部署脚本
  • start.sh: 服务启动脚本

开发环境设置

本地开发要求

  • Node.js: >= 18.0.0
  • MySQL: >= 8.0
  • yarn: 最新稳定版
  • Git: 版本控制

开发命令

# 安装依赖
yarn install

# 开发模式启动
yarn start:dev

# 构建项目
yarn build

# 生产模式启动
yarn start:prod

# 运行测试
yarn test

# 代码检查
yarn lint

# 代码格式化
yarn format

PM2 管理命令

# 启动开发环境
yarn pm2:start:dev

# 启动生产环境
yarn pm2:start

# 查看状态
yarn pm2:status

# 查看日志
yarn pm2:logs

# 重启服务
yarn pm2:restart

# 停止服务
yarn pm2:stop

环境变量配置

必需的环境变量

# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_DATABASE=pilates_db

# JWT 配置
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=7d
REFRESH_TOKEN_SECRET=your_refresh_token_secret
REFRESH_TOKEN_EXPIRES_IN=30d

# Apple 认证配置
APPLE_BUNDLE_ID=com.yourcompany.pilates
APPLE_KEY_ID=your_apple_key_id
APPLE_ISSUER_ID=your_apple_issuer_id
APPLE_PRIVATE_KEY_PATH=path/to/private/key.p8
APPLE_APP_SHARED_SECRET=your_app_shared_secret

# AI 服务配置
DASHSCOPE_API_KEY=your_dashscope_api_key
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
DASHSCOPE_MODEL=qwen-flash
DASHSCOPE_VISION_MODEL=qwen-vl-max

# 加密配置
ENCRYPTION_KEY=your-32-character-secret-key-here

# 腾讯云 COS 配置
COS_SECRET_ID=your_cos_secret_id
COS_SECRET_KEY=your_cos_secret_key
COS_REGION=your_cos_region
COS_BUCKET=your_cos_bucket

# RevenueCat 配置
REVENUECAT_PUBLIC_API_KEY=your_revenuecat_public_key
REVENUECAT_SECRET_API_KEY=your_revenuecat_secret_key

# 服务配置
PORT=3002
NODE_ENV=development

数据库架构

字符集和排序规则

  • 字符集: utf8mb4 (支持完整 Unicode包括 emoji)
  • 排序规则: utf8mb4_unicode_ci (不区分大小写)
  • 时区: 统一使用 UTC 时间

连接配置

  • 连接池: 最大连接数 10最小连接数 0
  • 超时设置: 查询超时 30 秒,连接超时 10 秒
  • 自动重连: 启用连接失败自动重连

迁移策略

  • 自动同步: 开发环境使用 synchronize: true
  • 生产环境: 使用 SQL 脚本手动执行迁移
  • 版本控制: SQL 脚本存储在 sql-scripts/ 目录

API 设计规范

RESTful 设计原则

  • 资源导向: 使用名词表示资源
  • HTTP 方法: GET/POST/PUT/DELETE 对应 CRUD 操作
  • 状态码: 标准 HTTP 状态码 + 业务错误码
  • 统一响应: 使用 ApiResponseDto 包装所有响应

接口版本控制

  • 路径版本: /api/v1/users (推荐)
  • 查询参数: ?version=1 (备选)
  • Header 版本: Accept: application/vnd.api+json;version=1 (备选)

请求响应格式

// 成功响应
{
  "code": 0,
  "message": "操作成功",
  "data": { ... }
}

// 错误响应
{
  "code": 1,
  "message": "错误描述",
  "data": null
}

日志管理

日志级别

  • ERROR: 错误信息,需要立即关注
  • WARN: 警告信息,可能的问题
  • INFO: 一般信息,重要业务操作
  • DEBUG: 调试信息,详细的执行流程

日志配置

  • Winston: 结构化日志记录
  • 日志轮转: 按日期和大小自动轮转
  • 多输出: 同时输出到文件和控制台
  • 格式化: JSON 格式便于分析

日志文件

  • logs/error.log: 错误日志
  • logs/output.log: 一般输出日志
  • logs/combined.log: 合并日志

安全最佳实践

数据加密

  • 传输加密: 强制 HTTPS/TLS 1.3
  • 存储加密: 敏感字段 AES-256-GCM 加密
  • 密钥管理: 环境变量 + 定期轮换
  • 哈希算法: bcrypt 处理密码(如需要)

输入验证

  • class-validator: DTO 数据验证
  • class-transformer: 数据转换和清理
  • SQL 注入防护: Sequelize ORM 自动防护
  • XSS 防护: 输入清理和输出编码

DTO 验证装饰器编写规范

基本原则

  • 所有 DTO 类必须同时包含 @ApiPropertyclass-validator 装饰器
  • @ApiProperty 用于 Swagger 文档生成,class-validator 用于数据验证
  • 缺少验证装饰器会导致参数校验失败,使 API 端点无法正常工作

必需要导入的验证装饰器

import { IsOptional, IsDateString, IsNumber, IsString, IsNotEmpty, IsEnum, MaxLength, Min, Max } from 'class-validator';

常用字段验证规则

  • 分页参数:在 GET 请求中使用 @IsOptional() + @IsString(),在控制器中转换为数字;在 POST/PUT 请求中使用 @IsOptional() + @IsNumber()
  • 日期参数startDateendDate 使用 @IsOptional() + @IsDateString()
  • 字符串参数:使用 @IsOptional() + @IsString(),必要时添加 @MaxLength()
  • 枚举参数:使用 @IsOptional() + @IsEnum(EnumType)
  • 必填字段:使用 @IsNotEmpty() 而不是只使用 @IsString()

GET 请求参数特殊处理

重要说明GET 请求的查询参数Query Parameters在 HTTP 协议中都是字符串类型,即使看起来是数字(如 ?page=1&limit=20)。因此需要特殊处理:

GET 请求 DTO 定义

export class GetRecordsQueryDto {
  @ApiProperty({ description: '页码', example: 1, required: false })
  @IsOptional()
  @IsString()  // 注意GET 请求中使用 @IsString() 而不是 @IsNumber()
  page?: string;

  @ApiProperty({ description: '每页数量', example: 20, required: false })
  @IsOptional()
  @IsString()  // 注意GET 请求中使用 @IsString() 而不是 @IsNumber()
  limit?: string;
}

控制器中的类型转换

async getRecords(
  @Query() query: GetRecordsQueryDto,
  @CurrentUser() user: AccessTokenPayload,
): Promise<RecordsResponseDto> {
  // 转换查询参数中的字符串为数字
  const convertedQuery = {
    page: query.page ? parseInt(query.page, 10) : undefined,
    limit: query.limit ? parseInt(query.limit, 10) : undefined,
    // 其他字符串参数保持不变
    startDate: query.startDate,
    endDate: query.endDate,
    status: query.status,
  };

  const result = await this.service.getRecords(user.sub, convertedQuery);
  return result;
}

POST/PUT 请求 DTO 定义(对比):

export class CreateRecordDto {
  @ApiProperty({ description: '数量', example: 10 })
  @IsNumber()  // POST/PUT 请求中可以直接使用 @IsNumber()
  quantity: number;
}

正确示例GET 请求)

export class GetRecordsQueryDto {
  @ApiProperty({ description: '页码', example: 1, required: false })
  @IsOptional()
  @IsString()  // GET 请求中使用 @IsString()
  page?: string;

  @ApiProperty({ description: '每页数量', example: 20, required: false })
  @IsOptional()
  @IsString()  // GET 请求中使用 @IsString()
  limit?: string;

  @ApiProperty({ description: '开始日期', example: '2023-01-01', required: false })
  @IsOptional()
  @IsDateString()
  startDate?: string;

  @ApiProperty({ description: '状态', example: 'active', required: false })
  @IsOptional()
  @IsString()
  status?: string;
}

正确示例POST/PUT 请求)

export class CreateRecordDto {
  @ApiProperty({ description: '数量', example: 10 })
  @IsNumber()  // POST/PUT 请求中可以直接使用 @IsNumber()
  quantity: number;

  @ApiProperty({ description: '名称', example: '测试' })
  @IsString()
  @IsNotEmpty()
  name: string;
}

常见错误

  • 只有 @ApiProperty 而缺少 class-validator 装饰器
  • GET 请求中的数字参数使用 @IsNumber() 而不是 @IsString()
  • 使用 @IsString() 但没有 @IsOptional() 处理可选参数
  • 日期字段没有使用 @IsDateString() 验证
  • GET 请求中忘记在控制器进行类型转换,导致服务层接收到字符串而不是数字
  • 类型转换时没有进行空值检查,可能导致 parseInt(undefined) 返回 NaN

访问控制

  • JWT 认证: 无状态 Token 认证
  • 权限守卫: 基于角色的访问控制
  • 速率限制: 防止 API 滥用和攻击
  • CORS 配置: 跨域请求安全控制

性能优化

数据库优化

  • 索引策略: 为常用查询字段添加索引
  • 查询优化: 避免 N+1 查询问题
  • 连接池: 合理配置数据库连接池
  • 分页查询: 大数据集分页处理

缓存策略

  • 内存缓存: 热点数据内存缓存
  • 查询缓存: 数据库查询结果缓存
  • CDN 缓存: 静态资源 CDN 分发
  • 浏览器缓存: 合理设置 Cache-Control

代码优化

  • 异步处理: 使用 async/await 处理异步操作
  • 批量操作: 减少数据库往返次数
  • 流式处理: 大数据量流式处理
  • 懒加载: 按需加载模块和数据

监控与调试

应用监控

  • PM2 监控: 进程状态和资源使用
  • 健康检查: 应用健康状态接口
  • 性能指标: 响应时间和吞吐量
  • 错误追踪: 异常自动收集和报告

调试工具

  • Source Map: 生产环境调试支持
  • 日志分析: 结构化日志查询和分析
  • API 文档: Swagger 自动生成文档
  • 数据库工具: MySQL Workbench/Sequel Pro

部署架构

服务器环境

  • 操作系统: Ubuntu 20.04 LTS
  • Node.js: 18.x LTS 版本
  • 数据库: MySQL 8.0
  • Web 服务器: Nginx 1.18+

部署流程

  1. 代码构建: 本地或服务器端 TypeScript 编译
  2. 依赖安装: 生产依赖安装和锁定
  3. 数据库迁移: SQL 脚本执行和数据迁移
  4. 服务启动: PM2 集群模式启动应用
  5. 健康检查: 验证服务正常运行

容器化部署(未来)

  • Docker: 应用容器化
  • Docker Compose: 多服务编排
  • Kubernetes: 容器编排管理
  • CI/CD: 自动化构建和部署流水线