主要修改: 1. 修复module-generator中服务重命名时的DI错误 - 对于重命名的服务,直接使用别名注册,避免TypeScript找不到原始名称 - 移除不必要的provide/useClass模式 2. 集成core层到主应用 - 在app.module.ts中导入wwjcloud-core的AppModule - 在wwjcloud-core/src/index.ts中导出AppModule 3. 构建结果 - 编译错误: 64+ -> 0 - 注册路由: 15 -> 678 - Docker服务全部正常启动 - API接口正常响应
9.6 KiB
9.6 KiB
WWJCloud NestJS 开发指导原则
基于 v0.1.1 版本真实项目结构分析制定
更新时间: 2025-01-27
适用范围: WWJCloud NestJS 项目开发
🎯 核心开发原则
1. 框架使用原则
- 框架层面: 100% 使用 NestJS 的方式和特性
- 业务层面: 与 Java 项目保持 100% 一致
- 数据层面: 与 Java 项目数据库结构 100% 一致
2. 开发约束条件
- ✅ 必须: 基于 Java 项目真实代码进行开发
- ✅ 必须: 基于真实数据库表结构进行映射
- ✅ 必须: 遵循项目既定的命名规范
- ❌ 禁止: 自创业务逻辑或数据结构
- ❌ 禁止: 编写骨架代码或 TODO 注释
- ❌ 禁止: 硬编码业务数据或配置
📁 项目结构规范
目录层级
src/
├── config/ # 配置管理层
│ ├── *.config.ts # 各类配置文件
│ ├── config.module.ts # 配置模块
│ └── *.entity.ts # 配置相关实体
├── common/ # 通用服务层
│ ├── base/ # 基础服务
│ ├── utils/ # 工具类
│ ├── interceptors/ # 拦截器
│ ├── guards/ # 守卫
│ └── pipes/ # 管道
├── core/ # 核心基础设施层
│ └── (待开发)
└── vendor/ # 第三方服务适配层
├── pay/ # 支付服务
├── sms/ # 短信服务
└── upload/ # 上传服务
🏷️ 命名规范标准
文件命名规范
1. 实体文件
- 格式:
kebab-case.entity.ts - 示例:
dynamic-config.entity.ts,sys-user.entity.ts - 说明: 使用短横线分隔,以
.entity.ts结尾
2. 服务文件
- 格式:
kebab-case.service.ts - 示例:
config-center.service.ts,pay.service.ts - 说明: 使用短横线分隔,以
.service.ts结尾
3. 控制器文件
- 格式:
kebab-case.controller.ts - 示例:
config-center.controller.ts,auth.controller.ts - 说明: 使用短横线分隔,以
.controller.ts结尾
4. 工具类文件
- 格式:
kebab-case.util.ts - 示例:
json.util.ts,string.util.ts - 说明: 使用短横线分隔,以
.util.ts结尾
5. 模块文件
- 格式:
kebab-case.module.ts - 示例:
config.module.ts,auth.module.ts - 说明: 使用短横线分隔,以
.module.ts结尾
6. DTO 文件
- 格式:
PascalCaseDto.ts - 示例:
CreateUserDto.ts,UpdateConfigDto.ts - 说明: 使用 PascalCase,以
Dto.ts结尾
类命名规范
1. 实体类
- 格式:
PascalCase - 示例:
DynamicConfig,SysUser,MemberLevel - 说明: 与数据库表名对应,使用 PascalCase
2. 服务类
- 格式:
PascalCase + Service - 示例:
ConfigCenterService,PayService,AuthService - 说明: 业务名称 + Service 后缀
3. 控制器类
- 格式:
PascalCase + Controller - 示例:
ConfigCenterController,AuthController - 说明: 业务名称 + Controller 后缀
4. 工具类
- 格式:
PascalCase + Util - 示例:
JsonUtil,StringUtil,DateUtil - 说明: 功能名称 + Util 后缀
5. DTO 类
- 格式:
操作动词 + 业务名称 + Dto - 示例:
CreateUserDto,UpdateConfigDto,QueryMemberDto - 说明: 明确表示操作类型和业务对象
方法命名规范
1. 业务方法
- 格式:
camelCase - 原则: 与 Java 项目方法名保持一致
- 示例:
getUserList(),addUser(),updateConfig()
2. 私有方法
- 格式:
camelCase - 示例:
private validateUser(),private formatData()
3. 生命周期方法
- 格式: 按 NestJS 标准
- 示例:
onModuleInit(),onApplicationBootstrap()
变量命名规范
1. 私有属性
- 格式:
private readonly camelCase - 示例:
private readonly logger,private readonly configService
2. 业务变量
- 格式:
camelCase - 原则: 与 Java 项目变量名保持一致
- 示例:
userId,userName,configKey
3. 常量
- 格式:
UPPER_SNAKE_CASE - 示例:
DEFAULT_PAGE_SIZE,MAX_RETRY_COUNT
数据库相关命名
1. 表名映射
- 原则: 与 Java 项目表名 100% 一致
- 示例:
nc_sys_config,nc_sys_user,nc_member_level - 说明: 不能修改任何表名或前缀
2. 字段名映射
- 原则: 与 Java 项目字段名 100% 一致
- 示例:
site_id,config_key,create_time,update_time - 说明: 不能修改任何字段名或类型
🔧 开发最佳实践
Nest DI 与导入规范(重要)
- DI 相关类(如
MetricsService、CacheService、LockService)统一使用深路径导入:@wwjcloud/wwjcloud-boot/infra/...。 - 禁止在 AI 模块中通过聚合路径
@wwjcloud/wwjcloud-boot导入上述 DI 类,避免符号不一致导致依赖解析失败。 - 优先使用“按类型注入”,仅在确有抽象需要时使用令牌,并确保令牌在提供方模块中唯一、稳定导出。
- 避免在运行期使用
ModuleRef.get动态解析,除非处理循环依赖或跨域解耦的极端场景。 - 约定:Boot 层模块负责提供与导出,业务模块仅按类型消费,不再重复定义别名提供者。
1. 依赖注入
@Injectable()
export class UserService {
constructor(
private readonly userRepository: Repository<User>,
private readonly configService: ConfigService,
private readonly logger: Logger,
) {}
}
2. 装饰器使用
@Controller('api/user')
@UseGuards(JwtAuthGuard)
export class UserController {
@Get('list')
@UseInterceptors(ResponseInterceptor)
async getUserList(@Query() query: QueryUserDto) {
// 实现逻辑
}
}
3. 异常处理
@Injectable()
export class UserService {
async findUser(id: number) {
const user = await this.userRepository.findOne({ where: { id } });
if (!user) {
throw new NotFoundException('用户不存在');
}
return user;
}
}
4. 数据验证
export class CreateUserDto {
@IsString()
@IsNotEmpty()
username: string;
@IsEmail()
email: string;
@IsOptional()
@IsString()
nickname?: string;
}
📋 开发检查清单
开发前检查
- 已查看对应的 Java 源码文件
- 已查看相关的数据库表结构
- 已理解真实的业务逻辑
- 已确认所有依赖关系
开发中检查
- 文件命名符合项目规范
- 类命名符合项目规范
- 方法命名与 Java 项目一致
- 数据库字段映射准确
- 业务逻辑与 Java 项目一致
开发后检查
- 代码可以正常编译
- 所有依赖正确注入
- 数据库操作正常
- API 接口功能正确
- 异常处理完善
🚫 常见错误避免
1. 命名错误
- ❌ 错误:
userController.ts(camelCase) - ✅ 正确:
user.controller.ts(kebab-case)
2. 文件结构错误
- ❌ 错误: 按技术层级划分目录
- ✅ 正确: 按业务模块划分目录
3. 业务逻辑错误
- ❌ 错误: 自创业务逻辑
- ✅ 正确: 基于 Java 项目真实代码
4. 数据库映射错误
- ❌ 错误: 修改表名或字段名
- ✅ 正确: 与 Java 项目 100% 一致
📚 参考资源
- 项目仓库: wwjcloud-nsetjs
- Java 项目: niucloud-java
- 数据库结构:
sql/wwjcloud.sql - NestJS 官方文档: https://nestjs.com/
- TypeORM 文档: https://typeorm.io/
本文档基于项目真实结构制定,请严格遵循以确保代码质量和项目一致性。
🔧 AI 恢复模块集成与测试
模块挂载
- 根应用:
AI_ENABLED=true时动态导入AiModule apps/api:直接导入AiModule,受GLOBAL_PREFIX=api影响- 开发阶段:
AiController使用@Public()便于无令牌验证;生产需加守卫或网关策略
路由与前缀
- 推荐统一使用
GLOBAL_PREFIX=api以避免基础设施路由状态码异常 - 端点示例:
GET /api/ai/recovery/statusGET /api/ai/recovery/simulate-failure?taskId=T1&severity=high&reason=devPOST /api/ai/recovery/process-onePOST /api/ai/recovery/drain
队列驱动策略
- 开发:
QUEUE_DRIVER=memory,避免 Kafka/Redis 干扰,快速闭环 - 生产:推荐
redis或企业内部kafka,实现跨进程/跨实例协同
依赖注入规范(与 DI 章节一致)
- Boot 层 DI 使用深路径导入:
@wwjcloud/wwjcloud-boot/infra/... - 业务模块按类型消费,避免重复定义令牌与别名
- 事件监听器与服务在
AiModule内提供并导出:AiSelfHealListener、AiRecoveryService
本地端到端验证
# 查看初始队列大小
curl -s http://localhost:3001/api/ai/recovery/status
# 模拟失败(入队)
curl -s "http://localhost:3001/api/ai/recovery/simulate-failure?taskId=T1&severity=high&reason=dev"
# 再次查看(应增长)
curl -s http://localhost:3001/api/ai/recovery/status
# 处理一个(收敛)
curl -s -X POST http://localhost:3001/api/ai/recovery/process-one
# 清空队列(可选)
curl -s -X POST http://localhost:3001/api/ai/recovery/drain
测试建议
- e2e:覆盖失败事件触发 → 入队 → 处理 → 收敛的闭环
- 异常过滤:
GLOBAL_PREFIX=api下/api/metrics、/api/health保留原始状态码 - 队列驱动兼容:
memory、redis、kafka三模式最小用例
参考
- 详细指南:
docs/AI-RECOVERY-DEV.md - 工作流规范:
docs/AI-WORKFLOW-GUIDE.md