主要变更: - 添加完整的项目结构和模块(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 密钥对支持 - 添加环境变量验证和数据库备份恢复功能
235 lines
7.3 KiB
Markdown
235 lines
7.3 KiB
Markdown
# AGENTS.md - 智能编码助手指南
|
||
|
||
## 偏好设置
|
||
|
||
- 使用中文回答问题
|
||
- 代码变更前先阅读相关文件
|
||
- 遵循项目现有架构和模式
|
||
|
||
---
|
||
|
||
## 命令速查
|
||
|
||
### 基础命令
|
||
|
||
```bash
|
||
pnpm install # 安装依赖
|
||
pnpm build # 构建应用
|
||
pnpm start:dev # 开发服务器(热重载)
|
||
pnpm lint # 代码检查(自动修复)
|
||
pnpm format # 代码格式化
|
||
```
|
||
|
||
### 测试命令
|
||
|
||
```bash
|
||
pnpm test # 所有测试
|
||
pnpm test:watch # 监听模式
|
||
pnpm test:cov # 覆盖率报告
|
||
pnpm test -- path/to/testFile.spec.ts # 单个测试文件
|
||
pnpm test -- -t "pattern" # 匹配名称的测试
|
||
pnpm test:e2e # E2E 测试
|
||
```
|
||
|
||
### 数据库
|
||
|
||
```bash
|
||
pnpm prisma generate # 生成 Prisma Client
|
||
pnpm prisma migrate dev # 开发环境迁移
|
||
pnpm prisma:deploy # 生产环境迁移
|
||
pnpm prisma:seed # 运行种子数据
|
||
```
|
||
|
||
### 部署运维
|
||
|
||
```bash
|
||
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`)
|
||
- 关键选项:`noImplicitAny`、`strictNullChecks`
|
||
- 目标: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-case(如 `admin-comments.controller.ts`)
|
||
- **类**:PascalCase(如 `ArticlesService`)
|
||
- **方法/变量**: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`
|
||
- `RequireRole`:RBAC 角色验证,配合 `RequireRoleGuard` 使用
|
||
- `@Throttler()`:对 `/login` 和 `/oauth2/token` 限流
|
||
|
||
### 错误处理
|
||
|
||
- 使用 `HttpException` 配合适当的 HTTP 状态码
|
||
- 服务层用 `Logger.error()` 记录异常
|
||
- 外部 API 调用必须用 try-catch 包裹,提供降级行为
|
||
- 不暴露内部错误详情给客户端
|
||
|
||
### 日志规范
|
||
|
||
- 使用 `Logger` from `@nestjs/common`
|
||
- 实例化:`new Logger(ClassName.name)`
|
||
- 日志级别:`log`、`debug`、`warn`、`error`
|
||
- 禁止记录敏感数据,记录操作审计
|
||
|
||
### 数据库(Prisma)
|
||
|
||
- Schema:`prisma/schema.prisma`
|
||
- 通过 `PrismaService` 访问,生产用真实客户端,开发用内存 mock
|
||
- Mock 必须实现完整 Prisma API:`findUnique`、`findMany`、`create`、`update`、`delete`、`count`、`aggregate`
|
||
- `findMany` 支持:`where`、`include`、`orderBy`、`skip`、`take`
|
||
- `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=true`、`HttpOnly=true`
|
||
- 限流:`@Throttler()` 应用于 `/login` 和 `/oauth2/token`
|
||
- 全局验证管道:自动转换、白名单、开发环境拒绝额外属性
|
||
- 绝不记录敏感数据,所有凭据通过环境变量管理
|
||
|
||
### 管理后台 API
|
||
|
||
- 所有 `/admin/*` 路由需要 `@RequireRole('admin')`
|
||
- 参考 `AdminCommentsController` 模式
|
||
- 分页:查询参数 `page`、`limit`,响应包含 `{ 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 服务:`postgres`、`redis`、`api`
|
||
- 健康检查端点验证数据库和 Redis 连接
|
||
- 启动时自动运行:`prisma migrate deploy` 和 `prisma db seed`
|
||
|
||
### 环境变量
|
||
|
||
必需配置(见 `.env.example`):
|
||
|
||
```env
|
||
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 test`、`pnpm test:watch`、`pnpm test:cov`
|
||
|
||
### Git 与提交
|
||
|
||
- 无强制提交规范,但请写清晰的提交信息
|
||
- 禁止提交密钥和 `.env` 文件
|
||
- 提交前运行 `pnpm lint` 和 `pnpm test`
|
||
|
||
### 已知模式
|
||
|
||
- 基于 session 的 Web 认证 + OAuth2 API 客户端
|
||
- 评论审核:规则优先,可疑内容走 AI 异步审核
|
||
- 文章查看数:`{ viewCount: { increment: 1 } }`
|
||
- RBAC 角色:`admin`、`moderator`、`user`
|
||
- PrismaService mock:确保所有模型实现完整 CRUD 方法
|
||
|
||
---
|
||
|
||
## Cursor / Copilot 说明
|
||
|
||
本项目无特殊的 Cursor 或 Copilot 配置,请遵循上述指南。所有编码助手应:
|
||
|
||
1. 遵守 TypeScript 严格模式
|
||
2. 遵循 NestJS 最佳实践
|
||
3. 使用 DTO 进行输入验证
|
||
4. 正确使用 PrismaService
|
||
5. 记录日志但不泄露敏感信息
|