laobinghu 37742571ae feat: 完成项目初始化并重构部署流程
主要变更:
- 添加完整的项目结构和模块(admin、articles、comments、users、session、oauth2、email、moderation、analytics、jobs 等)
- 实现系统初始化 API(/init/status 和 /init/run)
- 重写部署流程:迁移到 package.json scripts,删除 Makefile
- 优化部署脚本:deploy.sh、healthcheck.sh、backup.sh、restore.sh、verify-env.sh
- 更新 README.md:简化文档,整合部署指南
- 优化 AGENTS.md:精简到约 150 行,包含完整的代码规范和命令速查
- 配置 Docker Compose 自动化部署(prisma migrate deploy + seed)
- 生成 OAuth2 RSA 密钥对支持
- 添加环境变量验证和数据库备份恢复功能
2026-03-28 16:53:25 +08:00

7.3 KiB
Raw Blame History

AGENTS.md - 智能编码助手指南

偏好设置

  • 使用中文回答问题
  • 代码变更前先阅读相关文件
  • 遵循项目现有架构和模式

命令速查

基础命令

pnpm install              # 安装依赖
pnpm build               # 构建应用
pnpm start:dev           # 开发服务器(热重载)
pnpm lint                # 代码检查(自动修复)
pnpm format              # 代码格式化

测试命令

pnpm test                           # 所有测试
pnpm test:watch                    # 监听模式
pnpm test:cov                      # 覆盖率报告
pnpm test -- path/to/testFile.spec.ts   # 单个测试文件
pnpm test -- -t "pattern"           # 匹配名称的测试
pnpm test:e2e                      # E2E 测试

数据库

pnpm prisma generate      # 生成 Prisma Client
pnpm prisma migrate dev   # 开发环境迁移
pnpm prisma:deploy        # 生产环境迁移
pnpm prisma:seed          # 运行种子数据

部署运维

pnpm run verify           # 验证环境配置
pnpm run deploy           # 生产环境一键部署
pnpm run deploy:dev       # 开发环境部署
pnpm run health           # 健康检查
pnpm run init:status      # 检查初始化状态(需 token
pnpm run backup           # 备份数据库
pnpm run logs:api         # 查看 API 日志
pnpm run shell            # 进入 API 容器

代码规范

TypeScript

  • 严格模式已启用(strict: true
  • 关键选项:noImplicitAnystrictNullChecks
  • 目标ES2023模块NodeNext装饰器已启用

导入顺序

  1. Node 内置模块
  2. 第三方库
  3. 内部模块(相对路径)

文件结构NestJS 模块)

src/modules/<module-name>/
├── <module>.module.ts
├── <module>.service.ts
├── <module>.controller.ts
├── dto/
│   ├── <entity>.dto.ts
│   └── ...
└── guards/、decorators/、processors/(可选)

命名约定

  • 文件kebab-caseadmin-comments.controller.ts
  • PascalCaseArticlesService
  • 方法/变量camelCase
  • 枚举PascalCase 名称UPPER_SNAKE 值
  • 常量UPPER_SNAKE
  • 接口PascalCase

DTO 与验证

  • 必须使用 class-validator 装饰器
  • 必填字段必填,可选字段加 @IsOptional()
  • 使用 @IsString()@IsInt()@IsEnum()@IsEmail()
  • 添加限制:@Length()@Min()@Max()
  • Create DTO必填字段Update DTO所有字段可选

服务层

  • @Injectable(),通过构造函数注入依赖
  • 异步操作使用 async/await
  • 记录日志但不吞噬异常
  • 返回 Plain Objects避免循环引用

控制器层

  • 使用 NestJS 装饰器:@Controller()@Get()@Post()@Put()@Delete()
  • 验证输入:@Body()@Query()@Param() 配合 DTO
  • 访问请求:@Req() 获取 session、用户、IP 等
  • 应用守卫:@UseGuards(RequireSessionUser)@RequireRole('admin')
  • 错误处理:未找到用 HttpStatus.NOT_FOUND,禁止访问用 HttpStatus.FORBIDDEN

守卫与装饰器

  • RequireSessionUser:从 session 加载用户到 req.user
  • RequireRoleRBAC 角色验证,配合 RequireRoleGuard 使用
  • @Throttler():对 /login/oauth2/token 限流

错误处理

  • 使用 HttpException 配合适当的 HTTP 状态码
  • 服务层用 Logger.error() 记录异常
  • 外部 API 调用必须用 try-catch 包裹,提供降级行为
  • 不暴露内部错误详情给客户端

日志规范

  • 使用 Logger from @nestjs/common
  • 实例化:new Logger(ClassName.name)
  • 日志级别:logdebugwarnerror
  • 禁止记录敏感数据,记录操作审计

数据库Prisma

  • Schemaprisma/schema.prisma
  • 通过 PrismaService 访问,生产用真实客户端,开发用内存 mock
  • Mock 必须实现完整 Prisma APIfindUniquefindManycreateupdatedeletecountaggregate
  • findMany 支持:whereincludeorderByskiptake
  • update 支持嵌套操作:{ viewCount: { increment: 1 } }

AI 内容审核OpenRouter

  • 使用 OpenAI 兼容的 chat completions 端点
  • 配置:AI_REVIEW_PROMPT_TEMPLATE 环境变量
  • 响应必须是 JSON{ decision: 'approved'|'rejected'|'suspicious', reason, score: 0-1 }
  • API 错误时降级到基于规则的审核

邮件服务Nodemailer + BullMQ

  • 仅使用 HTML 模板(可选纯文本备用),内联 CSS
  • 邮件任务通过 BullMQ 队列 email 排队
  • EmailProcessor 处理 send-email 任务
  • 所有邮件记录到 EmailMessage状态pending、sent、failed
  • 重试机制3 次尝试,指数退避

安全规范

  • Helmet 中间件已启用(安全头)
  • CORS生产环境仅允许 APP_BASE_URL
  • Session Cookie生产环境 SESSION_COOKIE_SECURE=trueHttpOnly=true
  • 限流:@Throttler() 应用于 /login/oauth2/token
  • 全局验证管道:自动转换、白名单、开发环境拒绝额外属性
  • 绝不记录敏感数据,所有凭据通过环境变量管理

管理后台 API

  • 所有 /admin/* 路由需要 @RequireRole('admin')
  • 参考 AdminCommentsController 模式
  • 分页:查询参数 pagelimit,响应包含 { items, total, page, limit, totalPages }

Swagger 文档

  • 非生产环境可访问 /api-docs
  • 使用 @nestjs/swagger 装饰器:@ApiProperty()@ApiBody()@ApiParam()@ApiQuery()@ApiBearerAuth()
  • 保持 DTO 简单,示例避免复杂嵌套对象

Docker 与部署

  • 镜像使用 Bun 运行时(oven/bun:1.1
  • 多阶段构建:builder + runner
  • Docker Compose 服务:postgresredisapi
  • 健康检查端点验证数据库和 Redis 连接
  • 启动时自动运行:prisma migrate deployprisma db seed

环境变量

必需配置(见 .env.example

DATABASE_URL              # PostgreSQL 连接
SESSION_COOKIE_SECRET     # Session 签名密钥(至少 32 位)
AI_API_KEY                # AI 服务 API Key
SMTP_HOST、SMTP_PORT、SMTP_USER、SMTP_PASS  # 邮件服务
REDIS_HOST                # Redis 地址
OAUTH2_TOKEN_SIGNING_PRIVATE_KEY、OAUTH2_TOKEN_SIGNING_PUBLIC_KEY  # RSA 密钥对(生产必填)

测试策略

  • 单元测试隔离测试服务层mock PrismaService
  • E2E 测试:使用 supertest 测试 HTTP 端点
  • 文件命名*.spec.ts*.test.ts
  • 位置:与源文件并列或 test/ 目录
  • 运行pnpm testpnpm test:watchpnpm test:cov

Git 与提交

  • 无强制提交规范,但请写清晰的提交信息
  • 禁止提交密钥和 .env 文件
  • 提交前运行 pnpm lintpnpm test

已知模式

  • 基于 session 的 Web 认证 + OAuth2 API 客户端
  • 评论审核:规则优先,可疑内容走 AI 异步审核
  • 文章查看数:{ viewCount: { increment: 1 } }
  • RBAC 角色:adminmoderatoruser
  • PrismaService mock确保所有模型实现完整 CRUD 方法

Cursor / Copilot 说明

本项目无特殊的 Cursor 或 Copilot 配置,请遵循上述指南。所有编码助手应:

  1. 遵守 TypeScript 严格模式
  2. 遵循 NestJS 最佳实践
  3. 使用 DTO 进行输入验证
  4. 正确使用 PrismaService
  5. 记录日志但不泄露敏感信息