Skip to content

Commit 1980cf1

Browse files
gxklclaude
andauthored
feat(skills): add EventBus and AOP skill content (#5835)
## Summary - Fix technical inaccuracies and naming issues in existing skill docs based on review feedback - Add EventBus skill content to egg-core (reference doc + SKILL.md decision tree + entry routing) - Add AOP skill content to egg-core (reference doc covering Advice/Pointcut/Crosscut/order + SKILL.md decision tree + entry routing) - Restructure egg-core SKILL.md with clear sections: "代码组织与依赖注入" and "异步任务" and "AOP 切面编程" - Add 17 eval cases (EventBus 7 + AOP 8 + routing 2) with iteration-5 results ## Test plan - [x] EventBus evals: with-skill 26/26 (100%) vs site-docs 19/26 (73%) - [x] AOP evals: with-skill 23/23 (100%) vs site-docs 19/23 (83%) - [x] Total: with-skill 49/49 (100%) vs site-docs 38/49 (78%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added comprehensive guides for EventBus (event-driven patterns), AOP (advice/pointcut/crosscut), and BackgroundTask behavior; improved Ajv/TypeBox parameter-validation guidance, examples, and best practices; reorganized skill docs and examples to reflect updated naming and paths. * **New Features** * Added new evaluation and routing entries covering EventBus, AOP, background-task vs EventBus decisions, and parameter-validation scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4417c8f commit 1980cf1

10 files changed

Lines changed: 624 additions & 72 deletions

File tree

packages/skills/CLAUDE.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
`packages/skills/` 目录包含 AI agent skills — 纯 markdown 文档,指导 AI 助手使用 Egg 框架。以 `@eggjs/skills` npm 包发布,仅含 `.md` 文件。
44

5-
> **Skill 编写基础知识**:SKILL.md 格式、frontmatter 规范、目录结构、progressive disclosure、写作风格等通用知识请使用 `/ant-skill-creator` skill 获取指导。以下仅记录 Egg 项目特有的约定。
5+
> **Skill 编写基础知识**:SKILL.md 格式、frontmatter 规范、目录结构、progressive disclosure、写作风格等通用知识请使用 `/skill-creator` skill 获取指导。以下仅记录 Egg 项目特有的约定。
66
77
## Egg Skills 架构
88

99
Skills 采用分层路由模式:
1010

1111
- **入口 skill** (`egg/`) — 分析用户意图,通过关键词匹配和决策逻辑路由到专业 skill
1212
- **专业 skills** — 提供特定领域的深度指导:
13-
- `egg-core/` — 核心概念:模块、依赖注入、生命周期、AccessLevel
14-
- `controller/` — 实现指导:HTTPController、MCPController、Schedule
13+
- `egg-core/` — 核心概念:模块、依赖注入、生命周期、AccessLevel、后台任务
14+
- `egg-controller/` — 实现指导:HTTPController、MCPController、Schedule、Ajv 校验
1515

1616
## Egg Skill Frontmatter 约定
1717

@@ -25,7 +25,7 @@ Skills 采用分层路由模式:
2525

2626
**入口 Skill(如 `egg/`)编写要点:**
2727

28-
对应 ant-skill-creator 的 **Workflow-Based** 模式。
28+
对应 /skill-creator 的 **Workflow-Based** 模式。
2929

3030
1. 决策框架包含明确步骤:识别意图 → 检查模糊意图 → 协议/用例特定指示
3131
2. 为每个专业 skill 列出中英文触发关键词
@@ -36,10 +36,10 @@ Skills 采用分层路由模式:
3636

3737
**专业 Skill 两种组织模式:**
3838

39-
| 模式 | ant-skill-creator 对应 | 适用场景 | SKILL.md 内容 | references/ 用途 |
40-
| ------------------------------ | ---------------------- | ------------------ | ----------------------- | ------------------ |
41-
| **概念型**(如 `egg-core/`| Reference-Based | 概念解释、架构理解 | 自包含的深度内容 | 更深入的专题文档 |
42-
| **索引型**(如 `controller/`| Workflow-Based | 多种实现方式的选择 | 精简的决策树 + 快速参考 | 每种实现的详细指南 |
39+
| 模式 | /skill-creator 对应 | 适用场景 | SKILL.md 内容 | references/ 用途 |
40+
| ---------------------------------- | ------------------- | ------------------ | ----------------------- | ------------------ |
41+
| **概念型**(如 `egg-core/` | Reference-Based | 概念解释、架构理解 | 自包含的深度内容 | 更深入的专题文档 |
42+
| **索引型**(如 `egg-controller/`| Workflow-Based | 多种实现方式的选择 | 精简的决策树 + 快速参考 | 每种实现的详细指南 |
4343

4444
**概念型 Skill 内容结构:**
4545

@@ -92,11 +92,11 @@ Skill 的价值 = 文档 + 实践经验 - 重复内容。如果内容和 `site/d
9292
## 添加新 Skill
9393

9494
1.`packages/skills/` 下创建目录:`packages/skills/<skill-name>/`
95-
2. 创建 `SKILL.md`(格式规范参考 `/ant-skill-creator`,frontmatter 遵循上述 Egg 约定)
95+
2. 创建 `SKILL.md`(格式规范参考 `/skill-creator`,frontmatter 遵循上述 Egg 约定)
9696
3. 创建 `references/` 目录(初始为空时放置 `.gitkeep`
9797
4. 按需在 `references/*.md` 中添加详细参考文档
9898
5. 更新入口 skill(`egg/SKILL.md`)的路由逻辑以包含新 skill
99-
6. 如果 skill 涉及 controller 类型,同时更新 `controller/SKILL.md` 决策树
99+
6. 如果 skill 涉及 controller 类型,同时更新 `egg-controller/SKILL.md` 决策树
100100

101101
## 添加新 Reference 文档
102102

@@ -112,7 +112,7 @@ Skill 的价值 = 文档 + 实践经验 - 重复内容。如果内容和 `site/d
112112

113113
**评测文件结构:**
114114

115-
```
115+
```text
116116
packages/skills/eval/
117117
├── evals-egg-core.json # egg-core skill 评测用例
118118
├── evals-egg-controller.json # egg-controller skill 评测用例
@@ -169,7 +169,7 @@ packages/skills/eval/
169169

170170
with-skill 环境:
171171

172-
```
172+
```text
173173
你是 EGG 框架开发专家。你只能通过 Read 工具读取 packages/skills/ 目录下的文件,不能访问 site/docs/ 或项目源码。
174174
175175
{egg/SKILL.md 的完整内容}
@@ -180,7 +180,7 @@ with-skill 环境:
180180

181181
site-docs 环境:
182182

183-
```
183+
```text
184184
你是 EGG 框架开发专家。你只能通过 Read 工具读取 site/docs/ 目录下的文件,不能访问 packages/skills/ 或项目源码。项目文档目录如下:
185185
186186
{完整的 site/docs/ 文件列表,通过 find site/docs -name '*.md' | sort 生成}

packages/skills/egg-controller/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: egg-controller
3-
description: Use when creating API endpoints, implementing protocol handlers, or exposing interfaces for specific clients. Covers HTTP, MCP and Schedule controllers for EGG framework applications.
3+
description: Use when creating API endpoints, implementing protocol handlers, exposing interfaces for specific clients, or adding parameter validation. Covers HTTP, MCP and Schedule controllers, and Ajv/TypeBox parameter validation for EGG framework applications.
44
allowed-tools: Read
55
---
66

packages/skills/egg-controller/references/ajv-validate.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { Ajv, Type, Static, TransformEnum } from 'egg/ajv';
3131
### 完整示例
3232

3333
```typescript
34-
// app/modules/demo/FooController.ts
34+
// app/userModule/UserController.ts
3535
import {
3636
HTTPController,
3737
HTTPMethod,
@@ -66,7 +66,7 @@ export class UserController {
6666
path: '/api/users',
6767
})
6868
async create(@HTTPBody() body: CreateUserParams) {
69-
// 校验失败自动抛出 AjvInvalidParamError(422)
69+
// 校验失败自动抛出 AjvInvalidParamError
7070
this.ajv.validate(CreateUserSchema, body);
7171

7272
// 校验通过,body 已经有完整类型提示
@@ -142,5 +142,5 @@ Type.String({
142142

143143
- **Schema 与 Controller 同文件** — Schema 定义放在使用它的 Controller 文件中,保持就近原则
144144
- **校验在 Controller 层** — 不要在 Service 层做入参校验,Service 信任上层传入的数据
145-
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致 422
145+
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致校验失败
146146
- **善用 transform** — 对用户输入做 trim 预处理,减少脏数据

packages/skills/egg-core/SKILL.md

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
---
22
name: egg-core
3-
description: 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器和动态注入。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理和运行时多实现动态选择
3+
description: 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器、动态注入、BackgroundTaskHelper 后台任务、EventBus 事件总线和 AOP 切面编程。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理、运行时多实现动态选择、请求返回后的异步任务处理、事件驱动架构和横切关注点
44
allowed-tools: Read
55
---
66

77
# egg 核心概念
88

9-
## Step 1: 代码写在 module 中
9+
## 代码组织与依赖注入
1010

11-
### 什么是模块?
11+
### Step 1: 代码写在 module 中
12+
13+
#### 什么是模块?
1214

1315
模块是 EGG 中基础的代码组织单元。只有模块内的代码会被框架扫描和加载。模块之间相互独立,但可以通过 `@Inject` 装饰器访问其他模块的对象。
1416

15-
### 定义 module
17+
#### 定义 module
1618

1719
在目录中添加包含 `eggModule.name` 字段的 `package.json` 文件来声明该目录为模块:
1820

@@ -97,9 +99,9 @@ import { SingletonProto } from '@eggjs/tegg';
9799

98100
---
99101

100-
## Step 2: 用 Proto 实现 Service
102+
### Step 2: 用 Proto 实现 Service
101103

102-
### SingletonProto
104+
#### SingletonProto
103105

104106
应用启动时立即创建,整个应用生命周期内只有一个实例,性能更好,应该作为默认选择。
105107

@@ -114,7 +116,7 @@ export class HelloService {
114116
}
115117
```
116118

117-
### ContextProto
119+
#### ContextProto
118120

119121
请求到达时按需创建,每个请求一个实例,请求结束自动销毁。仅在需要隔离不同请求的上下文信息时使用。
120122

@@ -129,7 +131,7 @@ export class RequestContext {
129131

130132
**重要提示**:大多数服务应该使用 `SingletonProto` 以获得更好的性能。只有当请求上下文必须在服务之间共享以确保请求之间隔离时,才使用 `ContextProto`
131133

132-
### AccessLevel
134+
#### AccessLevel
133135

134136
proto 对象默认 accessLevel 为 `AccessLevel.PRIVATE`,仅在当前 module 内使用。可以设置为 `AccessLevel.PUBLIC`,进行跨模块访问。
135137

@@ -143,9 +145,9 @@ export class SharedService {}
143145
export class SharedContextService {}
144146
```
145147

146-
## Step 3: 通过 Inject 使用 Service
148+
### Step 3: 通过 Inject 使用 Service
147149

148-
### 基本用法
150+
#### 基本用法
149151

150152
使用 `@Inject()` 注入其他 Proto 或 Egg 对象:
151153

@@ -167,43 +169,62 @@ export class HelloService {
167169
}
168170
```
169171

170-
### 动态注入
172+
#### 动态注入
171173

172174
当同一个抽象有多种实现,需要在运行时动态选择时,通过 `EggObjectFactory` 按类型获取实现,无需 if/else。详见 `references/dynamic-inject.md`
173175

174-
### 重要约束
176+
#### 重要约束
175177

176178
- **不能有循环依赖**:Proto 或模块之间都不能有循环依赖
177179
- **不能有同名对象**:一个模块不能有相同名称和初始化类型的 Proto
178180
- **按需注入**:不要直接注入 `app``ctx`,按需注入特定对象
179181

180-
## 快速决策指南
182+
### 快速决策指南
183+
184+
| 场景 | 使用方式 |
185+
| -------------------------------- | ------------------------------------------------------ |
186+
| 无状态服务 | `@SingletonProto()` |
187+
| 跨服务共享的请求级状态 | `@ContextProto()` |
188+
| 需要跨模块访问 | `@SingletonProto({ accessLevel: AccessLevel.PUBLIC })` |
189+
| 注入依赖 | `@Inject()` |
190+
| 使用自定义名称注入 | `@Inject({ name: 'customName' })` |
191+
| 同一抽象多种实现,运行时动态选择 | `QualifierImplDecoratorUtil` + `EggObjectFactory` |
181192

182-
| 场景 | 使用装饰器 |
183-
| -------------------------------- | ------------------------------------------------------------------ |
184-
| 无状态服务 | `@SingletonProto()` |
185-
| 跨服务共享的请求级状态 | `@ContextProto()` |
186-
| 需要跨模块访问 | `@SingletonProto({ accessLevel: AccessLevel.PUBLIC })` |
187-
| 注入依赖 | `@Inject()` |
188-
| 使用自定义名称注入 | `@Inject({ name: 'customName' })` |
189-
| 同一抽象多种实现,运行时动态选择 | `QualifierImplDecoratorUtil` + `EggObjectFactory` |
190-
| 请求返回后执行异步任务 | `BackgroundTaskHelper.run()`,详见 `references/background-task.md` |
193+
## 异步任务
191194

192-
### 异步任务选型
195+
| 特性 | BackgroundTaskHelper | EventBus |
196+
| ---------- | ----------------------------- | ----------------------------------------- |
197+
| **耦合** | 高 — 异步逻辑写在触发者代码中 | 低 — handler 独立,新增处理者不修改触发者 |
198+
| **上下文** | 共享触发者的请求上下文 | handler 运行在独立的新上下文中 |
199+
| **扩展** | 需要修改触发者代码 | 新增 `@Event` handler 类即可 |
193200

194201
```
195202
需要在请求之外执行任务?
196203
197204
├─ 请求返回后执行,依赖当前请求上下文
198205
│ └─ → BackgroundTaskHelper(references/background-task.md)
199206
200-
├─ 请求返回后执行,不依赖当前请求上下文
201-
│ └─ → EventBus
207+
├─ 请求返回后执行,不依赖当前请求上下文,需要解耦
208+
│ └─ → EventBus(references/eventbus.md)
202209
203210
└─ 定时或周期执行
204211
└─ → Schedule(参考 egg-controller skill)
205212
```
206213

214+
## AOP 切面编程
215+
216+
AOP 用于将日志、鉴权、缓存、事务等横切关注点从业务代码中分离。AOP 装饰器从 `egg/aop` 导入(不是 `egg`)。
217+
218+
```
219+
需要在方法执行前后添加通用逻辑?
220+
221+
├─ 针对特定方法 → @Pointcut(在目标方法上声明)
222+
223+
└─ 批量切入多个类/方法 → @Crosscut(在 Advice 类上声明匹配规则)
224+
```
225+
226+
详细用法(Advice 生命周期、AdviceContext、Pointcut/Crosscut 选型、参数透传、执行顺序)请参阅 `references/aop.md`
227+
207228
## 常见问题排查
208229

209230
| 现象 | 原因 | 解决方案 |
@@ -221,3 +242,5 @@ export class HelloService {
221242
- SingletonProto 和 ContextProto 详情,请参阅:`references/proto.md`
222243
- 动态注入(Qualifier 动态注入),请参阅:`references/dynamic-inject.md`
223244
- 请求后异步任务(BackgroundTaskHelper),请参阅:`references/background-task.md`
245+
- 事件总线(EventBus),请参阅:`references/eventbus.md`
246+
- AOP 切面编程(Advice、Pointcut、Crosscut),请参阅:`references/aop.md`

0 commit comments

Comments
 (0)