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

235 lines
7.3 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.

# 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. 记录日志但不泄露敏感信息