# CLAUDE.md

本文件为 Claude Code 在此代码仓库中工作时提供指导。

## 重要规定

**所有回复必须使用中文。**

**架构边界规则:** 实现功能前必须遵循 `.claude/rules/architecture-boundaries.md`。

**需要操作数据库时使用 MCP 工具。**

## 项目概述

Neta AI电商 是 AI 驱动的电商自动化运营平台，采用 Monorepo 架构。后端基于 Midway.js + Cool Admin 框架，前端基于 Vue 3 + Element Plus，AI 引擎采用自研 NetaClaw（ReAct 循环 + WebSocket 实时通信）。

**核心架构:**
- **Monorepo**: pnpm workspace 管理多个包
- **后端**: Midway.js 3.20 + Cool Admin 8.x，端口 8003
- **前端**: Vue 3.5 + Vite 5.4 + Element Plus 2.9，端口 9001
- **AI 引擎**: NetaClaw (ReAct + TypeBox Schema + Socket.IO)
- **数据库**: MySQL 8.0+ (`neta_test`)

## 项目结构

```
Neta-monorepo/
├── packages/
│   ├── backend/          # Midway.js 后端 (Cool Admin 框架)
│   ├── frontend/         # Vue 3 前端 (Cool Admin UI)
│   └── shared/           # 共享 TypeScript 类型
├── docs/superpowers/     # 设计文档与实施计划
└── package.json
```

## 常用命令

```bash
pnpm install                          # 安装依赖
pnpm dev                              # 同时启动后端+前端
pnpm --filter @neta/backend dev       # 单独启动后端 (8003)
pnpm --filter @neta/frontend dev      # 单独启动前端 (9001)
pnpm build                            # 构建所有包
pnpm lint                             # 代码检查
```

## Cool Admin 框架规范

本项目基于 Cool Admin 开源框架二次开发，**必须遵循以下约定**。

### 后端 CRUD 模式 (@CoolController)

`@CoolController` 装饰器自动生成标准 CRUD 接口：

```typescript
@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 {}
```

**自动生成的接口:**
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/admin/{module}/{entity}/add` | 新增 |
| POST | `/admin/{module}/{entity}/delete` | 删除 (body: {ids: [1,2]}) |
| POST | `/admin/{module}/{entity}/update` | 更新 |
| GET | `/admin/{module}/{entity}/info` | 详情 (query: id) |
| POST | `/admin/{module}/{entity}/list` | 列表 |
| POST | `/admin/{module}/{entity}/page` | 分页 (body: {page, size, keyWord, ...}) |

**自定义接口:** 在 Controller 类中用 `@Get`/`@Post` 装饰器添加：
```typescript
@Get('/ganttData', { summary: '甘特图数据' })
async ganttData(@Query('projectId') projectId: number) {
  return this.ok(await this.service.ganttData(projectId));
}
```
<!-- PLACEHOLDER_CLAUDE_CONTINUE -->

### BaseEntity 提供的字段

所有 Entity 继承 `BaseEntity`（来自 `../../base/entity/base.ts`），自动拥有：
- `id`: 自增主键
- `createTime`: 创建时间（自动填充）
- `updateTime`: 更新时间（自动更新）
- `tenantId`: 租户ID（多租户支持，nullable）

**创建 Entity 示例:**
```typescript
import { BaseEntity } from '../../base/entity/base.js';
import { Column, Entity } from 'typeorm';

@Entity('project_info')
export class ProjectInfoEntity extends BaseEntity {
  @Column({ comment: '项目名称' })
  name: string;

  @Column({ comment: '状态 0未开始 1进行中 2已完成', default: 0 })
  status: number;

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

### 前端 Service 代理

Cool Admin 根据后端 Controller 文件名自动生成 service 代理对象：

```typescript
const { service } = useCool();

// Controller 文件: modules/project/controller/admin/info.ts
// → service.project.info.page({...})
// → service.project.info.add({...})
// → service.project.info.update({...})
// → service.project.info.delete({ ids: [1] })
// → service.project.info.info({ id: 1 })

// Controller 文件: modules/project/controller/admin/task.ts
// → service.project.task.page({...})

// 自定义接口需要用 request:
// service.request({ url: '/admin/project/task/ganttData', params: { projectId: 1 } })
```

**重要:** service 路径由文件名决定，下划线文件名如 `time_log.ts` 对应 `service.project.time_log`（不是 timeLog）。

### 前端模块配置 (ModuleConfig)

每个前端模块必须有 `config.ts`：

```typescript
export default (): ModuleConfig => {
  return {
    name: 'project',
    label: '项目管理',
    order: 50,
    views: [
      {
        path: '/project/list',
        meta: { label: '项目列表' },
        component: () => import('./views/list.vue')
      },
    ]
  };
};
```
## 菜单与权限系统

### 菜单配置 (base_sys_menu 表)

菜单通过数据库 `base_sys_menu` 表配置，**不在前端硬编码**。

| 字段 | 说明 |
|------|------|
| `parentId` | 父菜单ID（顶级为 null） |
| `name` | 菜单名称 |
| `router` | 路由路径（如 `/project/list`） |
| `viewPath` | Vue 组件路径（如 `modules/project/views/list.vue`） |
| `icon` | 图标 |
| `orderNum` | 排序号 |
| `type` | 0=目录, 1=菜单页面, 2=按钮权限 |
| `isShow` | 是否在侧边栏显示 |
| `keepAlive` | 是否缓存页面 |
| `perms` | 权限标识（按钮级，如 `project:info:add`） |

**新增菜单标准流程:**
```sql
-- 1. 新增目录
INSERT INTO base_sys_menu (parentId, name, icon, orderNum, type, isShow, createTime, updateTime)
VALUES (null, '项目管理', 'icon-project', 3, 0, 1, NOW(), NOW());
-- 记录返回的 id，假设为 158

-- 2. 新增菜单页面
INSERT INTO base_sys_menu (parentId, name, router, viewPath, orderNum, type, isShow, createTime, updateTime)
VALUES (158, '项目列表', '/project/list', 'modules/project/views/list.vue', 1, 1, 1, NOW(), NOW());

-- 3. 隐藏页面（详情页等）
INSERT INTO base_sys_menu (parentId, name, router, viewPath, orderNum, type, isShow, createTime, updateTime)
VALUES (158, '项目详情', '/project/detail', 'modules/project/views/detail.vue', 2, 1, 0, NOW(), NOW());
```

### 权限机制

- **admin 用户** 自动拥有所有权限，无需配置 role_menu 映射
- 普通用户通过 `base_sys_role_menu` 关联角色和菜单
- 权限中间件: JWT Token → 解析 userId → 查询权限列表 → 匹配请求 URL
- `/admin/*/comm/` 路径对所有登录用户开放

## 后端模块

| 模块 | 路径 | 用途 | 关键 Entity |
|------|------|------|------------|
| **base** | `modules/base/` | 用户、角色、菜单、权限 | BaseSysUser, BaseSysRole, BaseSysMenu |
| **netaclaw** | `modules/netaclaw/` | AI Agent 引擎 | NetaClawAgent, NetaClawSession, NetaClawMessage, NetaClawSkill, NetaClawModelChannel |
| **project** | `modules/project/` | 项目管理 | ProjectInfo, ProjectPhase, ProjectTask, ProjectTaskDependency, ProjectTimeLog |
| **data** | `modules/data/` | 药品目录数据 | DataDrugItem, DataCatalog, DataMedicalItem |
| **dict** | `modules/dict/` | 字典管理 | DictType, DictInfo |
| **task** | `modules/task/` | 定时任务 | TaskInfo, TaskLog |
| **space** | `modules/space/` | 文件空间 | SpaceInfo, SpaceType |
| **user** | `modules/user/` | 应用用户 | UserInfo, UserWx |
| **notification** | `modules/notification/` | 通知服务 | NotificationMessageLog |
| **plugin** | `modules/plugin/` | 插件系统 | PluginInfo |
| **recycle** | `modules/recycle/` | 回收站 | RecycleData |
| **demo** | `modules/demo/` | 演示 | DemoGoods |
| **swagger** | `modules/swagger/` | API 文档 | - |

## 前端模块

| 模块 | 路由前缀 | 用途 |
|------|---------|------|
| **base** | `/` | 登录(Canvas星河动画)、用户、角色、菜单、部门 |
| **agent** | `/agent/*` | Agent 对话(WebSocket)、Skill 管理、模型渠道管理 |
| **project** | `/project/*` | 项目管理(甘特图/日历/看板/列表) |
| **data** | `/data/*` | 药品目录数据管理 |
| **dict** | `/dict/*` | 字典管理 |
| **task** | `/task/*` | 定时任务 |
| **space** | `/space/*` | 文件空间 |
| **user** | `/user/*` | 应用用户 |

## 开发规范

- **后端文件名**: 下划线法 (`model_channel.ts`)
- **Entity 字段**: 驼峰法 (`modelConfig`)
- **注释**: 中文
- **Entity**: 继承 BaseEntity，不使用外键
- **Controller**: 使用 `@CoolController` 自动生成 CRUD
- **包管理器**: 必须使用 pnpm
- **数据库**: 开发环境 `synchronize: true` 自动建表，生产环境禁止

## 环境变量

```env
NODE_ENV=development
BACKEND_PORT=8003
DB_HOST=120.48.5.80
DB_PORT=3306
DB_DATABASE=neta_test
```
