# CLAUDE.md - GPU Guard 后端

## 项目概述

GPU Guard 后端 - 基于 Midway.js + Cool Admin 框架的 GPU 智能监控平台后端。

**技术栈**: Midway.js 3.20 + TypeScript 5.9 + TypeORM + Cool Admin 8.x + MySQL 8+
**端口**: 8003
**包管理器**: pnpm (必须)

## 重要规定

1. **所有回答用中文**
2. **需要操作数据库时使用 MCP 工具**
3. **遵循 Cool Admin 框架约定**（见下方）

## 常用命令

```bash
pnpm i                    # 安装依赖
pnpm dev                  # 启动开发服务器 (端口 8003)
npm run build             # 构建
npm run start             # 生产启动
```

## 数据库配置

| 环境 | 配置文件 | 数据库 |
|-----|---------|-------|
| 开发 | `src/config/config.local.ts` | MySQL cpu_guard |
| 生产 | `src/config/config.prod.ts` | MySQL cpu_guard |

**重要**: 生产环境不要开启 `synchronize: true`

## Cool Admin 后端开发规范

### 新增模块标准流程

```
src/modules/{模块名}/
├── config.ts              # 模块配置
├── entity/
│   └── {实体名}.ts        # TypeORM Entity
├── service/
│   └── {实体名}.ts        # 业务逻辑 Service
└── controller/admin/
    └── {实体名}.ts        # Admin API Controller
```

### 创建 Entity

```typescript
import { BaseEntity } from '../../base/entity/base.js';
import { Column, Entity, Index } from 'typeorm';

@Entity('project_info')  // 表名
export class ProjectInfoEntity extends BaseEntity {
  // BaseEntity 已提供: id, createTime, updateTime, tenantId

  @Column({ comment: '名称' })
  name: string;

  @Column({ comment: '状态', default: 0 })
  status: number;

  @Column({ comment: '日期', type: 'date', nullable: true })
  startDate: string;

  @Column({ comment: 'JSON配置', type: 'json', nullable: true })
  config: any;
}
```

**注册 Entity:** 在 `src/entities.ts` 中添加 import 和数组项。

### 创建 Controller

```typescript
import { Provide } from '@midwayjs/core';
import { CoolController, BaseController } from '@cool-midway/core';
import { ProjectInfoEntity } from '../../entity/info';
import { ProjectInfoService } from '../../service/info';

@Provide()
@CoolController({
  api: ['add', 'delete', 'update', 'info', 'list', 'page'],
  entity: ProjectInfoEntity,
  service: ProjectInfoService,
  pageQueryOp: {
    keyWordLikeFields: ['name'],
    fieldEq: ['status'],
    addOrderBy: { createTime: 'DESC' },
  },
})
export class AdminProjectInfoController extends BaseController {
  // 自定义接口
  @Get('/custom', { summary: '自定义接口' })
  async custom(@Query('id') id: number) {
    return this.ok(await this.service.customMethod(id));
  }
}
```

**api 数组可选值:** `add`, `delete`, `update`, `info`, `list`, `page`
**pageQueryOp 配置:**
- `keyWordLikeFields`: 支持 keyWord 模糊搜索的字段
- `fieldEq`: 支持精确匹配的字段（前端传同名参数即可过滤）
- `addOrderBy`: 默认排序

### 创建 Service

```typescript
import { Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { ProjectInfoEntity } from '../entity/info';

@Provide()
export class ProjectInfoService extends BaseService {
  @InjectEntityModel(ProjectInfoEntity)
  projectInfoEntity: Repository<ProjectInfoEntity>;

  async customMethod(id: number) {
    return this.projectInfoEntity.findOneBy({ id });
  }
}
```

## 模块清单

| 模块 | Entity 数量 | 关键表 |
|------|------------|--------|
| **base** | 11 | base_sys_user, base_sys_role, base_sys_menu, base_sys_department, base_sys_param |
| **netaclaw** | 5 | netaclaw_agent, netaclaw_session, netaclaw_message, netaclaw_skill, netaclaw_model_channel |
| **user** | 3 | user_info, user_wx, user_address |
| **task** | 2 | task_info, task_log |
| **space** | 2 | space_info, space_type |
| **dict** | 2 | dict_type, dict_info |
| **notification** | 2 | notification_message_log, notification_user |
| **plugin** | 1 | plugin_info |
| **recycle** | 1 | recycle_data |
| **demo** | 1 | demo_goods |

## NetaClaw AI 引擎

位于 `src/modules/netaclaw/`，核心组件：

| 组件 | 路径 | 用途 |
|------|------|------|
| Agent 运行时 | `runtime/agent.ts` | ReAct 循环 (Think→Act→Observe) |
| 模型选择 | `runtime/model_selection.ts` | provider:model 解析 |
| WebSocket 网关 | `gateway/session.ts` | Socket.IO 实时通信 |
| LLM 提供商 | `plugins/llm_providers/` | OpenAI/Anthropic/DeepSeek 适配 |
| 工具系统 | `plugins/tools/` | TypeBox Schema 工具定义 |
| 模型渠道 | `service/model_channel.ts` | 渠道凭证管理与解析 |

## 开发规范

- **文件名**: 下划线法 (`model_channel.ts`)
- **Entity 字段**: 驼峰法 (`modelConfig`)
- **注释**: 中文
- **Entity**: 继承 BaseEntity，不使用外键
- **Controller**: @CoolController 自动生成 CRUD
- **响应格式**: 成功用 `this.ok(data)`，失败用 `this.fail('message')`
