diff --git a/wwjcloud-nest-v1/README.md b/wwjcloud-nest-v1/README.md
index 8f0f65f7..180872c6 100644
--- a/wwjcloud-nest-v1/README.md
+++ b/wwjcloud-nest-v1/README.md
@@ -1,98 +1,144 @@
+# WWJCloud NestJS v1 Framework
+
-
+
-[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
-[circleci-url]: https://circleci.com/gh/nestjs/nest
-
- A progressive Node.js framework for building efficient and scalable server-side applications.
-
-
-
-
-
-
-
-
-
-
-
+
+ 基于 NestJS v11 的企业级全栈框架,超越 Java 的企业能力
-
-## Description
+## 🎯 项目概述
-[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
+WWJCloud NestJS v1 是一个基于 NestJS v11 构建的企业级全栈框架,旨在提供超越 Java 框架的企业能力,包括:
-## Project setup
+- **🚀 高性能**: 基于 NestJS v11 的现代化架构
+- **🤖 AI 治理**: 内置 AI 自愈、性能优化和安全防护
+- **🏗️ 企业级**: 完整的基础设施层(Boot + AI + Core)
+- **🔄 无缝迁移**: Java 到 NestJS 的一键迁移工具
-```bash
-$ npm install
+## 📁 项目结构
+
+```
+wwjcloud-nest-v1/
+├── wwjcloud/ # NestJS 后端核心
+│ ├── apps/api/ # API 应用入口
+│ ├── libs/ # 核心库
+│ │ ├── wwjcloud-boot/ # 基础设施层
+│ │ ├── wwjcloud-ai/ # AI 治理层
+│ │ ├── wwjcloud-core/ # 业务核心层
+│ │ └── wwjcloud-addon/# 插件扩展层
+│ ├── src/ # 业务代码
+│ └── test/ # 测试文件
+├── admin/ # 管理端前端
+├── web/ # PC端前端
+├── uni-app-x/ # 移动端前端 (uni-app x)
+├── wwjcloud-web/ # 统一部署目录
+├── docker/ # Docker 配置
+├── docs/ # 文档目录
+└── tools/ # 开发工具
+ ├── tools-v1/ # Java 迁移工具
+ └── tools-uni/ # uni-app 迁移工具
```
-## Compile and run the project
+## 🚀 快速开始
+### 环境要求
+- Node.js 20+
+- Docker & Docker Compose
+- MySQL 8.0+
+- Redis 7+
+
+### 安装依赖
```bash
-# development
-$ npm run start
+# 安装后端依赖
+cd wwjcloud
+npm install
-# watch mode
-$ npm run start:dev
-
-# production mode
-$ npm run start:prod
+# 安装前端依赖
+cd admin
+npm install
```
-## Run tests
-
+### 开发环境启动
```bash
-# unit tests
-$ npm run test
+# 启动后端服务
+cd wwjcloud
+npm run start:dev
-# e2e tests
-$ npm run test:e2e
-
-# test coverage
-$ npm run test:cov
+# 启动前端管理面板
+cd admin
+npm run dev
```
-## Deployment
-
-When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information.
-
-If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps:
-
+### Docker 全栈启动
```bash
-$ npm install -g @nestjs/mau
-$ mau deploy
+cd docker
+docker-compose up -d
```
-With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure.
+## 📚 详细文档
-## Resources
+### 核心文档
+- **[V1 框架指南](docs/V1-GUIDE.md)** - 📖 完整开发与运维指南
+- **[AI 能力说明](docs/AI-CAPABILITY-ROADMAP.md)** - 🤖 AI 治理能力详解
+- **[基础设施配置](docs/V11-INFRA-SETUP.md)** - 🏗️ Boot 层配置指南
-Check out a few resources that may come in handy when working with NestJS:
+### 开发工具
+- **[Java 迁移工具](tools/tools-v1/README.md)** - ⚡ Java 到 NestJS 迁移
+- **[uni-app 迁移](tools/tools-uni/README.md)** - 📱 uni-app 到 uni-app-x 迁移
-- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework.
-- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy).
-- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/).
-- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks.
-- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com).
-- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com).
-- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs).
-- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com).
+## 🔧 核心特性
-## Support
+### 基础设施层 (Boot)
+- **请求追踪**: 全局请求 ID 和链路追踪
+- **健康检查**: 多层次健康检查端点
+- **指标监控**: Prometheus 指标暴露
+- **缓存系统**: 多级缓存和分布式锁
+- **国际化**: 完整的 i18n 支持
-Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
+### AI 治理层 (AI)
+- **自愈系统**: 自动故障检测和恢复
+- **性能优化**: 智能缓存和查询优化
+- **安全防护**: 异常检测和访问控制
+- **预测分析**: 系统负载和性能预测
-## Stay in touch
+### 业务核心层 (Core)
+- **模块化架构**: 完整的业务模块体系
+- **统一 API**: 标准化的接口规范
+- **数据层**: TypeORM 实体和仓储
+- **权限系统**: RBAC 权限控制
-- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec)
-- Website - [https://nestjs.com](https://nestjs.com/)
-- Twitter - [@nestframework](https://twitter.com/nestframework)
+## 🧪 测试与部署
-## License
+### 单元测试
+```bash
+cd wwjcloud
+npm run test
+npm run test:e2e
+```
-Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).
+### 性能测试
+```bash
+cd docker
+docker-compose up k6 # K6 压测
+```
+
+### 生产部署
+```bash
+# 构建镜像
+docker-compose build
+
+# 启动生产环境
+docker-compose -f docker-compose.prod.yml up -d
+```
+
+## 🤝 贡献指南
+
+1. 查看 [开发规范](docs/CONSISTENCY-GUIDE.md)
+2. 遵循 [命名约定](docs/LANG-GUIDE.md)
+3. 提交时请使用标准的 commit 格式
+
+## 📄 许可证
+
+本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
diff --git a/wwjcloud-nest-v1/docker/Dockerfile b/wwjcloud-nest-v1/docker/Dockerfile
index 0e3a1147..e8fbc947 100644
--- a/wwjcloud-nest-v1/docker/Dockerfile
+++ b/wwjcloud-nest-v1/docker/Dockerfile
@@ -1,7 +1,7 @@
# Optimized Dockerfile using local build artifacts
FROM node:20-alpine AS runner
-WORKDIR /app/wwjcloud-nest-v1
+WORKDIR /app/wwjcloud
ENV NODE_ENV=production
# Copy pre-built application from local
diff --git a/wwjcloud-nest-v1/docker/docker-compose.yml b/wwjcloud-nest-v1/docker/docker-compose.yml
index 17607158..c1ca9093 100644
--- a/wwjcloud-nest-v1/docker/docker-compose.yml
+++ b/wwjcloud-nest-v1/docker/docker-compose.yml
@@ -53,7 +53,7 @@ services:
# ========================================
api:
build:
- context: ../wwjcloud-nest-v1
+ context: ../wwjcloud
dockerfile: ../docker/Dockerfile
container_name: wwjcloud-api-v1
restart: unless-stopped
diff --git a/wwjcloud-nest-v1/docs/AI-CAPABILITY-ROADMAP.md b/wwjcloud-nest-v1/docs/AI-CAPABILITY-ROADMAP.md
index 9eebfba4..e90f6d59 100644
--- a/wwjcloud-nest-v1/docs/AI-CAPABILITY-ROADMAP.md
+++ b/wwjcloud-nest-v1/docs/AI-CAPABILITY-ROADMAP.md
@@ -35,7 +35,7 @@
#### 2. 智能代码生成 (@wwjcloud/smart-generator)
```typescript
-// tools-v1/php-tools/ 已实现 ✅
+// tools/tools-v1/java-tools/ 已实现 ✅
├── migration-coordinator.js // 迁移协调器
├── generators/
│ ├── controller-generator.js // 控制器生成器
@@ -50,7 +50,7 @@
│ └── module-generator.js // 模块生成器
// 核心功能
-- PHP → NestJS 完整迁移
+- Java → NestJS 完整迁移
- 智能业务逻辑转换
- 质量门禁检查
- 增量更新支持
@@ -171,7 +171,7 @@ libs/wwjcloud-security-ai/src/
#### 4.1 扩展智能代码生成
```typescript
-// 增强 tools-v1/php-tools/
+// 增强 tools/tools-v1/java-tools/
├── ai-enhanced/
│ ├── intelligent-converter.js // 智能转换器
│ ├── pattern-learner.js // 模式学习器
diff --git a/wwjcloud-nest-v1/docs/I18N-GUIDE.md b/wwjcloud-nest-v1/docs/I18N-GUIDE.md
deleted file mode 100644
index 54a755cd..00000000
--- a/wwjcloud-nest-v1/docs/I18N-GUIDE.md
+++ /dev/null
@@ -1,237 +0,0 @@
-# 多语言(i18n)实现与对齐指南(Java-first)
-
-本指南说明在 `wwjcloud-nest-v1` 中接入与落地国际化(i18n),并与 Java 项目的语言包与 key 规范保持一致(Java-first)。PHP 只作为业务逻辑层使用同样的 key 获取文案,不维护独立规范。
-
-## 背景与原则
-- 单一标准:以 Java 的 `.properties` 和模块化规范为源头标准(source of truth)。
-- 统一 key:点分层级命名,如 `common.success`、`error.auth.invalid_token`。
-- 统一语言:后端统一 `zh-CN`、`en-US`,默认 `zh-CN`。
-- 语言协商:优先级 `?lang=` > `Accept-Language` > 默认。
-- 兜底策略:未命中返回原始 key(与 Java/PHP 行为一致)。
-- 历史兼容:仅为极少量老 key 建立别名映射(如 `SUCCESS` → `common.success`)。
-
-## 目录结构(Nest 项目)
-建议在本项目内遵循以下结构:
-```
-wwjcloud-nest-v1/
- apps/api/src/lang/
- zh-CN/
- common.json
- error.json
- user.json
- en-US/
- common.json
- error.json
- user.json
- libs/wwjcloud-boot/src/infra/lang/
- boot-i18n.module.ts
- resolvers.ts # 可选:自定义解析器集合(Query/Header)
- apps/api/src/common/
- interceptors/response.interceptor.ts # 使用 i18n 翻译成功提示
- filters/http-exception.filter.ts # 使用 i18n 翻译错误提示
- apps/api/src/app.module.ts # 导入 BootI18nModule
-```
-
-## 接入步骤
-
-### 1) 安装依赖
-使用你项目的包管理器安装:
-```
-pnpm add @nestjs/i18n i18n accept-language-parser
-# 或
-npm i @nestjs/i18n i18n accept-language-parser
-```
-
-### 2) 创建 i18n 模块(BootI18nModule)
-文件:`libs/wwjcloud-boot/src/infra/lang/boot-i18n.module.ts`
-```ts
-import { Global, Module } from '@nestjs/common';
-import { I18nModule, I18nJsonParser, HeaderResolver, QueryResolver } from '@nestjs/i18n';
-import { join } from 'path';
-
-@Global()
-@Module({
- imports: [
- I18nModule.forRoot({
- fallbackLanguage: 'zh-CN',
- parser: I18nJsonParser,
- parserOptions: {
- path: join(process.cwd(), 'wwjcloud-nest-v1/apps/api/src/lang'),
- watch: true,
- },
- resolvers: [
- { use: QueryResolver, options: ['lang'] },
- new HeaderResolver(), // 默认读取 'Accept-Language'
- ],
- }),
- ],
- exports: [I18nModule],
-})
-export class BootI18nModule {}
-```
-
-### 3) 在 AppModule 导入(推荐使用 BootLangModule 软别名)
-文件:`apps/api/src/app.module.ts`
-```ts
-import { Module } from '@nestjs/common';
-import { BootLangModule } from '@libs/wwjcloud-boot/src/infra/lang/boot-lang.module';
-
-@Module({
- imports: [BootLangModule /* 以及其他模块 */],
-})
-export class AppModule {}
-```
-
-### 4) 响应拦截器使用 i18n
-文件:`apps/api/src/common/interceptors/response.interceptor.ts`
-```ts
-import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
-import { I18nService } from '@nestjs/i18n';
-import { Observable, map } from 'rxjs';
-
-@Injectable()
-export class ResponseInterceptor implements NestInterceptor {
- constructor(private readonly i18n: I18nService) {}
-
- intercept(ctx: ExecutionContext, next: CallHandler): Observable {
- const req = ctx.switchToHttp().getRequest();
- return next.handle().pipe(
- map((original) => {
- const { code = 0, data = null, msg_key } = original ?? {};
- const key = msg_key || 'common.success';
- const msg = this.i18n.translate(key, {
- lang: req.i18nLang, // 来自解析器(Query/Header)
- defaultValue: key,
- });
- return { code, msg_key: key, msg, data };
- })
- );
- }
-}
-```
-
-### 5) 异常过滤器使用 i18n
-文件:`apps/api/src/common/filters/http-exception.filter.ts`
-```ts
-import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
-import { I18nService } from '@nestjs/i18n';
-
-@Catch()
-export class HttpExceptionFilter implements ExceptionFilter {
- constructor(private readonly i18n: I18nService) {}
-
- catch(exception: unknown, host: ArgumentsHost) {
- const ctx = host.switchToHttp();
- const req = ctx.getRequest();
- const res = ctx.getResponse();
-
- let code = 500;
- let msgKey = 'error.common.unknown';
- let args: Record | undefined;
-
- if (exception instanceof HttpException) {
- const response: any = exception.getResponse();
- code = exception.getStatus();
- msgKey = response?.msg_key || msgKey;
- args = response?.args;
- }
-
- const msg = this.i18n.translate(msgKey, {
- lang: req.i18nLang,
- defaultValue: msgKey,
- args,
- });
-
- res.status(code).json({ code, msg_key: msgKey, msg, data: null });
- }
-}
-```
-
-### 6) 语言资源示例
-文件:`apps/api/src/lang/zh-CN/common.json`
-```json
-{
- "success": "操作成功"
-}
-```
-文件:`apps/api/src/lang/en-US/common.json`
-```json
-{
- "success": "Success"
-}
-```
-文件:`apps/api/src/lang/zh-CN/error.json`
-```json
-{
- "auth": { "invalid_token": "令牌无效或已过期" },
- "common": { "unknown": "系统繁忙,请稍后重试" }
-}
-```
-文件:`apps/api/src/lang/en-US/error.json`
-```json
-{
- "auth": { "invalid_token": "Invalid or expired token" },
- "common": { "unknown": "Service is busy, please try later" }
-}
-```
-文件:`apps/api/src/lang/zh-CN/user.json`
-```json
-{
- "profile": { "updated": "资料已更新" }
-}
-```
-文件:`apps/api/src/lang/en-US/user.json`
-```json
-{
- "profile": { "updated": "Profile updated" }
-}
-```
-
-### 7) 历史 key 别名(可选)
-在拦截器或统一工具内对少量老 key 做映射:
-```ts
-const aliasMap = new Map([
- ['SUCCESS', 'common.success'],
-]);
-
-function mapAlias(key: string) { return aliasMap.get(key) || key; }
-```
-
-### 8) 使用示例(Controller 返回约定)
-```ts
-return { code: 0, msg_key: 'user.profile.updated', data: { id: 1 } };
-```
-
-## 语言协商与 DI 导入规范
-- 解析优先级:`Query(lang)` > `Header(Accept-Language)` > 默认 `zh-CN`。
-- DI 与导入:推荐使用 `BootLangModule`(底层为 `BootI18nModule`)仅在 `AppModule` 里导入一次(全局模块),遵循项目的「Nest DI 与导入规范」。拦截器与过滤器以 Provider 方式注入 `I18nService`。
-
-## 测试与验证
-- 默认语言:
-```
-curl http://localhost:3000/api/ping
-# => { code:0, msg_key:"common.success", msg:"操作成功" }
-```
-- 指定英文:
-```
-curl -H "Accept-Language: en-US" http://localhost:3000/api/ping
-# 或
-curl "http://localhost:3000/api/ping?lang=en-US"
-# => { code:0, msg_key:"common.success", msg:"Success" }
-```
-- 错误示例:
-```
-# 返回 { code:401, msg_key:"error.auth.invalid_token", msg:"令牌无效或已过期" }
-```
-
-## 维护策略
-- 新增文案:按模块/域定义 key,避免重复;中英文同时维护。
-- 变更文案:保持 key 不变,更新不同语言的文本内容。
-- 清理策略:定期检查未使用 key,删除并在变更日志记录。
-
-## 与 Java/PHP 的对齐
-- Java:沿用 `.properties` 的模块化与 key 命名;Nest 端资源内容与 Java 的 key 同名对齐。
-- PHP:继续使用 `get_lang(key)`,逐步统一到 Java 的点分 key,无需维护独立资源规范。
-
-// 术语对齐:对外事件与模块名统一使用 `lang`;内部技术栈保留 `i18n`。
-如需我在 `wwjcloud-nest-v1` 中继续完成代码接入(创建 `BootI18nModule`、改造拦截器与异常过滤器、添加示例语言资源),请在本指南基础上确认,我将按以上目录与步骤实施。
\ No newline at end of file
diff --git a/wwjcloud-nest-v1/docs/README.md b/wwjcloud-nest-v1/docs/README.md
index b0344ab6..b04b15e4 100644
--- a/wwjcloud-nest-v1/docs/README.md
+++ b/wwjcloud-nest-v1/docs/README.md
@@ -1,11 +1,57 @@
-# WWJCloud Nest v1 文档索引
+# WWJCloud NestJS v1 文档中心
-- 一体化总览:`V1-GUIDE.md`(推荐从此开始)
-- AI 开发与安全:`AI-RECOVERY-DEV.md`、`AI-RECOVERY-SECURITY.md`
-- 基础设施与配置:`V11-INFRA-SETUP.md`
-- 一致性与对齐:`CONSISTENCY-GUIDE.md`
-- 国际化指南:`LANG-GUIDE.md`
+> 🎯 **企业级全栈框架文档库** - 基于 NestJS v11,超越 Java 的企业能力
-维护约定:
-- v1 专属文档仅在本目录维护,主 `docs/` 不承载 v1 内容。
-- 新增能力需同步更新 `V1-GUIDE.md` 与相关子文档。
\ No newline at end of file
+## 📖 核心文档
+
+### 🚀 快速开始
+- **[V1 框架指南](V1-GUIDE.md)** - 完整开发与运维指南,**建议从这里开始**
+
+### 🏗️ 基础设施层 (Boot)
+- **[基础设施配置](V11-INFRA-SETUP.md)** - Boot 层配置与能力说明
+- **[Boot 就绪状态](V11-BOOT-READINESS.md)** - 模块生命周期与事件上报
+
+### 🤖 AI 治理层 (AI)
+- **[AI 能力路线图](AI-CAPABILITY-ROADMAP.md)** - AI 治理能力详解与规划
+- **[AI 开发指南](AI-RECOVERY-DEV.md)** - AI 自愈系统开发指南
+- **[AI 安全防护](AI-RECOVERY-SECURITY.md)** - AI 安全机制与防护策略
+- **[AI 就绪状态](V11-AI-READINESS.md)** - AI 层模块状态管理
+
+### 🔧 开发规范
+- **[一致性指南](CONSISTENCY-GUIDE.md)** - 代码规范与架构对齐
+- **[多语言指南](LANG-GUIDE.md)** - i18n 国际化实现指南
+
+## 📚 文档架构
+
+```
+docs/
+├── README.md # 文档索引(本文件)
+├── V1-GUIDE.md # 🚀 一体化总览
+├── V11-INFRA-SETUP.md # 🏗️ 基础设施配置
+├── V11-BOOT-READINESS.md # 🔄 Boot层生命周期
+├── V11-AI-READINESS.md # 🤖 AI层状态管理
+├── AI-CAPABILITY-ROADMAP.md # 📊 AI能力规划
+├── AI-RECOVERY-DEV.md # 🛠️ AI开发指南
+├── AI-RECOVERY-SECURITY.md # 🔒 AI安全防护
+├── CONSISTENCY-GUIDE.md # 📋 开发规范
+└── LANG-GUIDE.md # 🌐 国际化指南
+```
+
+## 🎯 使用建议
+
+### 新用户流程
+1. **开始** → 阅读 [V1-GUIDE.md](V1-GUIDE.md) 了解整体架构
+2. **配置** → 查看 [V11-INFRA-SETUP.md](V11-INFRA-SETUP.md) 配置基础设施
+3. **开发** → 参考 [CONSISTENCY-GUIDE.md](CONSISTENCY-GUIDE.md) 遵循开发规范
+
+### AI 功能开发
+1. **了解能力** → [AI-CAPABILITY-ROADMAP.md](AI-CAPABILITY-ROADMAP.md)
+2. **开发实现** → [AI-RECOVERY-DEV.md](AI-RECOVERY-DEV.md)
+3. **安全考虑** → [AI-RECOVERY-SECURITY.md](AI-RECOVERY-SECURITY.md)
+
+## 📝 维护约定
+
+- **v1 专属**:所有 v1 框架文档仅在本目录维护
+- **更新同步**:新增能力需同步更新 `V1-GUIDE.md` 与相关子文档
+- **版本控制**:文档变更需通过 Git 版本管理
+- **质量保证**:文档需保持与代码实现的一致性
\ No newline at end of file
diff --git a/wwjcloud-nest-v1/docs/V1-GUIDE.md b/wwjcloud-nest-v1/docs/V1-GUIDE.md
index 4cc3d98e..cccb8983 100644
--- a/wwjcloud-nest-v1/docs/V1-GUIDE.md
+++ b/wwjcloud-nest-v1/docs/V1-GUIDE.md
@@ -52,13 +52,13 @@
- 弹性与外部请求:`HTTP_CLIENT_TIMEOUT_MS`、`RESILIENCE_*`(重试/超时/断路器)。
- Lang:`OTEL/语言`无强制依赖;语言资源位于 `apps/api/src/lang`。
-## 自动 PHP 脚本迁移工具
-- 位置:`tools-v1/php-tools/` 与 `tools-v1/scripts/`。
-- 用途:从 PHP/Java 源仓提取控制器/服务/验证器信息,生成或校验 Nest 端的路由/DTO/实体映射;辅助一致性迁移与验证。
+## 自动 Java 脚本迁移工具
+- 位置:`tools/tools-v1/java-tools/` 与 `tools/tools-uni/`。
+- 用途:从 Java 源仓提取控制器/服务/实体信息,生成或校验 NestJS 端的路由/DTO/实体映射;辅助一致性迁移与验证。
- 建议流程:
- - 配置源路径(如 `niucloud-php/niucloud/app/*`、`sql/wwjcloud.sql`)。
+ - 配置源路径(如 `niucloud-java/*`、`sql/wwjcloud.sql`)。
- 运行脚本产出映射报告与待生成清单。
- - 按报告同步生成/修复 Nest 模块,并以 CI/e2e 验证闭环。
+ - 按报告同步生成/修复 NestJS 模块,并以 CI/e2e 验证闭环。
## 本地与 CI 验证清单
- 启动:`PORT=3001`、`GLOBAL_PREFIX=api`、`AI_ENABLED=true`、`QUEUE_DRIVER=memory`。
diff --git a/wwjcloud-nest-v1/eslint-report.json b/wwjcloud-nest-v1/eslint-report.json
deleted file mode 100644
index 8a1a40ff..00000000
--- a/wwjcloud-nest-v1/eslint-report.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/apps/api/src/app.module.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/apps/api/src/main.ts","messages":[{"ruleId":"@typescript-eslint/no-floating-promises","severity":2,"message":"Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.","line":15,"column":1,"nodeType":"ExpressionStatement","messageId":"floatingVoid","endLine":15,"endColumn":13,"suggestions":[{"messageId":"floatingFixVoid","fix":{"range":[514,514],"text":"void "},"desc":"Add void operator to ignore."},{"messageId":"floatingFixAwait","fix":{"range":[514,514],"text":"await "},"desc":"Add await operator."}]}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { NestFactory } from '@nestjs/core';\nimport { AppModule } from './app.module';\nimport { BootHttp } from '@wwjCommon/http/boot-http';\nimport { ConfigService } from '@nestjs/config';\n\nasync function bootstrap() {\n const app = await NestFactory.create(AppModule);\n await BootHttp.start(app);\n const config = app.get(ConfigService);\n const raw = config.get('PORT');\n const port =\n typeof raw === 'number' ? raw : parseInt(String(raw ?? '3000'), 10) || 3000;\n await app.listen(port);\n}\nbootstrap();\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/apps/api/src/secure.controller.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-addon/src/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-addon/src/registry.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":1,"column":31,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":1,"endColumn":34,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[30,33],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[30,33],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"export type AddonModuleType = any;\n\n// Keyed by lowercase addon name, e.g. { 'oss': OssAddonModule }\nexport const ADDON_REGISTRY: Record = {};\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-addon/src/wwjcloud-addon.module.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-return","severity":2,"message":"Unsafe return of a value of type `any`.","line":21,"column":9,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":21,"endColumn":72},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":24,"column":12,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":24,"endColumn":15,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[729,732],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[729,732],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":24,"column":77,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":24,"endColumn":80,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[794,797],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[794,797],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Module, DynamicModule, ForwardReference, Type } from '@nestjs/common';\nimport { ADDON_REGISTRY } from './registry';\n\n@Module({\n imports: [],\n providers: [],\n exports: [],\n})\nexport class AddonModule {\n static register(): DynamicModule {\n const enabledKeys = Object.keys(process.env).filter(\n (k) =>\n /^ADDON_.+_ENABLED$/.test(k) &&\n ['true', '1', 'yes'].includes(String(process.env[k]).toLowerCase()),\n );\n\n const imports = enabledKeys\n .map((k) => {\n const m = k.match(/^ADDON_(.+)_ENABLED$/);\n const key = m ? m[1].toLowerCase() : undefined;\n return key && ADDON_REGISTRY[key] ? ADDON_REGISTRY[key] : null;\n })\n .filter(Boolean) as Array<\n Type | DynamicModule | Promise | ForwardReference\n >;\n\n return {\n module: AddonModule,\n imports,\n exports: [],\n };\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/events.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/healing.module.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/interfaces/healing.interface.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":11,"column":20,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":11,"endColumn":23,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[161,164],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[161,164],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":21,"column":10,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":21,"endColumn":13,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[352,355],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[352,355],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":22,"column":28,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":22,"endColumn":31,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[384,387],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[384,387],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":35,"column":12,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":35,"endColumn":15,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[581,584],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[581,584],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":44,"column":20,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":44,"endColumn":23,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[728,731],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[728,731],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":45,"column":17,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":45,"endColumn":20,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[759,762],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[759,762],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":64,"column":28,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":64,"endColumn":31,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1130,1133],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1130,1133],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":73,"column":27,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":73,"endColumn":30,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1291,1294],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1291,1294],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":8,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Healing Module Interfaces - AI 自愈模块接口定义\n */\n\n/**\n * 恢复策略接口\n */\nexport interface RecoveryStrategy {\n name: string;\n priority: number;\n canHandle(error: any): boolean;\n execute(context: RecoveryContext): Promise;\n getEstimatedTime(): number;\n}\n\n/**\n * 恢复上下文接口\n */\nexport interface RecoveryContext {\n taskId: string;\n error: any;\n metadata: Record;\n retryCount: number;\n maxRetries: number;\n startTime: number;\n}\n\n/**\n * 恢复结果接口\n */\nexport interface RecoveryResult {\n success: boolean;\n strategy: string;\n duration: number;\n result?: any;\n error?: string;\n nextAction?: 'retry' | 'escalate' | 'abort';\n}\n\n/**\n * 自愈监听器接口\n */\nexport interface SelfHealListener {\n canHandle(event: any): boolean;\n handle(event: any): Promise;\n getPriority(): number;\n}\n\n/**\n * 错误分析结果接口\n */\nexport interface ErrorAnalysis {\n errorType: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n category:\n | 'network'\n | 'database'\n | 'service'\n | 'validation'\n | 'system'\n | 'unknown';\n recoverable: boolean;\n suggestedStrategies: string[];\n metadata: Record;\n}\n\n/**\n * 健康检查结果接口\n */\nexport interface HealthCheckResult {\n component: string;\n status: 'healthy' | 'degraded' | 'unhealthy';\n details: Record;\n timestamp: number;\n responseTime?: number;\n}\n\n/**\n * 自愈统计信息接口\n */\nexport interface HealingStats {\n totalRecoveries: number;\n successfulRecoveries: number;\n failedRecoveries: number;\n averageRecoveryTime: number;\n strategiesUsed: Record;\n errorCategories: Record;\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/listeners/ai-recovery.listener.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/listeners/ai-self-heal.listener.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/services/ai-recovery.service.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .message on an `any` value.","line":40,"column":52,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":40,"endColumn":59},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async arrow function has no 'await' expression.","line":45,"column":52,"nodeType":"ArrowFunctionExpression","messageId":"missingAwait","endLine":45,"endColumn":54,"suggestions":[{"messageId":"removeAsync","fix":{"range":[1560,1566],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":180,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":180,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type error typed assigned to a parameter of type `string | undefined`.","line":184,"column":9,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":184,"endColumn":16},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":188,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":188,"endColumn":26}],"suppressedMessages":[],"errorCount":5,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger } from '@nestjs/common';\nimport { CacheService } from '@wwjCommon/cache/cache.service';\nimport { LockService } from '@wwjCommon/cache/lock.service';\nimport { MetricsService } from '@wwjCommon/metrics/metrics.service';\nimport {\n TASK_RECOVERY_COMPLETED_EVENT,\n TaskRecoveryRequestedPayload,\n TaskRecoveryCompletedPayload,\n TASK_FAILED_EVENT,\n TASK_RECOVERY_REQUESTED_EVENT,\n Severity,\n TaskFailedPayload,\n} from '@wwjAi';\nimport { EventBus } from '@wwjCommon/events/event-bus';\nimport { QueueService } from '@wwjCommon/queue/queue.service';\nimport { ConfigService } from '@nestjs/config';\nimport { AiStrategyService } from '@wwjAi';\n\nconst QUEUE_KEY = 'ai:recovery:queue';\nconst QUEUE_LOCK_KEY = 'ai:recovery:lock';\n\n@Injectable()\nexport class AiRecoveryService {\n private readonly logger = new Logger(AiRecoveryService.name);\n // metrics injected via constructor now\n\n constructor(\n private readonly cache: CacheService,\n private readonly lock: LockService,\n private readonly metrics: MetricsService,\n private readonly eventBus: EventBus,\n private readonly queue: QueueService,\n private readonly config: ConfigService,\n private readonly strategy: AiStrategyService,\n ) {}\n\n onModuleInit() {\n // 初始化可选的队列(BullMQ / Kafka)\n this.queue.init('ai-recovery').catch((err) => {\n this.logger.error(`Queue init failed: ${err?.message || err}`);\n });\n if (this.queue.isBullmq() || this.queue.isKafka()) {\n // 注册 Worker 处理恢复请求(BullMQ/Kafka 共用统一处理器)\n this.queue.registerWorker(\n async (data: TaskRecoveryRequestedPayload) => {\n const start = Date.now();\n this.logger.log(\n `Processing recovery (worker) for taskId=${data.taskId}`,\n );\n const durationMs = Date.now() - start;\n const payload: TaskRecoveryCompletedPayload = {\n taskId: data.taskId,\n strategy: data.strategy,\n result: 'success',\n durationMs,\n timestamp: Date.now(),\n };\n this.eventBus.emit(TASK_RECOVERY_COMPLETED_EVENT, payload);\n this.metrics?.observeAiEvent(\n TASK_RECOVERY_COMPLETED_EVENT,\n undefined,\n data.strategy,\n );\n },\n 1,\n 'ai-recovery',\n );\n }\n }\n\n async enqueue(req: TaskRecoveryRequestedPayload): Promise {\n // 若启用队列,优先走队列(BullMQ/Kafka)\n if (this.queue.isBullmq() || this.queue.isKafka()) {\n await this.queue.enqueue('ai.recovery', req);\n // BullMQ 可以返回计数,Kafka 不易获取队列深度,这里统一返回 0 或 BullMQ 等待数量\n if (this.queue.isBullmq()) {\n const counts = await this.queue.getQueueCounts();\n const waiting = counts?.waiting ?? 0;\n const delayed = counts?.delayed ?? 0;\n return waiting + delayed;\n }\n return 0;\n }\n // 默认使用内存/Redis 模拟队列\n const list =\n (await this.cache.get(QUEUE_KEY)) ?? [];\n list.push(req);\n await this.cache.set(QUEUE_KEY, list);\n this.logger.log(\n `Enqueued recovery request: taskId=${req.taskId}, strategy=${req.strategy}`,\n );\n return list.length;\n }\n\n async status() {\n if (this.queue.isBullmq()) {\n const counts = await this.queue.getQueueCounts();\n const waiting = counts?.waiting ?? 0;\n const delayed = counts?.delayed ?? 0;\n return { size: waiting + delayed };\n }\n if (this.queue.isKafka()) {\n // Kafka 模式下无法快速获取队列大小,返回 0 以表示“由后台异步处理”\n return { size: 0 };\n }\n const list =\n (await this.cache.get(QUEUE_KEY)) ?? [];\n return { size: list.length };\n }\n\n async processOne(): Promise {\n // 队列模式下由 Worker 自动处理,processOne 返回 false 表示无需手动触发\n if (this.queue.isBullmq() || this.queue.isKafka()) return false;\n\n const list =\n (await this.cache.get(QUEUE_KEY)) ?? [];\n if (list.length === 0) return false;\n\n const lockToken = await this.lock.acquire(QUEUE_LOCK_KEY, 5000);\n if (!lockToken) return false; // someone else is processing\n\n try {\n const req = list.shift()!;\n await this.cache.set(QUEUE_KEY, list);\n // simulate processing logic here\n const start = Date.now();\n this.logger.log(`Processed recovery for taskId=${req.taskId}`);\n const durationMs = Date.now() - start;\n this.logger.log(\n `Processed recovery request: taskId=${req.taskId}, strategy=${req.strategy}`,\n );\n const payload: TaskRecoveryCompletedPayload = {\n taskId: req.taskId,\n strategy: req.strategy,\n result: 'success',\n durationMs,\n timestamp: Date.now(),\n };\n this.eventBus.emit(TASK_RECOVERY_COMPLETED_EVENT, payload);\n this.metrics?.observeAiEvent(\n TASK_RECOVERY_COMPLETED_EVENT,\n undefined,\n req.strategy,\n );\n return true;\n } finally {\n await this.lock.release(QUEUE_LOCK_KEY, lockToken);\n }\n }\n\n async drain(max = 10): Promise {\n // 队列模式下由 Worker 自动处理,这里返回 0 表示无需手动 drain\n if (this.queue.isBullmq() || this.queue.isKafka()) return 0;\n\n let processed = 0;\n while (processed < max) {\n const ok = await this.processOne();\n if (!ok) break;\n processed++;\n }\n return processed;\n }\n async simulateFailure(params: {\n taskId?: string;\n severity?: Severity;\n reason?: string;\n }): Promise<{ ok: true; emitted: boolean }> {\n const taskId = params.taskId ?? 'demo-task';\n const severity: Severity = params.severity ?? 'medium';\n const reason = params.reason ?? 'demo failure';\n const payload: TaskFailedPayload = {\n taskId,\n reason,\n severity,\n timestamp: Date.now(),\n };\n this.eventBus.emit(TASK_FAILED_EVENT, payload);\n this.metrics?.observeAiEvent(TASK_FAILED_EVENT, severity);\n if (this.readBoolean('AI_SIMULATE_DIRECT_ENQUEUE')) {\n const decided = this.strategy.decideStrategy(payload);\n this.metrics?.observeAiEvent(\n TASK_RECOVERY_REQUESTED_EVENT,\n undefined,\n decided,\n );\n const request: TaskRecoveryRequestedPayload = {\n taskId,\n strategy: decided,\n requestedBy: 'manual',\n timestamp: Date.now(),\n };\n await this.enqueue(request);\n }\n return { ok: true, emitted: true };\n }\n private readBoolean(key: string): boolean {\n const v = this.config.get(key);\n if (typeof v === 'boolean') return v;\n if (typeof v === 'string')\n return ['true', '1', 'yes', 'on'].includes(v.toLowerCase());\n return false;\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/services/ai-strategy.service.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":21,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":21,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Computed name [evt.severity] resolves to an `error` typed value.","line":21,"column":19,"nodeType":"MemberExpression","messageId":"unsafeComputedMemberAccess","endLine":21,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .severity on an `error` typed value.","line":21,"column":23,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .metadata on an `error` typed value.","line":23,"column":22,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":30}],"suppressedMessages":[],"errorCount":4,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport type { Severity, RecoveryStrategy, TaskFailedPayload } from '../types';\n\n@Injectable()\nexport class AiStrategyService {\n constructor(private readonly config: ConfigService) {}\n\n decideStrategy(evt: TaskFailedPayload): RecoveryStrategy {\n // allow override via env for quick testing\n const override = this.config.get('AI_STRATEGY_OVERRIDE');\n if (override && this.isValidStrategy(override)) {\n return override as RecoveryStrategy;\n }\n // simple mapping by severity; can be extended to rules by metadata\n const map: Record = {\n low: 'retry',\n medium: 'retry',\n high: 'fallback',\n };\n const s = map[evt.severity] ?? 'retry';\n // extend: if metadata.hint === 'reroute', do reroute\n const hint = evt.metadata?.hint as string | undefined;\n if (hint === 'reroute') return 'reroute';\n if (hint === 'restart') return 'restart';\n return s;\n }\n\n private isValidStrategy(v: string): boolean {\n return ['retry', 'restart', 'reroute', 'fallback', 'noop'].includes(v);\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/strategies/fallback.strategy.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":26,"column":20,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":26,"endColumn":23,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[506,509],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[506,509],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .code on an `any` value.","line":36,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":36,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":36,"column":48,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":36,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .code on an `any` value.","line":36,"column":54,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":36,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .severity on an `any` value.","line":41,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":41,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .severity on an `any` value.","line":41,"column":46,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":41,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":58,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":58,"endColumn":70},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":64,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":64,"endColumn":31},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":93,"column":73,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":93,"endColumn":76,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2007,2010],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2007,2010],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":94,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":94,"endColumn":61},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'handleDatabaseFallback' has no 'await' expression.","line":119,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":119,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2608,2676],"text":"handleDatabaseFallback(context: RecoveryContext): any"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":119,"column":75,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":119,"endColumn":78,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2672,2675],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2672,2675],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":125,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":125,"endColumn":49},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'handleApiFallback' has no 'await' expression.","line":134,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":134,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3008,3071],"text":"handleApiFallback(context: RecoveryContext): any"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":134,"column":70,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":134,"endColumn":73,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[3067,3070],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[3067,3070],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":140,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":140,"endColumn":75},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":149,"column":72,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":149,"endColumn":75,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[3479,3482],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[3479,3482],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":155,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":155,"endColumn":52},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'handleFileFallback' has no 'await' expression.","line":164,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":164,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3804,3868],"text":"handleFileFallback(context: RecoveryContext): any"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":164,"column":71,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":164,"endColumn":74,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[3864,3867],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[3864,3867],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":170,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":170,"endColumn":50},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'handleGenericFallback' has no 'await' expression.","line":179,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":179,"endColumn":38,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4191,4258],"text":"handleGenericFallback(context: RecoveryContext): any"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":179,"column":74,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":179,"endColumn":77,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4254,4257],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4254,4257],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":193,"column":72,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":193,"endColumn":75,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4606,4609],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4606,4609],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":198,"column":20,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":198,"endColumn":55}],"suppressedMessages":[],"errorCount":25,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger } from '@nestjs/common';\nimport {\n RecoveryStrategy,\n RecoveryContext,\n RecoveryResult,\n} from '../interfaces/healing.interface';\n\n/**\n * Fallback Recovery Strategy - 降级恢复策略\n *\n * 职责:\n * - 提供服务降级方案\n * - 处理不可恢复的错误\n * - 确保系统基本功能可用\n */\n@Injectable()\nexport class FallbackStrategy implements RecoveryStrategy {\n private readonly logger = new Logger(FallbackStrategy.name);\n\n readonly name = 'fallback';\n readonly priority = 3;\n\n /**\n * 判断是否可以处理该错误\n */\n canHandle(error: any): boolean {\n // 需要降级处理的错误类型\n const fallbackErrors = [\n 'SERVICE_UNAVAILABLE',\n 'DEPENDENCY_FAILURE',\n 'RESOURCE_EXHAUSTED',\n 'CIRCUIT_BREAKER_OPEN',\n 'RATE_LIMIT_EXCEEDED',\n ];\n\n if (error?.code && fallbackErrors.includes(error.code)) {\n return true;\n }\n\n // 检查错误严重程度\n if (error?.severity === 'high' || error?.severity === 'critical') {\n return true;\n }\n\n return false;\n }\n\n /**\n * 执行降级恢复\n */\n async execute(context: RecoveryContext): Promise {\n const startTime = Date.now();\n\n this.logger.log(`Executing fallback strategy for task: ${context.taskId}`);\n\n try {\n // 根据任务类型选择降级方案\n const fallbackResult = await this.selectFallbackOption(context);\n\n return {\n success: true,\n strategy: this.name,\n duration: Date.now() - startTime,\n result: fallbackResult,\n nextAction: 'abort', // 降级后通常不再重试\n };\n } catch (error) {\n this.logger.error(\n `Fallback strategy failed for task: ${context.taskId}`,\n error,\n );\n\n return {\n success: false,\n strategy: this.name,\n duration: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Fallback failed',\n nextAction: 'abort',\n };\n }\n }\n\n /**\n * 获取预估执行时间\n */\n getEstimatedTime(): number {\n return 2000; // 2秒预估时间\n }\n\n /**\n * 选择降级方案\n */\n private async selectFallbackOption(context: RecoveryContext): Promise {\n const taskType = context.metadata?.taskType || 'unknown';\n\n this.logger.debug(`Selecting fallback option for task type: ${taskType}`);\n\n switch (taskType) {\n case 'database':\n return await this.handleDatabaseFallback(context);\n\n case 'api':\n return await this.handleApiFallback(context);\n\n case 'cache':\n return await this.handleCacheFallback(context);\n\n case 'file':\n return await this.handleFileFallback(context);\n\n default:\n return await this.handleGenericFallback(context);\n }\n }\n\n /**\n * 数据库降级处理\n */\n private async handleDatabaseFallback(context: RecoveryContext): Promise {\n this.logger.warn(`Database fallback for task: ${context.taskId}`);\n\n // 返回缓存数据或默认值\n return {\n fallbackType: 'database',\n data: context.metadata?.cachedData || null,\n message: 'Using cached data due to database unavailability',\n timestamp: Date.now(),\n };\n }\n\n /**\n * API 降级处理\n */\n private async handleApiFallback(context: RecoveryContext): Promise {\n this.logger.warn(`API fallback for task: ${context.taskId}`);\n\n // 返回默认响应或离线数据\n return {\n fallbackType: 'api',\n data: context.metadata?.defaultResponse || { status: 'unavailable' },\n message: 'Using default response due to API unavailability',\n timestamp: Date.now(),\n };\n }\n\n /**\n * 缓存降级处理\n */\n private async handleCacheFallback(context: RecoveryContext): Promise {\n this.logger.warn(`Cache fallback for task: ${context.taskId}`);\n\n // 直接访问数据源\n return {\n fallbackType: 'cache',\n data: await this.fetchFromDataSource(context),\n message: 'Bypassing cache and fetching from data source',\n timestamp: Date.now(),\n };\n }\n\n /**\n * 文件降级处理\n */\n private async handleFileFallback(context: RecoveryContext): Promise {\n this.logger.warn(`File fallback for task: ${context.taskId}`);\n\n // 使用备用文件或默认内容\n return {\n fallbackType: 'file',\n data: context.metadata?.backupContent || '',\n message: 'Using backup content due to file access failure',\n timestamp: Date.now(),\n };\n }\n\n /**\n * 通用降级处理\n */\n private async handleGenericFallback(context: RecoveryContext): Promise {\n this.logger.warn(`Generic fallback for task: ${context.taskId}`);\n\n return {\n fallbackType: 'generic',\n data: null,\n message: 'Service temporarily unavailable, please try again later',\n timestamp: Date.now(),\n };\n }\n\n /**\n * 从数据源获取数据\n */\n private async fetchFromDataSource(context: RecoveryContext): Promise {\n // 这里应该实现从原始数据源获取数据的逻辑\n // 具体实现取决于数据源类型\n\n if (context.metadata?.dataSourceFunction) {\n return await context.metadata.dataSourceFunction();\n }\n\n return null;\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/healing/strategies/retry.strategy.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":26,"column":20,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":26,"endColumn":23,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[492,495],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[492,495],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .code on an `any` value.","line":37,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":37,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":37,"column":49,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":37,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .code on an `any` value.","line":37,"column":55,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":37,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .message on an `any` value.","line":41,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":41,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":42,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":42,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":42,"column":23,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":42,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .message on an `any` value.","line":42,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":42,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":2,"message":"Unsafe return of a value of type `any`.","line":43,"column":7,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":48,"endColumn":9},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":44,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":44,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .includes on an `any` value.","line":44,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":44,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":45,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":45,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .includes on an `any` value.","line":45,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":45,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":46,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":46,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .includes on an `any` value.","line":46,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":46,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":47,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":47,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .includes on an `any` value.","line":47,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":47,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":85,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":85,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":91,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":91,"endColumn":15},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":135,"column":65,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":135,"endColumn":68,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[3060,3063],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[3060,3063],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":143,"column":20,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":143,"endColumn":53}],"suppressedMessages":[],"errorCount":21,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger } from '@nestjs/common';\nimport {\n RecoveryStrategy,\n RecoveryContext,\n RecoveryResult,\n} from '../interfaces/healing.interface';\n\n/**\n * Retry Recovery Strategy - 重试恢复策略\n *\n * 职责:\n * - 处理可重试的错误\n * - 实现指数退避重试机制\n * - 监控重试成功率\n */\n@Injectable()\nexport class RetryStrategy implements RecoveryStrategy {\n private readonly logger = new Logger(RetryStrategy.name);\n\n readonly name = 'retry';\n readonly priority = 1;\n\n /**\n * 判断是否可以处理该错误\n */\n canHandle(error: any): boolean {\n // 可重试的错误类型\n const retryableErrors = [\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'ENOTFOUND',\n 'ECONNREFUSED',\n 'NETWORK_ERROR',\n 'TEMPORARY_FAILURE',\n ];\n\n if (error?.code && retryableErrors.includes(error.code)) {\n return true;\n }\n\n if (error?.message) {\n const message = error.message.toLowerCase();\n return (\n message.includes('timeout') ||\n message.includes('connection') ||\n message.includes('network') ||\n message.includes('temporary')\n );\n }\n\n return false;\n }\n\n /**\n * 执行重试恢复\n */\n async execute(context: RecoveryContext): Promise {\n const startTime = Date.now();\n\n this.logger.log(\n `Executing retry strategy for task: ${context.taskId}, attempt: ${context.retryCount + 1}`,\n );\n\n try {\n // 计算退避延迟\n const delay = this.calculateBackoffDelay(context.retryCount);\n\n if (delay > 0) {\n this.logger.debug(`Waiting ${delay}ms before retry`);\n await this.sleep(delay);\n }\n\n // 检查是否超过最大重试次数\n if (context.retryCount >= context.maxRetries) {\n return {\n success: false,\n strategy: this.name,\n duration: Date.now() - startTime,\n error: 'Maximum retry attempts exceeded',\n nextAction: 'escalate',\n };\n }\n\n // 执行重试逻辑\n const result = await this.performRetry(context);\n\n return {\n success: true,\n strategy: this.name,\n duration: Date.now() - startTime,\n result,\n nextAction: 'retry',\n };\n } catch (error) {\n this.logger.error(\n `Retry strategy failed for task: ${context.taskId}`,\n error,\n );\n\n return {\n success: false,\n strategy: this.name,\n duration: Date.now() - startTime,\n error: error instanceof Error ? error.message : 'Unknown error',\n nextAction:\n context.retryCount < context.maxRetries ? 'retry' : 'escalate',\n };\n }\n }\n\n /**\n * 获取预估执行时间\n */\n getEstimatedTime(): number {\n return 5000; // 5秒预估时间\n }\n\n /**\n * 计算指数退避延迟\n */\n private calculateBackoffDelay(retryCount: number): number {\n // 指数退避:2^retryCount * 1000ms,最大30秒\n const baseDelay = 1000;\n const maxDelay = 30000;\n const delay = Math.min(baseDelay * Math.pow(2, retryCount), maxDelay);\n\n // 添加随机抖动,避免雷群效应\n const jitter = Math.random() * 0.1 * delay;\n return Math.floor(delay + jitter);\n }\n\n /**\n * 执行重试\n */\n private async performRetry(context: RecoveryContext): Promise {\n // 这里应该重新执行原始任务\n // 具体实现取决于任务类型和上下文\n\n this.logger.debug(`Performing retry for task: ${context.taskId}`);\n\n // 模拟重试逻辑\n if (context.metadata?.originalFunction) {\n return await context.metadata.originalFunction();\n }\n\n // 如果没有原始函数,返回成功标记\n return { retried: true, timestamp: Date.now() };\n }\n\n /**\n * 睡眠函数\n */\n private sleep(ms: number): Promise {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/bootstrap/ai-bootstrap.provider.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/controllers/ai.controller.ts","messages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'TASK_FAILED_EVENT' is defined but never used.","line":9,"column":10,"nodeType":null,"messageId":"unusedVar","endLine":9,"endColumn":27},{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'TASK_RECOVERY_REQUESTED_EVENT' is defined but never used.","line":9,"column":29,"nodeType":null,"messageId":"unusedVar","endLine":9,"endColumn":58},{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'TaskFailedPayload' is defined but never used.","line":12,"column":3,"nodeType":null,"messageId":"unusedVar","endLine":12,"endColumn":20},{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'TaskRecoveryRequestedPayload' is defined but never used.","line":13,"column":3,"nodeType":null,"messageId":"unusedVar","endLine":13,"endColumn":31}],"suppressedMessages":[],"errorCount":4,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Controller, Get, Query, UseGuards, Post } from '@nestjs/common';\nimport { RateLimitGuard } from '@wwjCommon/http/rate-limit.guard';\nimport { AiRecoveryService } from '../../healing/services/ai-recovery.service';\nimport { ApiTags } from '@nestjs/swagger';\nimport { ApiQuery } from '@nestjs/swagger';\nimport { IsInt, IsOptional, Min, IsString, IsIn } from 'class-validator';\nimport { Public, Roles } from '@wwjCommon/auth/decorators';\nimport { EventBus } from '@wwjCommon/events/event-bus';\nimport { TASK_FAILED_EVENT, TASK_RECOVERY_REQUESTED_EVENT } from '@wwjAi';\nimport type {\n Severity,\n TaskFailedPayload,\n TaskRecoveryRequestedPayload,\n} from '@wwjAi';\nimport { ConfigService } from '@nestjs/config';\nimport { MetricsService } from '@wwjCommon/metrics/metrics.service';\nimport { AuthGuard } from '@wwjCommon/auth/auth.guard';\nimport { RbacGuard } from '@wwjCommon/auth/rbac.guard';\nimport { AiStrategyService } from '@wwjAi';\n\nclass DrainQueryDto {\n @IsInt()\n @Min(1)\n @IsOptional()\n max?: number;\n}\n\nclass SimulateFailureQueryDto {\n @IsString()\n @IsOptional()\n taskId?: string;\n\n @IsString()\n @IsIn(['low', 'medium', 'high'])\n @IsOptional()\n severity?: Severity;\n\n @IsString()\n @IsOptional()\n reason?: string;\n}\n\n@UseGuards(AuthGuard, RbacGuard, RateLimitGuard)\n@ApiTags('AI')\n@Controller('ai/recovery')\nexport class AiController {\n constructor(\n private readonly recovery: AiRecoveryService,\n private readonly eventBus: EventBus,\n private readonly config: ConfigService,\n private readonly metrics: MetricsService,\n private readonly strategy: AiStrategyService,\n ) {}\n\n @Get('status')\n @Public()\n async status() {\n return await this.recovery.status();\n }\n\n @Get('process-one')\n @Post('process-one')\n @Roles('admin')\n async processOne() {\n const ok = await this.recovery.processOne();\n return { ok };\n }\n\n @Get('drain')\n @Post('drain')\n @Roles('admin')\n @ApiQuery({\n name: 'max',\n required: false,\n type: Number,\n description: '最大处理数量(默认10)',\n })\n async drain(@Query() query: DrainQueryDto) {\n const n = await this.recovery.drain(query.max ?? 10);\n return { processed: n };\n }\n\n @Get('simulate-failure')\n @Post('simulate-failure')\n @Roles('admin')\n @ApiQuery({ name: 'taskId', required: false, type: String })\n @ApiQuery({\n name: 'severity',\n required: false,\n enum: ['low', 'medium', 'high'],\n })\n @ApiQuery({ name: 'reason', required: false, type: String })\n async simulateFailure(\n @Query() q: SimulateFailureQueryDto,\n ): Promise<{ ok: true; emitted: boolean }> {\n // 委派到服务层,控制器不再直接发事件或打点\n return await this.recovery.simulateFailure({\n taskId: q.taskId,\n severity: q.severity,\n reason: q.reason,\n });\n }\n\n // 移除 readBoolean 与直接依赖 metrics/strategy\n private readBoolean(key: string): boolean {\n const v = this.config.get(key);\n if (typeof v === 'boolean') return v;\n if (typeof v === 'string') return v === 'true' || v === '1' || v === 'yes';\n return false;\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/interfaces/ai-manager.interface.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":23,"column":29,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":23,"endColumn":32,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[356,359],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[356,359],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":44,"column":12,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":44,"endColumn":15,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[643,646],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[643,646],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":56,"column":29,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":56,"endColumn":32,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[876,879],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[876,879],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":66,"column":12,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":66,"endColumn":15,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1049,1052],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1049,1052],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":77,"column":12,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":77,"endColumn":15,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1218,1221],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1218,1221],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":5,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * AI Manager Interfaces - AI 管理模块接口定义\n */\n\n/**\n * 工作流程配置接口\n */\nexport interface WorkflowConfig {\n steps: string[];\n timeout: number;\n retryCount: number;\n parallel?: boolean;\n dependencies?: string[];\n}\n\n/**\n * 工作流程执行上下文接口\n */\nexport interface WorkflowContext {\n taskId: string;\n userId?: string;\n siteId?: number;\n metadata?: Record;\n startTime: number;\n}\n\n/**\n * 工作流程执行结果接口\n */\nexport interface WorkflowResult {\n success: boolean;\n steps: StepResult[];\n duration: number;\n error?: string;\n}\n\n/**\n * 步骤执行结果接口\n */\nexport interface StepResult {\n step: string;\n success: boolean;\n duration: number;\n result?: any;\n error?: string;\n}\n\n/**\n * 模块状态接口\n */\nexport interface ModuleState {\n name: string;\n status: 'initializing' | 'ready' | 'active' | 'error' | 'unavailable';\n version: string;\n lastUpdate: number;\n metadata?: Record;\n}\n\n/**\n * 任务协调请求接口\n */\nexport interface TaskCoordinationRequest {\n taskId: string;\n taskType: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n payload: any;\n requiredModules?: string[];\n timeout?: number;\n}\n\n/**\n * 任务协调结果接口\n */\nexport interface TaskCoordinationResult {\n taskId: string;\n success: boolean;\n result?: any;\n error?: string;\n duration: number;\n modulesUsed: string[];\n}\n\n/**\n * AI 管理器统计信息接口\n */\nexport interface AiManagerStats {\n modules: {\n total: number;\n active: number;\n error: number;\n };\n services: {\n total: number;\n healthy: number;\n byType: Record;\n };\n workflows: {\n active: string[];\n completed: number;\n failed: number;\n };\n tasks: {\n pending: number;\n byType: Record;\n oldestAge?: number;\n };\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/manager.module.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/services/ai-coordinator.service.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":19,"column":51,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":19,"endColumn":54,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[632,635],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[632,635],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'initializeModuleStates' has no 'await' expression.","line":37,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":37,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[1102,1147],"text":"initializeModuleStates(): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":84,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":84,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2163,2166],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2163,2166],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":85,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":85,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2181,2184],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2181,2184],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":100,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":104,"endColumn":8},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":106,"column":66,"nodeType":"Property","messageId":"anyAssignment","endLine":106,"endColumn":72},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":113,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":113,"endColumn":14},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkModuleAvailability' has no 'await' expression.","line":136,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":136,"endColumn":40,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3472,3615],"text":"checkModuleAvailability(modules: string[]): {\n allAvailable: boolean;\n available: string[];\n unavailable: string[];\n }"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":166,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":166,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4155,4158],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4155,4158],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":167,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":167,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4173,4176],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4173,4176],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":169,"column":47,"nodeType":"Property","messageId":"anyAssignment","endLine":169,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":177,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":180,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":183,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":186,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":189,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":192,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":195,"column":11,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":195,"endColumn":67},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":210,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":210,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5159,5162],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5159,5162],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":211,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":211,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5177,5180],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5177,5180],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":226,"column":35,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":226,"endColumn":38,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5526,5529],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5526,5529],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .taskId on an `any` value.","line":227,"column":46,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":227,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .severity on an `any` value.","line":230,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":230,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .taskId on an `any` value.","line":231,"column":53,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":231,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":232,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":232,"endColumn":30},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":241,"column":43,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":241,"endColumn":46,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5890,5893],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5890,5893],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .module on an `any` value.","line":243,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":243,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .currentState on an `any` value.","line":243,"column":61,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":243,"endColumn":73},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":247,"column":27,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":247,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .module on an `any` value.","line":247,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":247,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":247,"column":43,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":247,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .currentState on an `any` value.","line":247,"column":51,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":247,"endColumn":63},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .currentState on an `any` value.","line":251,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":251,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .currentState on an `any` value.","line":252,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":252,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":254,"column":35,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":254,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .module on an `any` value.","line":254,"column":43,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":254,"endColumn":49},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'pauseModuleTasks' has no 'await' expression.","line":261,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":261,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6336,6393],"text":"pauseModuleTasks(moduleName: string): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":265,"column":55,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":265,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .taskType on an `any` value.","line":265,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":265,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Computed name [task.taskType] resolves to an `any` value.","line":289,"column":14,"nodeType":"MemberExpression","messageId":"unsafeComputedMemberAccess","endLine":289,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .taskType on an `any` value.","line":289,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":289,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Computed name [task.taskType] resolves to an `any` value.","line":289,"column":39,"nodeType":"MemberExpression","messageId":"unsafeComputedMemberAccess","endLine":289,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .taskType on an `any` value.","line":289,"column":44,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":289,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .startTime on an `any` value.","line":291,"column":37,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":291,"endColumn":46}],"suppressedMessages":[],"errorCount":41,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger, OnModuleInit } from '@nestjs/common';\nimport { EventBus, OnEvent } from '@wwjCommon/events/event-bus';\nimport { AiRegistryService } from './ai-registry.service';\nimport { AiOrchestratorService } from './ai-orchestrator.service';\n\n/**\n * AI Coordinator Service - AI 协调服务\n *\n * 职责:\n * - 协调各 AI 模块间的通信\n * - 处理跨模块的事件和消息\n * - 管理模块间的依赖关系\n * - 提供统一的协调接口\n */\n@Injectable()\nexport class AiCoordinatorService implements OnModuleInit {\n private readonly logger = new Logger(AiCoordinatorService.name);\n private readonly moduleStates = new Map();\n private readonly pendingTasks = new Map();\n\n constructor(\n private readonly eventBus: EventBus,\n private readonly registryService: AiRegistryService,\n private readonly orchestratorService: AiOrchestratorService,\n ) {}\n\n async onModuleInit() {\n this.logger.log('AI Coordinator Service initialized');\n await this.initializeModuleStates();\n // Mark manager as ready once coordinator has initialized\n this.updateModuleState('manager', 'ready');\n }\n\n /**\n * 初始化模块状态\n */\n private async initializeModuleStates(): Promise {\n const modules = ['healing', 'safe', 'tuner', 'manager'];\n\n for (const module of modules) {\n this.moduleStates.set(module, 'initializing');\n }\n\n this.logger.log('Module states initialized');\n }\n\n /**\n * 更新模块状态\n */\n updateModuleState(moduleName: string, state: string): void {\n const previousState = this.moduleStates.get(moduleName);\n this.moduleStates.set(moduleName, state);\n\n this.logger.log(\n `Module state updated: ${moduleName} ${previousState} -> ${state}`,\n );\n this.eventBus.emit('module.state.changed', {\n module: moduleName,\n previousState,\n currentState: state,\n });\n }\n\n /**\n * 获取模块状态\n */\n getModuleState(moduleName: string): string | undefined {\n return this.moduleStates.get(moduleName);\n }\n\n /**\n * 获取所有模块状态\n */\n getAllModuleStates(): Record {\n return Object.fromEntries(this.moduleStates);\n }\n\n /**\n * 协调任务执行\n */\n async coordinateTask(\n taskId: string,\n taskType: string,\n payload: any,\n ): Promise {\n this.logger.log(`Coordinating task: ${taskId} (${taskType})`);\n\n try {\n // 检查相关模块状态\n const requiredModules = this.getRequiredModules(taskType);\n const moduleCheck = await this.checkModuleAvailability(requiredModules);\n\n if (!moduleCheck.allAvailable) {\n throw new Error(\n `Required modules not available: ${moduleCheck.unavailable.join(', ')}`,\n );\n }\n\n // 执行任务协调\n const result = await this.executeCoordinatedTask(\n taskId,\n taskType,\n payload,\n );\n\n this.eventBus.emit('task.coordinated', { taskId, taskType, result });\n return result;\n } catch (error) {\n this.logger.error(`Task coordination failed: ${taskId}`, error);\n this.eventBus.emit('task.coordination.failed', {\n taskId,\n taskType,\n error,\n });\n throw error;\n }\n }\n\n /**\n * 获取任务所需模块\n */\n private getRequiredModules(taskType: string): string[] {\n const moduleMap: Record = {\n healing: ['healing', 'manager'],\n security: ['safe', 'manager'],\n performance: ['tuner', 'manager'],\n comprehensive: ['healing', 'safe', 'tuner', 'manager'],\n };\n\n return moduleMap[taskType] || ['manager'];\n }\n\n /**\n * 检查模块可用性\n */\n private async checkModuleAvailability(modules: string[]): Promise<{\n allAvailable: boolean;\n available: string[];\n unavailable: string[];\n }> {\n const available: string[] = [];\n const unavailable: string[] = [];\n\n for (const module of modules) {\n const state = this.moduleStates.get(module);\n if (state === 'ready' || state === 'active') {\n available.push(module);\n } else {\n unavailable.push(module);\n }\n }\n\n return {\n allAvailable: unavailable.length === 0,\n available,\n unavailable,\n };\n }\n\n /**\n * 执行协调任务\n */\n private async executeCoordinatedTask(\n taskId: string,\n taskType: string,\n payload: any,\n ): Promise {\n // 将任务添加到待处理队列\n this.pendingTasks.set(taskId, { taskType, payload, startTime: Date.now() });\n\n try {\n // 根据任务类型选择执行策略\n let result;\n\n switch (taskType) {\n case 'healing':\n result = await this.orchestratorService.executeWorkflow(\n 'healing',\n payload,\n );\n break;\n case 'security':\n result = await this.orchestratorService.executeWorkflow(\n 'security',\n payload,\n );\n break;\n case 'performance':\n result = await this.orchestratorService.executeWorkflow(\n 'performance',\n payload,\n );\n break;\n default:\n result = await this.executeCustomTask(taskType, payload);\n }\n\n return result;\n } finally {\n // 从待处理队列中移除\n this.pendingTasks.delete(taskId);\n }\n }\n\n /**\n * 执行自定义任务\n */\n private async executeCustomTask(\n taskType: string,\n payload: any,\n ): Promise {\n const services = this.registryService.getServicesByType(taskType);\n\n if (services.length === 0) {\n throw new Error(`No services available for task type: ${taskType}`);\n }\n\n // 执行第一个可用服务\n return await services[0].execute(payload);\n }\n\n /**\n * 处理任务失败事件\n */\n @OnEvent('task.failed')\n async handleTaskFailed(payload: any): Promise {\n this.logger.warn(`Task failed: ${payload.taskId}`);\n\n // 尝试协调恢复\n if (payload.severity === 'high') {\n await this.coordinateTask(`recovery-${payload.taskId}`, 'healing', {\n originalTask: payload,\n });\n }\n }\n\n /**\n * 处理模块状态变化事件\n */\n @OnEvent('module.state.changed')\n async handleModuleStateChanged(payload: any): Promise {\n this.logger.debug(\n `Module state changed: ${payload.module} -> ${payload.currentState}`,\n );\n\n // 同步内部状态映射,保持状态来源一致\n this.moduleStates.set(payload.module, payload.currentState);\n\n // 如果模块变为不可用,暂停相关任务\n if (\n payload.currentState === 'error' ||\n payload.currentState === 'unavailable'\n ) {\n await this.pauseModuleTasks(payload.module);\n }\n }\n\n /**\n * 暂停模块相关任务\n */\n private async pauseModuleTasks(moduleName: string): Promise {\n this.logger.warn(`Pausing tasks for module: ${moduleName}`);\n\n for (const [taskId, task] of this.pendingTasks) {\n const requiredModules = this.getRequiredModules(task.taskType);\n if (requiredModules.includes(moduleName)) {\n this.logger.warn(`Pausing task: ${taskId}`);\n this.eventBus.emit('task.paused', {\n taskId,\n reason: `Module unavailable: ${moduleName}`,\n });\n }\n }\n }\n\n /**\n * 获取待处理任务统计\n */\n getPendingTasksStats(): {\n total: number;\n byType: Record;\n oldestTask?: { id: string; age: number };\n } {\n const total = this.pendingTasks.size;\n const byType: Record = {};\n let oldestTask: { id: string; age: number } | undefined;\n\n for (const [taskId, task] of this.pendingTasks) {\n byType[task.taskType] = (byType[task.taskType] || 0) + 1;\n\n const age = Date.now() - task.startTime;\n if (!oldestTask || age > oldestTask.age) {\n oldestTask = { id: taskId, age };\n }\n }\n\n return { total, byType, oldestTask };\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/services/ai-orchestrator.service.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":17,"column":54,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":17,"endColumn":57,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[506,509],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[506,509],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'registerDefaultWorkflows' has no 'await' expression.","line":41,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":41,"endColumn":41,"suggestions":[{"messageId":"removeAsync","fix":{"range":[997,1044],"text":"registerDefaultWorkflows(): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":67,"column":42,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":67,"endColumn":45,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1613,1616],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1613,1616],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":75,"column":48,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":75,"endColumn":51,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1799,1802],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1799,1802],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":75,"column":62,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":75,"endColumn":65,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1813,1816],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1813,1816],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":76,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":76,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":84,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":84,"endColumn":72},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":85,"column":56,"nodeType":"Property","messageId":"anyAssignment","endLine":85,"endColumn":62},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":89,"column":53,"nodeType":"Property","messageId":"anyAssignment","endLine":89,"endColumn":58},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":98,"column":15,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":98,"endColumn":18,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2440,2443],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2440,2443],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":99,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":99,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2458,2461],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2458,2461],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":100,"column":14,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":100,"endColumn":17,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2476,2479],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2476,2479],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .steps on an `any` value.","line":103,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":103,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":105,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":105,"endColumn":71},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":105,"column":57,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":105,"endColumn":61},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `never`.","line":106,"column":20,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":106,"endColumn":30},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":115,"column":60,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":115,"endColumn":63,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2832,2835],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2832,2835],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":115,"column":74,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":115,"endColumn":77,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2846,2849],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2846,2849],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":18,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger, OnModuleInit } from '@nestjs/common';\nimport { EventBus } from '@wwjCommon/events/event-bus';\nimport { AiRegistryService } from './ai-registry.service';\n\n/**\n * AI Orchestrator Service - AI 编排服务\n *\n * 职责:\n * - 协调各 AI 模块的工作流程\n * - 管理 AI 任务的执行顺序\n * - 处理模块间的依赖关系\n * - 监控和调度 AI 服务\n */\n@Injectable()\nexport class AiOrchestratorService implements OnModuleInit {\n private readonly logger = new Logger(AiOrchestratorService.name);\n private readonly activeWorkflows = new Map();\n\n constructor(\n private readonly eventBus: EventBus,\n private readonly registryService: AiRegistryService,\n ) {}\n\n async onModuleInit() {\n this.logger.log('AI Orchestrator Service initialized');\n await this.initializeWorkflows();\n }\n\n /**\n * 初始化工作流程\n */\n private async initializeWorkflows(): Promise {\n this.logger.log('Initializing AI workflows...');\n // 注册默认工作流程\n await this.registerDefaultWorkflows();\n }\n\n /**\n * 注册默认工作流程\n */\n private async registerDefaultWorkflows(): Promise {\n // 自愈工作流程\n this.registerWorkflow('healing', {\n steps: ['detect', 'analyze', 'recover', 'verify'],\n timeout: 30000,\n retryCount: 3,\n });\n\n // 安全检查工作流程\n this.registerWorkflow('security', {\n steps: ['scan', 'analyze', 'protect', 'report'],\n timeout: 15000,\n retryCount: 2,\n });\n\n // 性能优化工作流程\n this.registerWorkflow('performance', {\n steps: ['monitor', 'analyze', 'optimize', 'validate'],\n timeout: 60000,\n retryCount: 1,\n });\n }\n\n /**\n * 注册工作流程\n */\n registerWorkflow(name: string, config: any): void {\n this.activeWorkflows.set(name, config);\n this.logger.log(`Workflow registered: ${name}`);\n }\n\n /**\n * 执行工作流程\n */\n async executeWorkflow(name: string, context: any): Promise {\n const workflow = this.activeWorkflows.get(name);\n if (!workflow) {\n throw new Error(`Workflow not found: ${name}`);\n }\n\n this.logger.log(`Executing workflow: ${name}`);\n\n try {\n const result = await this.processWorkflowSteps(workflow, context);\n this.eventBus.emit('workflow.completed', { name, result });\n return result;\n } catch (error) {\n this.logger.error(`Workflow execution failed: ${name}`, error);\n this.eventBus.emit('workflow.failed', { name, error });\n throw error;\n }\n }\n\n /**\n * 处理工作流程步骤\n */\n private async processWorkflowSteps(\n workflow: any,\n context: any,\n ): Promise {\n const results = [];\n\n for (const step of workflow.steps) {\n this.logger.debug(`Processing workflow step: ${step}`);\n const stepResult = await this.executeWorkflowStep(step, context);\n results.push(stepResult);\n }\n\n return results;\n }\n\n /**\n * 执行工作流程步骤\n */\n private async executeWorkflowStep(step: string, context: any): Promise {\n // 根据步骤类型调用相应的服务\n const services = this.registryService.getServicesByType(step);\n\n if (services.length === 0) {\n this.logger.warn(`No services found for step: ${step}`);\n return null;\n }\n\n // 执行第一个匹配的服务\n const service = services[0];\n return await service.execute(context);\n }\n\n /**\n * 获取活动工作流程\n */\n getActiveWorkflows(): string[] {\n return Array.from(this.activeWorkflows.keys());\n }\n\n /**\n * 停止工作流程\n */\n stopWorkflow(name: string): boolean {\n const removed = this.activeWorkflows.delete(name);\n if (removed) {\n this.logger.log(`Workflow stopped: ${name}`);\n this.eventBus.emit('workflow.stopped', { name });\n }\n return removed;\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/manager/services/ai-registry.service.ts","messages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":16,"column":20,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":16,"endColumn":23,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[291,294],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[291,294],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":16,"column":34,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":16,"endColumn":37,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[305,308],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[305,308],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'onModuleDestroy' has no 'await' expression.","line":43,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":43,"endColumn":24,"suggestions":[{"messageId":"removeAsync","fix":{"range":[979,985],"text":""},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'startHealthCheck' has no 'await' expression.","line":139,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":139,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3083,3122],"text":"startHealthCheck(): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-misused-promises","severity":2,"message":"Promise returned in function argument where a void return was expected.","line":140,"column":44,"nodeType":"ArrowFunctionExpression","messageId":"voidReturnArgument","endLine":142,"endColumn":6},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":165,"column":56,"nodeType":"Property","messageId":"anyAssignment","endLine":165,"endColumn":61}],"suppressedMessages":[],"errorCount":6,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import {\n Injectable,\n Logger,\n OnModuleInit,\n OnModuleDestroy,\n} from '@nestjs/common';\nimport { EventBus } from '@wwjCommon/events/event-bus';\n\n/**\n * AI Service Interface - AI 服务接口\n */\nexport interface AiService {\n name: string;\n type: string;\n version: string;\n execute(context: any): Promise;\n isHealthy(): Promise;\n}\n\n/**\n * AI Registry Service - AI 注册服务\n *\n * 职责:\n * - 管理 AI 服务的注册和注销\n * - 提供服务发现功能\n * - 监控服务健康状态\n * - 维护服务元数据\n */\n@Injectable()\nexport class AiRegistryService implements OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(AiRegistryService.name);\n private readonly services = new Map();\n private readonly servicesByType = new Map();\n private healthCheckInterval: NodeJS.Timeout | null = null;\n\n constructor(private readonly eventBus: EventBus) {}\n\n async onModuleInit() {\n this.logger.log('AI Registry Service initialized');\n await this.startHealthCheck();\n }\n\n async onModuleDestroy() {\n // 停止健康检查定时器,避免残留句柄\n if (this.healthCheckInterval) {\n clearInterval(this.healthCheckInterval);\n this.healthCheckInterval = null;\n this.logger.log('AI Registry Service health check stopped');\n }\n }\n\n /**\n * 注册 AI 服务\n */\n registerService(service: AiService): void {\n this.services.set(service.name, service);\n\n // 按类型分组\n if (!this.servicesByType.has(service.type)) {\n this.servicesByType.set(service.type, []);\n }\n this.servicesByType.get(service.type)!.push(service);\n\n this.logger.log(`Service registered: ${service.name} (${service.type})`);\n this.eventBus.emit('service.registered', service);\n }\n\n /**\n * 注销 AI 服务\n */\n unregisterService(serviceName: string): boolean {\n const service = this.services.get(serviceName);\n if (!service) {\n return false;\n }\n\n this.services.delete(serviceName);\n\n // 从类型分组中移除\n const typeServices = this.servicesByType.get(service.type);\n if (typeServices) {\n const index = typeServices.findIndex((s) => s.name === serviceName);\n if (index > -1) {\n typeServices.splice(index, 1);\n }\n }\n\n this.logger.log(`Service unregistered: ${serviceName}`);\n this.eventBus.emit('service.unregistered', service);\n return true;\n }\n\n /**\n * 获取服务\n */\n getService(serviceName: string): AiService | undefined {\n return this.services.get(serviceName);\n }\n\n /**\n * 根据类型获取服务列表\n */\n getServicesByType(type: string): AiService[] {\n return this.servicesByType.get(type) || [];\n }\n\n /**\n * 获取所有服务\n */\n getAllServices(): AiService[] {\n return Array.from(this.services.values());\n }\n\n /**\n * 获取服务统计信息\n */\n getServiceStats(): {\n total: number;\n byType: Record;\n healthy: number;\n } {\n const total = this.services.size;\n const byType: Record = {};\n\n for (const [type, services] of this.servicesByType) {\n byType[type] = services.length;\n }\n\n return {\n total,\n byType,\n healthy: 0, // 将在健康检查中更新\n };\n }\n\n /**\n * 启动健康检查\n */\n private async startHealthCheck(): Promise {\n this.healthCheckInterval = setInterval(async () => {\n await this.performHealthCheck();\n }, 30000);\n }\n\n /**\n * 执行健康检查\n */\n private async performHealthCheck(): Promise {\n let healthyCount = 0;\n\n for (const service of this.services.values()) {\n try {\n const isHealthy = await service.isHealthy();\n if (isHealthy) {\n healthyCount++;\n } else {\n this.logger.warn(`Service unhealthy: ${service.name}`);\n this.eventBus.emit('service.unhealthy', service);\n }\n } catch (error) {\n this.logger.error(\n `Health check failed for service: ${service.name}`,\n error,\n );\n this.eventBus.emit('service.error', { service, error });\n }\n }\n\n this.logger.debug(\n `Health check completed: ${healthyCount}/${this.services.size} services healthy`,\n );\n }\n\n /**\n * 查找服务\n */\n findServices(predicate: (service: AiService) => boolean): AiService[] {\n return Array.from(this.services.values()).filter(predicate);\n }\n\n /**\n * 检查服务是否存在\n */\n hasService(serviceName: string): boolean {\n return this.services.has(serviceName);\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/safe/analyzers/security.analyzer.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkJwtSecurity' has no 'await' expression.","line":151,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":151,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3559,3613],"text":"checkJwtSecurity(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkPasswordPolicy' has no 'await' expression.","line":169,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":169,"endColumn":36,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3926,3983],"text":"checkPasswordPolicy(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkSessionSecurity' has no 'await' expression.","line":186,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":186,"endColumn":37,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4282,4340],"text":"checkSessionSecurity(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkMfaSecurity' has no 'await' expression.","line":203,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":203,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4642,4696],"text":"checkMfaSecurity(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkDataEncryption' has no 'await' expression.","line":219,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":219,"endColumn":36,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4979,5036],"text":"checkDataEncryption(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkDataAccess' has no 'await' expression.","line":236,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":236,"endColumn":32,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5335,5388],"text":"checkDataAccess(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkDataBackup' has no 'await' expression.","line":253,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":253,"endColumn":32,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5688,5741],"text":"checkDataBackup(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkDataRetention' has no 'await' expression.","line":270,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":270,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6030,6086],"text":"checkDataRetention(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkHttpsSecurity' has no 'await' expression.","line":287,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":287,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6391,6447],"text":"checkHttpsSecurity(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkCorsConfiguration' has no 'await' expression.","line":304,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":304,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[6732,6792],"text":"checkCorsConfiguration(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkRateLimiting' has no 'await' expression.","line":321,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":321,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7127,7182],"text":"checkRateLimiting(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkFirewallRules' has no 'await' expression.","line":338,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":338,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7470,7526],"text":"checkFirewallRules(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkInputValidation' has no 'await' expression.","line":355,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":355,"endColumn":37,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7820,7878],"text":"checkInputValidation(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkSqlInjection' has no 'await' expression.","line":372,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":372,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[8180,8235],"text":"checkSqlInjection(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkXssProtection' has no 'await' expression.","line":389,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":389,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[8551,8607],"text":"checkXssProtection(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'checkDependencyVulnerabilities' has no 'await' expression.","line":406,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":406,"endColumn":47,"suggestions":[{"messageId":"removeAsync","fix":{"range":[8899,8967],"text":"checkDependencyVulnerabilities(): SecurityCheckResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":524,"column":27,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":524,"endColumn":30,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[12229,12232],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[12229,12232],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":17,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger } from '@nestjs/common';\n\n/**\n * Security Analyzer - 安全分析器\n *\n * 职责:\n * - 分析系统安全状态\n * - 识别潜在安全威胁\n * - 评估安全风险等级\n * - 生成安全报告\n */\n@Injectable()\nexport class SecurityAnalyzer {\n private readonly logger = new Logger(SecurityAnalyzer.name);\n\n /**\n * 分析系统安全状态\n */\n async analyzeSystemSecurity(): Promise {\n this.logger.log('Starting system security analysis');\n\n const startTime = Date.now();\n\n try {\n // 执行各项安全检查\n const [authSecurity, dataSecurity, networkSecurity, codeSecurity] =\n await Promise.all([\n this.analyzeAuthSecurity(),\n this.analyzeDataSecurity(),\n this.analyzeNetworkSecurity(),\n this.analyzeCodeSecurity(),\n ]);\n\n const overallRisk = this.calculateOverallRisk([\n authSecurity.riskLevel,\n dataSecurity.riskLevel,\n networkSecurity.riskLevel,\n codeSecurity.riskLevel,\n ]);\n\n return {\n timestamp: Date.now(),\n duration: Date.now() - startTime,\n overallRisk,\n categories: {\n authentication: authSecurity,\n dataProtection: dataSecurity,\n networkSecurity: networkSecurity,\n codeQuality: codeSecurity,\n },\n recommendations: this.generateRecommendations(overallRisk),\n };\n } catch (error) {\n this.logger.error('Security analysis failed', error);\n throw error;\n }\n }\n\n /**\n * 分析认证安全\n */\n private async analyzeAuthSecurity(): Promise {\n // 检查认证机制\n const checks = [\n this.checkJwtSecurity(),\n this.checkPasswordPolicy(),\n this.checkSessionSecurity(),\n this.checkMfaSecurity(),\n ];\n\n const results = await Promise.all(checks);\n const riskLevel = this.calculateCategoryRisk(results);\n\n return {\n category: 'authentication',\n riskLevel,\n checks: results,\n score: this.calculateSecurityScore(results),\n };\n }\n\n /**\n * 分析数据安全\n */\n private async analyzeDataSecurity(): Promise {\n const checks = [\n this.checkDataEncryption(),\n this.checkDataAccess(),\n this.checkDataBackup(),\n this.checkDataRetention(),\n ];\n\n const results = await Promise.all(checks);\n const riskLevel = this.calculateCategoryRisk(results);\n\n return {\n category: 'dataProtection',\n riskLevel,\n checks: results,\n score: this.calculateSecurityScore(results),\n };\n }\n\n /**\n * 分析网络安全\n */\n private async analyzeNetworkSecurity(): Promise {\n const checks = [\n this.checkHttpsSecurity(),\n this.checkCorsConfiguration(),\n this.checkRateLimiting(),\n this.checkFirewallRules(),\n ];\n\n const results = await Promise.all(checks);\n const riskLevel = this.calculateCategoryRisk(results);\n\n return {\n category: 'networkSecurity',\n riskLevel,\n checks: results,\n score: this.calculateSecurityScore(results),\n };\n }\n\n /**\n * 分析代码安全\n */\n private async analyzeCodeSecurity(): Promise {\n const checks = [\n this.checkInputValidation(),\n this.checkSqlInjection(),\n this.checkXssProtection(),\n this.checkDependencyVulnerabilities(),\n ];\n\n const results = await Promise.all(checks);\n const riskLevel = this.calculateCategoryRisk(results);\n\n return {\n category: 'codeQuality',\n riskLevel,\n checks: results,\n score: this.calculateSecurityScore(results),\n };\n }\n\n /**\n * JWT 安全检查\n */\n private async checkJwtSecurity(): Promise {\n // 实现 JWT 安全检查逻辑\n return {\n name: 'JWT Security',\n status: 'pass',\n riskLevel: 'low',\n message: 'JWT configuration is secure',\n details: {\n algorithm: 'RS256',\n expiration: '1h',\n secretRotation: true,\n },\n };\n }\n\n /**\n * 密码策略检查\n */\n private async checkPasswordPolicy(): Promise {\n return {\n name: 'Password Policy',\n status: 'pass',\n riskLevel: 'low',\n message: 'Password policy meets security requirements',\n details: {\n minLength: 8,\n complexity: true,\n expiration: 90,\n },\n };\n }\n\n /**\n * 会话安全检查\n */\n private async checkSessionSecurity(): Promise {\n return {\n name: 'Session Security',\n status: 'pass',\n riskLevel: 'medium',\n message: 'Session configuration needs improvement',\n details: {\n httpOnly: true,\n secure: true,\n sameSite: 'strict',\n },\n };\n }\n\n /**\n * 多因素认证检查\n */\n private async checkMfaSecurity(): Promise {\n return {\n name: 'Multi-Factor Authentication',\n status: 'warning',\n riskLevel: 'medium',\n message: 'MFA is not enabled for all users',\n details: {\n enabled: false,\n coverage: '30%',\n },\n };\n }\n\n /**\n * 数据加密检查\n */\n private async checkDataEncryption(): Promise {\n return {\n name: 'Data Encryption',\n status: 'pass',\n riskLevel: 'low',\n message: 'Data encryption is properly configured',\n details: {\n atRest: true,\n inTransit: true,\n algorithm: 'AES-256',\n },\n };\n }\n\n /**\n * 数据访问检查\n */\n private async checkDataAccess(): Promise {\n return {\n name: 'Data Access Control',\n status: 'pass',\n riskLevel: 'low',\n message: 'Data access controls are properly implemented',\n details: {\n rbac: true,\n audit: true,\n encryption: true,\n },\n };\n }\n\n /**\n * 数据备份检查\n */\n private async checkDataBackup(): Promise {\n return {\n name: 'Data Backup',\n status: 'pass',\n riskLevel: 'low',\n message: 'Data backup strategy is adequate',\n details: {\n frequency: 'daily',\n encryption: true,\n offsite: true,\n },\n };\n }\n\n /**\n * 数据保留检查\n */\n private async checkDataRetention(): Promise {\n return {\n name: 'Data Retention',\n status: 'pass',\n riskLevel: 'low',\n message: 'Data retention policies are compliant',\n details: {\n policy: 'defined',\n automation: true,\n compliance: 'GDPR',\n },\n };\n }\n\n /**\n * HTTPS 安全检查\n */\n private async checkHttpsSecurity(): Promise {\n return {\n name: 'HTTPS Security',\n status: 'pass',\n riskLevel: 'low',\n message: 'HTTPS is properly configured',\n details: {\n enforced: true,\n tlsVersion: '1.3',\n hsts: true,\n },\n };\n }\n\n /**\n * CORS 配置检查\n */\n private async checkCorsConfiguration(): Promise {\n return {\n name: 'CORS Configuration',\n status: 'warning',\n riskLevel: 'medium',\n message: 'CORS configuration may be too permissive',\n details: {\n origins: ['*'],\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'DELETE'],\n },\n };\n }\n\n /**\n * 速率限制检查\n */\n private async checkRateLimiting(): Promise {\n return {\n name: 'Rate Limiting',\n status: 'pass',\n riskLevel: 'low',\n message: 'Rate limiting is properly configured',\n details: {\n enabled: true,\n limits: '100/min',\n burst: 10,\n },\n };\n }\n\n /**\n * 防火墙规则检查\n */\n private async checkFirewallRules(): Promise {\n return {\n name: 'Firewall Rules',\n status: 'pass',\n riskLevel: 'low',\n message: 'Firewall rules are properly configured',\n details: {\n enabled: true,\n defaultDeny: true,\n logging: true,\n },\n };\n }\n\n /**\n * 输入验证检查\n */\n private async checkInputValidation(): Promise {\n return {\n name: 'Input Validation',\n status: 'pass',\n riskLevel: 'low',\n message: 'Input validation is comprehensive',\n details: {\n sanitization: true,\n validation: true,\n whitelisting: true,\n },\n };\n }\n\n /**\n * SQL 注入检查\n */\n private async checkSqlInjection(): Promise {\n return {\n name: 'SQL Injection Protection',\n status: 'pass',\n riskLevel: 'low',\n message: 'SQL injection protection is effective',\n details: {\n parameterizedQueries: true,\n orm: 'TypeORM',\n escaping: true,\n },\n };\n }\n\n /**\n * XSS 保护检查\n */\n private async checkXssProtection(): Promise {\n return {\n name: 'XSS Protection',\n status: 'pass',\n riskLevel: 'low',\n message: 'XSS protection is properly implemented',\n details: {\n csp: true,\n sanitization: true,\n encoding: true,\n },\n };\n }\n\n /**\n * 依赖漏洞检查\n */\n private async checkDependencyVulnerabilities(): Promise {\n return {\n name: 'Dependency Vulnerabilities',\n status: 'warning',\n riskLevel: 'medium',\n message: 'Some dependencies have known vulnerabilities',\n details: {\n total: 150,\n vulnerable: 3,\n critical: 0,\n high: 1,\n medium: 2,\n },\n };\n }\n\n /**\n * 计算分类风险等级\n */\n private calculateCategoryRisk(results: SecurityCheckResult[]): RiskLevel {\n const riskLevels = results.map((r) => r.riskLevel);\n\n if (riskLevels.includes('critical')) return 'critical';\n if (riskLevels.includes('high')) return 'high';\n if (riskLevels.includes('medium')) return 'medium';\n return 'low';\n }\n\n /**\n * 计算整体风险等级\n */\n private calculateOverallRisk(categoryRisks: RiskLevel[]): RiskLevel {\n const riskWeights = { critical: 4, high: 3, medium: 2, low: 1 };\n const totalWeight = categoryRisks.reduce(\n (sum, risk) => sum + riskWeights[risk],\n 0,\n );\n const avgWeight = totalWeight / categoryRisks.length;\n\n if (avgWeight >= 3.5) return 'critical';\n if (avgWeight >= 2.5) return 'high';\n if (avgWeight >= 1.5) return 'medium';\n return 'low';\n }\n\n /**\n * 计算安全评分\n */\n private calculateSecurityScore(results: SecurityCheckResult[]): number {\n const statusWeights = { pass: 100, warning: 60, fail: 0 };\n const totalScore = results.reduce(\n (sum, result) => sum + statusWeights[result.status],\n 0,\n );\n return Math.round(totalScore / results.length);\n }\n\n /**\n * 生成安全建议\n */\n private generateRecommendations(riskLevel: RiskLevel): string[] {\n const recommendations: Record = {\n critical: [\n 'Immediately address critical security vulnerabilities',\n 'Implement emergency security patches',\n 'Review and strengthen access controls',\n 'Conduct comprehensive security audit',\n ],\n high: [\n 'Address high-priority security issues within 24 hours',\n 'Implement additional security monitoring',\n 'Review security policies and procedures',\n 'Consider security training for development team',\n ],\n medium: [\n 'Address medium-priority security issues within a week',\n 'Implement security best practices',\n 'Regular security assessments',\n 'Update security documentation',\n ],\n low: [\n 'Maintain current security posture',\n 'Continue regular security monitoring',\n 'Keep security tools and policies updated',\n 'Periodic security reviews',\n ],\n };\n\n return recommendations[riskLevel] || recommendations.low;\n }\n}\n\n// 类型定义\nexport interface SecurityAnalysisResult {\n timestamp: number;\n duration: number;\n overallRisk: RiskLevel;\n categories: {\n authentication: SecurityCategoryResult;\n dataProtection: SecurityCategoryResult;\n networkSecurity: SecurityCategoryResult;\n codeQuality: SecurityCategoryResult;\n };\n recommendations: string[];\n}\n\nexport interface SecurityCategoryResult {\n category: string;\n riskLevel: RiskLevel;\n checks: SecurityCheckResult[];\n score: number;\n}\n\nexport interface SecurityCheckResult {\n name: string;\n status: 'pass' | 'warning' | 'fail';\n riskLevel: RiskLevel;\n message: string;\n details: Record;\n}\n\nexport type RiskLevel = 'low' | 'medium' | 'high' | 'critical';\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/safe/detectors/vulnerability.detector.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'scanDependencyVulnerabilities' has no 'await' expression.","line":90,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":90,"endColumn":46,"suggestions":[{"messageId":"removeAsync","fix":{"range":[2315,2378],"text":"scanDependencyVulnerabilities(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'scanConfigurationVulnerabilities' has no 'await' expression.","line":138,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":138,"endColumn":49,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3685,3751],"text":"scanConfigurationVulnerabilities(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'scanNetworkVulnerabilities' has no 'await' expression.","line":166,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":166,"endColumn":43,"suggestions":[{"messageId":"removeAsync","fix":{"range":[4453,4513],"text":"scanNetworkVulnerabilities(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectSqlInjection' has no 'await' expression.","line":194,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":194,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5186,5238],"text":"detectSqlInjection(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectXssVulnerabilities' has no 'await' expression.","line":202,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":202,"endColumn":41,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5317,5375],"text":"detectXssVulnerabilities(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectAuthenticationBypass' has no 'await' expression.","line":210,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":210,"endColumn":43,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5451,5511],"text":"detectAuthenticationBypass(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectPrivilegeEscalation' has no 'await' expression.","line":218,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":218,"endColumn":42,"suggestions":[{"messageId":"removeAsync","fix":{"range":[5586,5645],"text":"detectPrivilegeEscalation(): Vulnerability[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectSuspiciousActivity' has no 'await' expression.","line":307,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":307,"endColumn":41,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7603,7654],"text":"detectSuspiciousActivity(): Threat[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectAnomalousTraffic' has no 'await' expression.","line":315,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":315,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7727,7776],"text":"detectAnomalousTraffic(): Threat[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectBruteForceAttacks' has no 'await' expression.","line":323,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":323,"endColumn":40,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7851,7901],"text":"detectBruteForceAttacks(): Threat[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'detectMaliciousPayloads' has no 'await' expression.","line":331,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":331,"endColumn":40,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7974,8024],"text":"detectMaliciousPayloads(): Threat[]"},"desc":"Remove 'async'."}]}],"suppressedMessages":[],"errorCount":11,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { Injectable, Logger } from '@nestjs/common';\n\n/**\n * Vulnerability Detector - 漏洞检测器\n *\n * 职责:\n * - 扫描系统漏洞\n * - 检测安全威胁\n * - 监控异常行为\n * - 生成威胁报告\n */\n@Injectable()\nexport class VulnerabilityDetector {\n private readonly logger = new Logger(VulnerabilityDetector.name);\n\n /**\n * 执行全面漏洞扫描\n */\n async scanVulnerabilities(): Promise {\n this.logger.log('Starting comprehensive vulnerability scan');\n\n const startTime = Date.now();\n\n try {\n const [\n codeVulnerabilities,\n dependencyVulnerabilities,\n configVulnerabilities,\n networkVulnerabilities,\n ] = await Promise.all([\n this.scanCodeVulnerabilities(),\n this.scanDependencyVulnerabilities(),\n this.scanConfigurationVulnerabilities(),\n this.scanNetworkVulnerabilities(),\n ]);\n\n const allVulnerabilities = [\n ...codeVulnerabilities,\n ...dependencyVulnerabilities,\n ...configVulnerabilities,\n ...networkVulnerabilities,\n ];\n\n return {\n timestamp: Date.now(),\n duration: Date.now() - startTime,\n totalVulnerabilities: allVulnerabilities.length,\n severityBreakdown: this.calculateSeverityBreakdown(allVulnerabilities),\n vulnerabilities: allVulnerabilities,\n recommendations:\n this.generateVulnerabilityRecommendations(allVulnerabilities),\n };\n } catch (error) {\n this.logger.error('Vulnerability scan failed', error);\n throw error;\n }\n }\n\n /**\n * 扫描代码漏洞\n */\n private async scanCodeVulnerabilities(): Promise {\n this.logger.debug('Scanning code vulnerabilities');\n\n // 模拟代码漏洞扫描\n const vulnerabilities: Vulnerability[] = [];\n\n // SQL 注入检测\n const sqlInjectionVulns = await this.detectSqlInjection();\n vulnerabilities.push(...sqlInjectionVulns);\n\n // XSS 检测\n const xssVulns = await this.detectXssVulnerabilities();\n vulnerabilities.push(...xssVulns);\n\n // 认证绕过检测\n const authBypassVulns = await this.detectAuthenticationBypass();\n vulnerabilities.push(...authBypassVulns);\n\n // 权限提升检测\n const privilegeEscalationVulns = await this.detectPrivilegeEscalation();\n vulnerabilities.push(...privilegeEscalationVulns);\n\n return vulnerabilities;\n }\n\n /**\n * 扫描依赖漏洞\n */\n private async scanDependencyVulnerabilities(): Promise {\n this.logger.debug('Scanning dependency vulnerabilities');\n\n // 模拟依赖漏洞扫描结果\n return [\n {\n id: 'CVE-2023-1234',\n type: 'dependency',\n severity: 'high',\n title: 'Remote Code Execution in lodash',\n description:\n 'A prototype pollution vulnerability in lodash allows remote code execution',\n affectedComponent: 'lodash@4.17.20',\n cweId: 'CWE-1321',\n cvssScore: 8.5,\n discoveredAt: Date.now(),\n status: 'open',\n remediation: {\n type: 'update',\n description: 'Update lodash to version 4.17.21 or later',\n effort: 'low',\n },\n },\n {\n id: 'CVE-2023-5678',\n type: 'dependency',\n severity: 'medium',\n title: 'Information Disclosure in express',\n description:\n 'Express middleware may leak sensitive information in error messages',\n affectedComponent: 'express@4.18.0',\n cweId: 'CWE-200',\n cvssScore: 5.3,\n discoveredAt: Date.now(),\n status: 'open',\n remediation: {\n type: 'configuration',\n description:\n 'Configure error handling to prevent information leakage',\n effort: 'medium',\n },\n },\n ];\n }\n\n /**\n * 扫描配置漏洞\n */\n private async scanConfigurationVulnerabilities(): Promise {\n this.logger.debug('Scanning configuration vulnerabilities');\n\n return [\n {\n id: 'CONFIG-001',\n type: 'configuration',\n severity: 'medium',\n title: 'Weak CORS Configuration',\n description:\n 'CORS is configured to allow all origins which may lead to security issues',\n affectedComponent: 'CORS Middleware',\n cweId: 'CWE-346',\n cvssScore: 4.3,\n discoveredAt: Date.now(),\n status: 'open',\n remediation: {\n type: 'configuration',\n description: 'Restrict CORS origins to specific trusted domains',\n effort: 'low',\n },\n },\n ];\n }\n\n /**\n * 扫描网络漏洞\n */\n private async scanNetworkVulnerabilities(): Promise {\n this.logger.debug('Scanning network vulnerabilities');\n\n return [\n {\n id: 'NET-001',\n type: 'network',\n severity: 'low',\n title: 'Missing Security Headers',\n description: 'Some security headers are not configured properly',\n affectedComponent: 'HTTP Headers',\n cweId: 'CWE-693',\n cvssScore: 3.1,\n discoveredAt: Date.now(),\n status: 'open',\n remediation: {\n type: 'configuration',\n description:\n 'Add missing security headers (CSP, HSTS, X-Frame-Options)',\n effort: 'low',\n },\n },\n ];\n }\n\n /**\n * 检测 SQL 注入漏洞\n */\n private async detectSqlInjection(): Promise {\n // 模拟 SQL 注入检测\n return [];\n }\n\n /**\n * 检测 XSS 漏洞\n */\n private async detectXssVulnerabilities(): Promise {\n // 模拟 XSS 检测\n return [];\n }\n\n /**\n * 检测认证绕过漏洞\n */\n private async detectAuthenticationBypass(): Promise {\n // 模拟认证绕过检测\n return [];\n }\n\n /**\n * 检测权限提升漏洞\n */\n private async detectPrivilegeEscalation(): Promise {\n // 模拟权限提升检测\n return [];\n }\n\n /**\n * 计算严重程度分布\n */\n private calculateSeverityBreakdown(\n vulnerabilities: Vulnerability[],\n ): SeverityBreakdown {\n const breakdown = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n };\n\n vulnerabilities.forEach((vuln) => {\n breakdown[vuln.severity]++;\n });\n\n return breakdown;\n }\n\n /**\n * 生成漏洞修复建议\n */\n private generateVulnerabilityRecommendations(\n vulnerabilities: Vulnerability[],\n ): string[] {\n const recommendations: string[] = [];\n\n const criticalCount = vulnerabilities.filter(\n (v) => v.severity === 'critical',\n ).length;\n const highCount = vulnerabilities.filter(\n (v) => v.severity === 'high',\n ).length;\n\n if (criticalCount > 0) {\n recommendations.push(\n `Immediately address ${criticalCount} critical vulnerabilities`,\n );\n }\n\n if (highCount > 0) {\n recommendations.push(\n `Address ${highCount} high-severity vulnerabilities within 24 hours`,\n );\n }\n\n recommendations.push(\n 'Implement automated vulnerability scanning in CI/CD pipeline',\n );\n recommendations.push('Regular security training for development team');\n recommendations.push(\n 'Establish vulnerability disclosure and response process',\n );\n\n return recommendations;\n }\n\n /**\n * 检测实时威胁\n */\n async detectRealTimeThreats(): Promise {\n this.logger.log('Starting real-time threat detection');\n\n const threats = await Promise.all([\n this.detectSuspiciousActivity(),\n this.detectAnomalousTraffic(),\n this.detectBruteForceAttacks(),\n this.detectMaliciousPayloads(),\n ]);\n\n const allThreats = threats.flat();\n\n return {\n timestamp: Date.now(),\n threatsDetected: allThreats.length,\n threats: allThreats,\n riskLevel: this.calculateThreatRiskLevel(allThreats),\n };\n }\n\n /**\n * 检测可疑活动\n */\n private async detectSuspiciousActivity(): Promise {\n // 模拟可疑活动检测\n return [];\n }\n\n /**\n * 检测异常流量\n */\n private async detectAnomalousTraffic(): Promise {\n // 模拟异常流量检测\n return [];\n }\n\n /**\n * 检测暴力破解攻击\n */\n private async detectBruteForceAttacks(): Promise {\n // 模拟暴力破解检测\n return [];\n }\n\n /**\n * 检测恶意载荷\n */\n private async detectMaliciousPayloads(): Promise {\n // 模拟恶意载荷检测\n return [];\n }\n\n /**\n * 计算威胁风险等级\n */\n private calculateThreatRiskLevel(\n threats: Threat[],\n ): 'low' | 'medium' | 'high' | 'critical' {\n if (threats.length === 0) return 'low';\n\n const highSeverityThreats = threats.filter(\n (t) => t.severity === 'high' || t.severity === 'critical',\n );\n\n if (highSeverityThreats.length > 5) return 'critical';\n if (highSeverityThreats.length > 2) return 'high';\n if (threats.length > 10) return 'medium';\n\n return 'low';\n }\n}\n\n// 类型定义\nexport interface VulnerabilityScanResult {\n timestamp: number;\n duration: number;\n totalVulnerabilities: number;\n severityBreakdown: SeverityBreakdown;\n vulnerabilities: Vulnerability[];\n recommendations: string[];\n}\n\nexport interface Vulnerability {\n id: string;\n type: 'code' | 'dependency' | 'configuration' | 'network';\n severity: 'low' | 'medium' | 'high' | 'critical';\n title: string;\n description: string;\n affectedComponent: string;\n cweId?: string;\n cvssScore?: number;\n discoveredAt: number;\n status: 'open' | 'in_progress' | 'resolved' | 'false_positive';\n remediation: {\n type: 'update' | 'patch' | 'configuration' | 'code_change';\n description: string;\n effort: 'low' | 'medium' | 'high';\n };\n}\n\nexport interface SeverityBreakdown {\n critical: number;\n high: number;\n medium: number;\n low: number;\n}\n\nexport interface ThreatDetectionResult {\n timestamp: number;\n threatsDetected: number;\n threats: Threat[];\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n}\n\nexport interface Threat {\n id: string;\n type:\n | 'suspicious_activity'\n | 'anomalous_traffic'\n | 'brute_force'\n | 'malicious_payload';\n severity: 'low' | 'medium' | 'high' | 'critical';\n source: string;\n description: string;\n detectedAt: number;\n indicators: string[];\n}\n","usedDeprecatedRules":[]},{"filePath":"/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-ai/src/safe/protectors/access.protector.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":37,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":37,"endColumn":56},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'monitorAccessPatterns' has no 'await' expression.","line":143,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":143,"endColumn":30,"suggestions":[{"messageId":"removeAsync","fix":{"range":[3194,3255],"text":"monitorAccessPatterns(): AccessPatternAnalysis"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":176,"column":32,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":176,"endColumn":35,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4124,4127],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4124,4127],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":2,"message":"Unsafe return of a value of type `any`.","line":177,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":183,"endColumn":7},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .ip on an `any` value.","line":178,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":178,"endColumn":17},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .connection on an `any` value.","line":179,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":179,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .socket on an `any` value.","line":180,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":180,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `any` typed value.","line":181,"column":7,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":181,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .headers on an `any` value.","line":181,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":181,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access [0] on an `any` value.","line":181,"column":54,"nodeType":"Literal","messageId":"unsafeMemberExpression","endLine":181,"endColumn":55},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":189,"column":52,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":189,"endColumn":55,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4416,4419],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4416,4419],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":197,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":197,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .method on an `any` value.","line":197,"column":23,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":197,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":198,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":198,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .url on an `any` value.","line":198,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":198,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":199,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":199,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .headers on an `any` value.","line":199,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":199,"endColumn":33},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":224,"column":57,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":224,"endColumn":60,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5259,5262],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5259,5262],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":237,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":237,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .headers on an `any` value.","line":237,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":237,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":238,"column":50,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":238,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":2,"message":"Unsafe argument of type `any` assigned to a parameter of type `string`.","line":243,"column":40,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":243,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .url on an `any` value.","line":243,"column":48,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":243,"endColumn":51},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":253,"column":57,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":253,"endColumn":60,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5894,5897],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5894,5897],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":263,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":263,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .method on an `any` value.","line":263,"column":25,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":263,"endColumn":31},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":264,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":264,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .url on an `any` value.","line":264,"column":22,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":264,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":265,"column":9,"nodeType":"Property","messageId":"anyAssignment","endLine":265,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .headers on an `any` value.","line":265,"column":28,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":265,"endColumn":35},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getUserPermissions' has no 'await' expression.","line":314,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":314,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7217,7283],"text":"getUserPermissions(userId: string): UserPermissions"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'getSecurityPolicy' has no 'await' expression.","line":344,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":344,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[7889,7973],"text":"getSecurityPolicy(\n policyName: string,\n ): SecurityPolicy | null"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'evaluateCondition' has no 'await' expression.","line":388,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":388,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[8991,9104],"text":"evaluateCondition(\n condition: PolicyCondition,\n context: SecurityContext,\n ): PolicyResult"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'context' is defined but never used.","line":434,"column":5,"nodeType":null,"messageId":"unusedVar","endLine":434,"endColumn":12},{"ruleId":"@typescript-eslint/require-await","severity":2,"message":"Async method 'logSecurityEvent' has no 'await' expression.","line":479,"column":3,"nodeType":"FunctionExpression","messageId":"missingAwait","endLine":479,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[11195,11262],"text":"logSecurityEvent(eventType: string, data: any): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":479,"column":59,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":479,"endColumn":62,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[11243,11246],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[11243,11246],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":541,"column":27,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":541,"endColumn":30,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[12638,12641],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[12638,12641],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}],"suppressedMessages":[],"errorCount":37,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import {\n Injectable,\n Logger,\n CanActivate,\n ExecutionContext,\n} from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport { Observable } from 'rxjs';\n\n/**\n * Access Protector - 访问保护器\n *\n * 职责:\n * - 控制系统访问权限\n * - 实施安全策略\n * - 监控访问行为\n * - 防止未授权访问\n */\n@Injectable()\nexport class AccessProtector implements CanActivate {\n private readonly logger = new Logger(AccessProtector.name);\n private readonly accessAttempts = new Map();\n private readonly blockedIps = new Set();\n private readonly suspiciousActivities = new Map<\n string,\n SuspiciousActivity[]\n >();\n\n constructor(private reflector: Reflector) {}\n\n /**\n * 守卫方法 - 检查访问权限\n */\n canActivate(\n context: ExecutionContext,\n ): boolean | Promise | Observable {\n const request = context.switchToHttp().getRequest();\n const clientIp = this.getClientIp(request);\n\n // 检查 IP 是否被阻止\n if (this.blockedIps.has(clientIp)) {\n this.logger.warn(`Blocked IP attempted access: ${clientIp}`);\n return false;\n }\n\n // 记录访问尝试\n this.recordAccessAttempt(clientIp, request);\n\n // 检查访问频率\n if (this.isAccessRateLimited(clientIp)) {\n this.logger.warn(`Rate limit exceeded for IP: ${clientIp}`);\n return false;\n }\n\n // 检查可疑活动\n if (this.detectSuspiciousActivity(clientIp, request)) {\n this.logger.warn(`Suspicious activity detected from IP: ${clientIp}`);\n this.handleSuspiciousActivity(clientIp, request);\n return false;\n }\n\n return true;\n }\n\n /**\n * 验证用户权限\n */\n async validateUserPermissions(\n userId: string,\n resource: string,\n action: string,\n ): Promise {\n this.logger.debug(\n `Validating permissions for user ${userId}: ${action} on ${resource}`,\n );\n\n try {\n // 获取用户角色和权限\n const userPermissions = await this.getUserPermissions(userId);\n\n // 检查资源访问权限\n const hasPermission = this.checkResourcePermission(\n userPermissions,\n resource,\n action,\n );\n\n if (!hasPermission) {\n this.logger.warn(\n `Permission denied for user ${userId}: ${action} on ${resource}`,\n );\n await this.logSecurityEvent('PERMISSION_DENIED', {\n userId,\n resource,\n action,\n timestamp: Date.now(),\n });\n }\n\n return hasPermission;\n } catch (error) {\n this.logger.error(\n `Error validating permissions for user ${userId}`,\n error,\n );\n return false;\n }\n }\n\n /**\n * 实施安全策略\n */\n async enforceSecurityPolicy(\n policyName: string,\n context: SecurityContext,\n ): Promise {\n this.logger.debug(`Enforcing security policy: ${policyName}`);\n\n const policy = await this.getSecurityPolicy(policyName);\n\n if (!policy) {\n return {\n allowed: false,\n reason: 'Policy not found',\n actions: [],\n };\n }\n\n // 评估策略条件\n const evaluation = await this.evaluatePolicyConditions(policy, context);\n\n if (!evaluation.allowed) {\n // 执行策略动作\n await this.executePolicyActions(policy.denyActions, context);\n }\n\n return evaluation;\n }\n\n /**\n * 监控访问模式\n */\n async monitorAccessPatterns(): Promise {\n this.logger.log('Analyzing access patterns');\n\n const analysis = {\n timestamp: Date.now(),\n totalAccesses: 0,\n uniqueIps: 0,\n suspiciousActivities: 0,\n blockedAttempts: 0,\n topSources: [] as AccessSource[],\n anomalies: [] as AccessAnomaly[],\n };\n\n // 分析访问尝试\n for (const [ip, attempts] of this.accessAttempts.entries()) {\n analysis.totalAccesses += attempts.length;\n\n // 检查异常模式\n const anomalies = this.detectAccessAnomalies(ip, attempts);\n analysis.anomalies.push(...anomalies);\n }\n\n analysis.uniqueIps = this.accessAttempts.size;\n analysis.suspiciousActivities = this.suspiciousActivities.size;\n analysis.blockedAttempts = this.blockedIps.size;\n analysis.topSources = this.getTopAccessSources();\n\n return analysis;\n }\n\n /**\n * 获取客户端 IP\n */\n private getClientIp(request: any): string {\n return (\n request.ip ||\n request.connection?.remoteAddress ||\n request.socket?.remoteAddress ||\n request.headers['x-forwarded-for']?.split(',')[0] ||\n 'unknown'\n );\n }\n\n /**\n * 记录访问尝试\n */\n private recordAccessAttempt(ip: string, request: any): void {\n if (!this.accessAttempts.has(ip)) {\n this.accessAttempts.set(ip, []);\n }\n\n const attempts = this.accessAttempts.get(ip)!;\n attempts.push({\n timestamp: Date.now(),\n method: request.method,\n url: request.url,\n userAgent: request.headers['user-agent'],\n success: true,\n });\n\n // 保持最近 1000 次访问记录\n if (attempts.length > 1000) {\n attempts.splice(0, attempts.length - 1000);\n }\n }\n\n /**\n * 检查访问频率限制\n */\n private isAccessRateLimited(ip: string): boolean {\n const attempts = this.accessAttempts.get(ip) || [];\n const recentAttempts = attempts.filter(\n (attempt) => Date.now() - attempt.timestamp < 60000, // 1分钟内\n );\n\n return recentAttempts.length > 100; // 每分钟最多100次请求\n }\n\n /**\n * 检测可疑活动\n */\n private detectSuspiciousActivity(ip: string, request: any): boolean {\n const attempts = this.accessAttempts.get(ip) || [];\n\n // 检查快速连续请求\n const recentAttempts = attempts.filter(\n (attempt) => Date.now() - attempt.timestamp < 10000, // 10秒内\n );\n\n if (recentAttempts.length > 50) {\n return true;\n }\n\n // 检查异常 User-Agent\n const userAgent = request.headers['user-agent'];\n if (!userAgent || this.isSuspiciousUserAgent(userAgent)) {\n return true;\n }\n\n // 检查恶意路径\n if (this.containsMaliciousPatterns(request.url)) {\n return true;\n }\n\n return false;\n }\n\n /**\n * 处理可疑活动\n */\n private handleSuspiciousActivity(ip: string, request: any): void {\n if (!this.suspiciousActivities.has(ip)) {\n this.suspiciousActivities.set(ip, []);\n }\n\n const activities = this.suspiciousActivities.get(ip)!;\n activities.push({\n timestamp: Date.now(),\n type: 'suspicious_request',\n details: {\n method: request.method,\n url: request.url,\n userAgent: request.headers['user-agent'],\n },\n });\n\n // 如果可疑活动过多,阻止该 IP\n if (activities.length > 10) {\n this.blockedIps.add(ip);\n this.logger.warn(\n `IP ${ip} has been blocked due to excessive suspicious activities`,\n );\n }\n }\n\n /**\n * 检查可疑 User-Agent\n */\n private isSuspiciousUserAgent(userAgent: string): boolean {\n const suspiciousPatterns = [\n /bot/i,\n /crawler/i,\n /spider/i,\n /scanner/i,\n /sqlmap/i,\n /nikto/i,\n ];\n\n return suspiciousPatterns.some((pattern) => pattern.test(userAgent));\n }\n\n /**\n * 检查恶意路径模式\n */\n private containsMaliciousPatterns(url: string): boolean {\n const maliciousPatterns = [\n /\\.\\./, // 路径遍历\n /\\/etc\\/passwd/,\n /\\/proc\\/self/,\n /