@ranger1/dx 0.1.104 → 0.1.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/codex-initial.js +79 -5
- package/package.json +1 -1
- package/skills/backend-audit-fixer/SKILL.md +98 -0
- package/skills/backend-audit-fixer/references/backend-layering.md +103 -0
- package/skills/backend-audit-fixer/references/e2e.md +60 -0
- package/skills/backend-audit-fixer/references/env-accessor.md +73 -0
- package/skills/backend-audit-fixer/references/error-handling.md +77 -0
- package/skills/{naming-audit-fixer/references/fix-guide.md → backend-audit-fixer/references/naming-fix-guide.md} +8 -3
- package/skills/backend-audit-fixer/references/naming.md +139 -0
- package/skills/backend-audit-fixer/references/pagination-dto.md +52 -0
- package/skills/create-issue/SKILL.md +90 -0
- package/skills/feature-decide-plan-execute/SKILL.md +537 -0
- package/skills/issues-batch-deliver/SKILL.md +549 -0
- package/skills/pr-train-ship/SKILL.md +669 -0
- package/skills/backend-layering-audit-fixer/SKILL.md +0 -180
- package/skills/e2e-audit-fixer/SKILL.md +0 -76
- package/skills/e2e-audit-fixer/agents/openai.yaml +0 -4
- package/skills/env-accessor-audit-fixer/SKILL.md +0 -149
- package/skills/env-accessor-audit-fixer/agents/openai.yaml +0 -7
- package/skills/error-handling-audit-fixer/SKILL.md +0 -187
- package/skills/error-handling-audit-fixer/agents/openai.yaml +0 -7
- package/skills/git-pr-ship/SKILL.md +0 -528
- package/skills/multi-pr-feature-delivery/SKILL.md +0 -493
- package/skills/multi-pr-feature-delivery/agents/openai.yaml +0 -7
- package/skills/naming-audit-fixer/SKILL.md +0 -149
- package/skills/pagination-dto-audit-fixer/SKILL.md +0 -69
- package/skills/pagination-dto-audit-fixer/agents/openai.yaml +0 -7
- /package/skills/{env-accessor-audit-fixer → backend-audit-fixer}/references/bootstrap-env-foundation.md +0 -0
- /package/skills/{error-handling-audit-fixer/references/foundation-bootstrap.md → backend-audit-fixer/references/error-handling-foundation-bootstrap.md} +0 -0
- /package/skills/{error-handling-audit-fixer → backend-audit-fixer}/references/error-handling-standard.md +0 -0
- /package/skills/{pagination-dto-audit-fixer → backend-audit-fixer}/references/pagination-standard.md +0 -0
- /package/skills/{e2e-audit-fixer/scripts/e2e_e2e_audit.py → backend-audit-fixer/scripts/e2e_audit.py} +0 -0
- /package/skills/{env-accessor-audit-fixer → backend-audit-fixer}/scripts/env_accessor_audit.py +0 -0
- /package/skills/{error-handling-audit-fixer → backend-audit-fixer}/scripts/error_handling_audit.py +0 -0
- /package/skills/{naming-audit-fixer/scripts/audit_naming.py → backend-audit-fixer/scripts/naming_audit.py} +0 -0
- /package/skills/{pagination-dto-audit-fixer → backend-audit-fixer}/scripts/pagination_dto_audit.py +0 -0
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: backend-layering-audit-fixer
|
|
3
|
-
description: Use when backend、NestJS 分层架构或事务规范审查中,需要检查 Service 是否绕过 Repository 直接访问数据库、Controller 是否跨层注入 Repository、Service 是否伪装 Repository、事务装饰器是否匹配 afterCommit 使用、非 HTTP 场景事务模式是否正确、SSE 端点是否误加事务装饰器、以及是否存在直接 prisma.$transaction() 调用。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 后端三层架构与事务规范合规检查
|
|
7
|
-
|
|
8
|
-
## 概览
|
|
9
|
-
|
|
10
|
-
扫描后端代码是否遵守 **Controller → Service → Repository** 三层架构约束及事务规范。默认只输出审计结果和修复建议;用户明确要求时才自动修复。
|
|
11
|
-
|
|
12
|
-
规则来源:`ruler/conventions.md` 第 4 节 "NestJS/Prisma 约定" + 第 5 节 "事务规范"。
|
|
13
|
-
|
|
14
|
-
## 检查项
|
|
15
|
-
|
|
16
|
-
### 分层架构
|
|
17
|
-
|
|
18
|
-
| 编号 | 违规类型 | 说明 |
|
|
19
|
-
|------|----------|------|
|
|
20
|
-
| L1 | Service 直接访问数据库 | Service 注入 `PrismaService` 并调用 `this.prisma.*` |
|
|
21
|
-
| L2 | Service 伪装为 Repository | Service 文件含 `getClient()` / `txHost.tx` 模式,实质是 Repository |
|
|
22
|
-
| L3 | Service 死依赖 | Service 注入 `PrismaService` 但从未使用 |
|
|
23
|
-
| L4 | Controller 跨层调用 | Controller 直接注入 Repository |
|
|
24
|
-
|
|
25
|
-
### 事务规范
|
|
26
|
-
|
|
27
|
-
| 编号 | 违规类型 | 说明 |
|
|
28
|
-
|------|----------|------|
|
|
29
|
-
| T1 | afterCommit 未被排空 | Controller 用 `@Transactional()` 但调用链中存在 `txEvents.afterCommit()` 回调(应改用 `@TransactionalWithAfterCommit()`) |
|
|
30
|
-
| T2 | Service 违规传播类型 | Service 使用 `Propagation.Required` / `RequiresNew` / `Nested`(禁止 Service 自行创建事务) |
|
|
31
|
-
| T3 | 直接 `prisma.$transaction()` | 绕过 `TransactionHost` 抽象,直接调用 `prisma.$transaction()` |
|
|
32
|
-
| T4 | SSE/流式端点加事务装饰器 | `@Sse()` 或流式返回的方法上使用了 `@Transactional()` / `@TransactionalWithAfterCommit()`(会导致 afterCommit 提前排空) |
|
|
33
|
-
| T5 | 非 HTTP 场景事务模式错误 | Subscriber/Scheduler 使用了 `@Transactional()` 装饰器而非 `txHost.withTransaction()` 或 `txEvents.withAfterCommit()` |
|
|
34
|
-
| T6 | 非 HTTP 场景缺少 CLS 作用域 | Scheduler 调用 `txHost.withTransaction()` 前未用 `cls.run()` 创建 CLS 作用域 |
|
|
35
|
-
|
|
36
|
-
## 审计命令
|
|
37
|
-
|
|
38
|
-
**分层架构扫描(并行执行):**
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# L1 + L2 + L3:Service 注入 PrismaService
|
|
42
|
-
rg "PrismaService" apps/backend/src/modules --glob '*.service.ts' -l
|
|
43
|
-
|
|
44
|
-
# L2:Service 含 Repository 模式
|
|
45
|
-
rg "getClient|txHost\.tx" apps/backend/src/modules --glob '*.service.ts' -l
|
|
46
|
-
|
|
47
|
-
# L4:Controller 注入 Repository
|
|
48
|
-
rg "Repository" apps/backend/src/modules --glob '*.controller.ts' -l
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
**事务规范扫描(并行执行):**
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
# T1:找出所有只用 @Transactional() 的 Controller 方法(排除 @TransactionalWithAfterCommit)
|
|
55
|
-
rg "@Transactional\(\)" apps/backend/src/modules --glob '*.controller.ts' -l
|
|
56
|
-
|
|
57
|
-
# T2:Service 违规传播类型
|
|
58
|
-
rg "Propagation\.(Required|RequiresNew|Nested)" apps/backend/src/modules --glob '*.service.ts' -l
|
|
59
|
-
|
|
60
|
-
# T3:直接 prisma.$transaction()
|
|
61
|
-
rg "prisma\.\$transaction" apps/backend/src/modules -l
|
|
62
|
-
|
|
63
|
-
# T4:SSE 端点是否带事务装饰器(需人工确认上下文)
|
|
64
|
-
rg "@Sse\(\)" apps/backend/src/modules --glob '*.controller.ts' -l
|
|
65
|
-
|
|
66
|
-
# T5:Subscriber/Scheduler 误用 @Transactional 装饰器
|
|
67
|
-
rg "@Transactional" apps/backend/src/modules --glob '*.subscriber.ts' --glob '*.task.ts' --glob '*.scheduler*.ts' -l
|
|
68
|
-
|
|
69
|
-
# T6:Scheduler 使用 txHost.withTransaction 但未包 cls.run
|
|
70
|
-
rg "txHost\.withTransaction" apps/backend/src/modules --glob '*.scheduler*.ts' --glob '*.task.ts' -l
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## 执行流程
|
|
74
|
-
|
|
75
|
-
1. 执行上述审计命令,收集命中文件列表
|
|
76
|
-
2. **分层检查**:对每个命中文件,读取构造函数和使用处,判定违规类型:
|
|
77
|
-
- 注入了 `PrismaService` 且有 `this.prisma.*` 调用 → **L1**
|
|
78
|
-
- 注入了 `PrismaService`/`txHost` 且有 `getClient()` → **L2**
|
|
79
|
-
- 注入了 `PrismaService` 但无任何 `this.prisma.*` 调用 → **L3**
|
|
80
|
-
- Controller 文件 import/注入 Repository → **L4**
|
|
81
|
-
3. **事务检查**:
|
|
82
|
-
- T1:对只用 `@Transactional()` 的 Controller,追踪其调用的 Service 方法,检查是否存在 `txEvents.afterCommit()` 调用
|
|
83
|
-
- T2:直接匹配即违规
|
|
84
|
-
- T3:直接匹配即违规
|
|
85
|
-
- T4:对 `@Sse()` 方法,检查同一方法上是否有事务装饰器
|
|
86
|
-
- T5:直接匹配即违规(Subscriber/Scheduler 不应用装饰器声明事务)
|
|
87
|
-
- T6:对命中文件,检查 `txHost.withTransaction()` 调用是否在 `cls.run()` 回调内部
|
|
88
|
-
4. 输出审计报告(按模块分组,标注违规类型和行号)
|
|
89
|
-
5. 仅当用户明确要求修复时,才执行修复
|
|
90
|
-
|
|
91
|
-
## 修复策略
|
|
92
|
-
|
|
93
|
-
### 分层架构
|
|
94
|
-
|
|
95
|
-
**L1:Service 直接访问数据库**
|
|
96
|
-
- 将数据库查询逻辑提取到对应 Repository(新建或复用已有)
|
|
97
|
-
- Service 改为注入 Repository 调用
|
|
98
|
-
|
|
99
|
-
**L2:Service 伪装为 Repository**
|
|
100
|
-
- 重命名文件为 `*.repository.ts`,类名改为 `*Repository`
|
|
101
|
-
- 更新所有引用(import、Module providers、注入处)
|
|
102
|
-
- 确认 Service 层消费者改为注入新 Repository
|
|
103
|
-
|
|
104
|
-
**L3:Service 死依赖**
|
|
105
|
-
- 移除构造函数中 `PrismaService` 注入
|
|
106
|
-
- 移除对应 import 语句
|
|
107
|
-
- 运行 lint 确认无残留
|
|
108
|
-
|
|
109
|
-
**L4:Controller 跨层调用**
|
|
110
|
-
- Controller 中的 Repository 调用下沉到 Service
|
|
111
|
-
- Controller 改为调用 Service 方法
|
|
112
|
-
|
|
113
|
-
### 事务规范
|
|
114
|
-
|
|
115
|
-
**T1:afterCommit 未被排空**
|
|
116
|
-
- 将 Controller 方法的 `@Transactional()` 改为 `@TransactionalWithAfterCommit()`
|
|
117
|
-
- 或确认调用链中确实不存在 `afterCommit()` 回调(则无需修改)
|
|
118
|
-
|
|
119
|
-
**T2:Service 违规传播类型**
|
|
120
|
-
- 改为 `Propagation.Mandatory`(必须在事务中调用)或 `Propagation.Supports`(有事务则加入)
|
|
121
|
-
- 事务边界上移到 Controller 层
|
|
122
|
-
|
|
123
|
-
**T3:直接 `prisma.$transaction()`**
|
|
124
|
-
- 改用 `txHost.withTransaction()` 或由 Controller 层 `@Transactional()` 声明事务边界
|
|
125
|
-
- Repository 内通过 `txHost.tx` 自动参与事务
|
|
126
|
-
|
|
127
|
-
**T4:SSE/流式端点加事务装饰器**
|
|
128
|
-
- 移除事务装饰器
|
|
129
|
-
- 如需事务操作,在流式逻辑内部用 `cls.run()` + `txHost.withTransaction()` 局部处理
|
|
130
|
-
|
|
131
|
-
**T5:非 HTTP 场景误用 @Transactional 装饰器**
|
|
132
|
-
- Subscriber:改用 `txEvents.withAfterCommit()` 包裹处理逻辑
|
|
133
|
-
- Scheduler/Task:改用 `cls.run()` + `txHost.withTransaction()`
|
|
134
|
-
|
|
135
|
-
**T6:非 HTTP 场景缺少 CLS 作用域**
|
|
136
|
-
- 在 `txHost.withTransaction()` 外层包裹 `cls.run()`:
|
|
137
|
-
```typescript
|
|
138
|
-
await this.cls.run(async () => {
|
|
139
|
-
await this.txHost.withTransaction(async () => { /* ... */ })
|
|
140
|
-
})
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## 排除项
|
|
144
|
-
|
|
145
|
-
以下场景不视为违规:
|
|
146
|
-
- `*.repository.ts` 文件中使用 `PrismaService` / `getClient()` / `txHost`(Repository 正常职责)
|
|
147
|
-
- `prisma/` 目录下的基础设施文件(`prisma.service.ts` 等)
|
|
148
|
-
- `common/` 目录下的事务基础设施(`TransactionEventsService`、`AfterCommitInterceptor` 等)
|
|
149
|
-
- `*.spec.ts` / `e2e/` 测试文件
|
|
150
|
-
- Subscriber / Scheduler 中通过 `txHost.withTransaction()` 管理事务(正确模式,但其中数据库查询仍应走 Repository)
|
|
151
|
-
|
|
152
|
-
## 审计报告模板
|
|
153
|
-
|
|
154
|
-
```
|
|
155
|
-
## 后端分层架构与事务规范审计报告
|
|
156
|
-
|
|
157
|
-
### 违规汇总
|
|
158
|
-
|
|
159
|
-
**分层架构:**
|
|
160
|
-
- L1(Service 直接访问 DB):N 处
|
|
161
|
-
- L2(Service 伪装 Repository):N 处
|
|
162
|
-
- L3(Service 死依赖):N 处
|
|
163
|
-
- L4(Controller 跨层调用):N 处
|
|
164
|
-
|
|
165
|
-
**事务规范:**
|
|
166
|
-
- T1(afterCommit 未被排空):N 处
|
|
167
|
-
- T2(Service 违规传播类型):N 处
|
|
168
|
-
- T3(直接 prisma.$transaction):N 处
|
|
169
|
-
- T4(SSE 端点加事务装饰器):N 处
|
|
170
|
-
- T5(非 HTTP 场景误用装饰器):N 处
|
|
171
|
-
- T6(非 HTTP 缺少 CLS 作用域):N 处
|
|
172
|
-
|
|
173
|
-
### 详细列表
|
|
174
|
-
|
|
175
|
-
#### [模块名]
|
|
176
|
-
| 文件 | 违规类型 | 行号 | 说明 |
|
|
177
|
-
|------|----------|------|------|
|
|
178
|
-
| ... | L1 | 39 | `this.prisma.user.findMany()` |
|
|
179
|
-
| ... | T1 | 85 | `@Transactional()` 但调用链含 `afterCommit()` |
|
|
180
|
-
```
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: e2e-audit-fixer
|
|
3
|
-
description: 对 backend 的 E2E 用例进行中文名称、通用 fixture 重复实现与测试请求构建规范检查,并按可配置路径输出修复建议与可选自动修复。适用于需要审计或修复 E2E 测试中的中文用例名、手工请求构造、手工 JWT、以及本应复用通用测试基建的重复实现。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# E2E 测试可维护性检查与修复
|
|
7
|
-
|
|
8
|
-
## 触发场景
|
|
9
|
-
|
|
10
|
-
- 需要检查 `apps/backend/e2e/**/*.e2e-spec.ts` 的 E2E 用例是否符合英文命名规范。
|
|
11
|
-
- 需要识别直接操作 Prisma、手工 JWT、手工 API URL、手工请求实现,并区分哪些适合改用全局通用 fixture,哪些更适合抽成本地 helper。
|
|
12
|
-
- 需要一次性生成问题清单并按规则应用可控修复。
|
|
13
|
-
|
|
14
|
-
## 准备
|
|
15
|
-
|
|
16
|
-
执行前确认项目有可读权限,并准备以下路径参数(全部可覆盖,避免硬编码):
|
|
17
|
-
|
|
18
|
-
1. `--workspace`:代码根目录,默认当前目录。
|
|
19
|
-
2. `--e2e-glob`:扫描文件模式,默认 `apps/backend/e2e/**/*.e2e-spec.ts`。
|
|
20
|
-
3. `--fixtures`:fixtures 文件路径,默认 `${workspace}/apps/backend/e2e/fixtures/fixtures.ts`。
|
|
21
|
-
|
|
22
|
-
## 执行流程
|
|
23
|
-
|
|
24
|
-
1. 先扫描问题:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
|
28
|
-
python "$CODEX_HOME/skills/e2e-audit-fixer/scripts/e2e_e2e_audit.py" \
|
|
29
|
-
--workspace /Users/a1/work/ai-monorepo
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
2. 生成输出 JSON 用于复核:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
python "$CODEX_HOME/skills/e2e-audit-fixer/scripts/e2e_e2e_audit.py" \
|
|
36
|
-
--workspace /Users/a1/work/ai-monorepo \
|
|
37
|
-
--output-json /tmp/e2e-audit.json
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
3. 按修复策略应用:
|
|
41
|
-
|
|
42
|
-
1. 中文测试名:先翻译为英文。可直接提供翻译映射:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
python "$CODEX_HOME/skills/e2e-audit-fixer/scripts/e2e_e2e_audit.py" \
|
|
46
|
-
--workspace /Users/a1/work/ai-monorepo \
|
|
47
|
-
--translation-map /tmp/name-map.json \
|
|
48
|
-
--apply
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
2. fixture 重复实现:自动加注释提示并给出替换建议,保留原有逻辑不变。仅 `user` / `userCredential` 作为全局通用 fixture 候选,其余默认建议抽成本地 helper。
|
|
52
|
-
|
|
53
|
-
4. 必要时清理:对比扫描结果再次运行,确保无回归。
|
|
54
|
-
|
|
55
|
-
## 检查规则(脚本输出)
|
|
56
|
-
|
|
57
|
-
- `e2e-chinese`:`describe/it/test/context` 名称包含中文字符。
|
|
58
|
-
- `e2e-fixtures`:检测 `prisma.user.*`、`prisma.userCredential.*`、`jwtService.sign/jwt.sign`、未使用 `buildApiUrl()` 的 API URL 片段、未使用 `createAuthRequest/createAdminAuthRequest/createPublicRequest` 的手工请求调用。
|
|
59
|
-
- `e2e-local-helper`:检测其他 `prisma.*.create*` / `upsert` 类重复实现,默认只建议在当前测试文件内抽成本地 helper,不建议直接上收为全局 fixtures。
|
|
60
|
-
|
|
61
|
-
## 可选翻译入口
|
|
62
|
-
|
|
63
|
-
支持三种方式之一:
|
|
64
|
-
|
|
65
|
-
1. `--translation-map`:JSON 映射文件 `{ "中文原文": "English text" }`(推荐,稳定、可审计)。
|
|
66
|
-
2. `--translate-service openai`:提供 `OPENAI_API_KEY` 后自动调用 OpenAI 批量翻译。
|
|
67
|
-
3. 不提供翻译参数:仅输出中文字符串与建议,不改写文件。
|
|
68
|
-
|
|
69
|
-
## 注意
|
|
70
|
-
|
|
71
|
-
- 扫描不改变业务逻辑,只做问题检测与可控注释插入。
|
|
72
|
-
- 自动修复默认只对中文测试名称做真实替换。
|
|
73
|
-
- `user` / `userCredential` 以外的重复造数默认视为“本地 helper 候选”,不默认建议进入全局 fixtures。
|
|
74
|
-
- fixture 与请求构造类问题仅插入 TODO 注释,不宣称已完成重构。
|
|
75
|
-
- 翻译服务仅处理测试名称,不处理其他文本。
|
|
76
|
-
- 扫描路径来源全部来自参数,不会固定死为 `apps/backend/e2e/**/*.e2e-spec.ts`。
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: env-accessor-audit-fixer
|
|
3
|
-
description: Use when backend、NestJS、配置模块、E2E 测试或脚本中需要审计或修复 `process.env` 直读,判断项目是否已具备统一环境访问基础设施,并在缺少 EnvAccessor、EnvService、EnvModule 或统一配置接入时补齐最小可用实现。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 环境变量访问审计与修复
|
|
7
|
-
|
|
8
|
-
## 概览
|
|
9
|
-
|
|
10
|
-
先扫描 `process.env` 直读点,再判断仓库是否已有统一 env 访问基础设施。
|
|
11
|
-
|
|
12
|
-
- 若已有 `EnvService`、`createEnvAccessor`、`defaultEnvAccessor` 或等价封装,优先复用现有方案并逐项迁移。
|
|
13
|
-
- 若缺少统一入口,先补齐最小基础设施,再收口剩余直读点。
|
|
14
|
-
|
|
15
|
-
## 快速开始
|
|
16
|
-
|
|
17
|
-
先运行扫描脚本:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
|
|
21
|
-
python "$CODEX_HOME/skills/env-accessor-audit-fixer/scripts/env_accessor_audit.py" \
|
|
22
|
-
--workspace /Users/a1/work/ai-monorepo
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
需要结构化结果时输出 JSON:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
python "$CODEX_HOME/skills/env-accessor-audit-fixer/scripts/env_accessor_audit.py" \
|
|
29
|
-
--workspace /Users/a1/work/ai-monorepo \
|
|
30
|
-
--output-json /tmp/env-accessor-audit.json
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
若脚本显示尚未形成统一 env 入口,再读取 [references/bootstrap-env-foundation.md](./references/bootstrap-env-foundation.md)。
|
|
34
|
-
|
|
35
|
-
## 执行流程
|
|
36
|
-
|
|
37
|
-
1. 扫描 `apps/backend/src` 与 `apps/backend/e2e` 中的 `process.env`。
|
|
38
|
-
2. 仅排除真正的基础封装文件:
|
|
39
|
-
- `env.accessor.ts`
|
|
40
|
-
- `env.service.ts`
|
|
41
|
-
3. 不排除 `apps/backend/src/config/**/*.ts`,确保 `registerAs` 配置层也纳入审计。
|
|
42
|
-
4. 优先识别当前基础设施状态:
|
|
43
|
-
- 是否存在 `createEnvAccessor`
|
|
44
|
-
- 是否存在 `defaultEnvAccessor`
|
|
45
|
-
- 是否存在 `EnvService`
|
|
46
|
-
- 是否存在 `EnvModule`
|
|
47
|
-
- 是否已有 `registerAs` 或配置层通过统一 env 入口读取变量
|
|
48
|
-
5. 按场景为每个直读点选择迁移方式,而不是机械替换。
|
|
49
|
-
6. 修复后重新扫描,并补跑最小验证,确认配置读取与运行行为一致。
|
|
50
|
-
|
|
51
|
-
## 快速复核命令
|
|
52
|
-
|
|
53
|
-
项目具备 `rg` 时,优先用下列命令复核:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
rg "process\\.env" apps/backend/src apps/backend/e2e \
|
|
57
|
-
--glob '!*env.accessor.ts' \
|
|
58
|
-
--glob '!*env.service.ts'
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## 修复准则
|
|
62
|
-
|
|
63
|
-
### 配置层与 `registerAs`
|
|
64
|
-
|
|
65
|
-
- 优先使用 `defaultEnvAccessor`
|
|
66
|
-
- 仅在必须显式传入环境对象时使用 `createEnvAccessor(process.env)`
|
|
67
|
-
- 不要继续裸读 `process.env.FOO`
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
import { registerAs } from '@nestjs/config'
|
|
71
|
-
import { defaultEnvAccessor } from '@/common/env/env.accessor'
|
|
72
|
-
|
|
73
|
-
const env = defaultEnvAccessor
|
|
74
|
-
|
|
75
|
-
export const redisConfig = registerAs('redis', () => ({
|
|
76
|
-
host: env.str('REDIS_HOST', 'localhost'),
|
|
77
|
-
}))
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### 运行期服务、控制器、提供者
|
|
81
|
-
|
|
82
|
-
- 注入 `EnvService`
|
|
83
|
-
- 优先使用 `getString`、`getInt`、`getBoolean`、`isProd`、`isE2E` 等 typed getter
|
|
84
|
-
- 若模块尚未暴露 `EnvModule`,先补模块依赖,再迁移读取逻辑
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
@Injectable()
|
|
88
|
-
export class ExampleService {
|
|
89
|
-
constructor(private readonly env: EnvService) {}
|
|
90
|
-
|
|
91
|
-
getRedisHost() {
|
|
92
|
-
return this.env.getString('REDIS_HOST', 'localhost')
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### 独立脚本与 CLI
|
|
98
|
-
|
|
99
|
-
- 在完成 dotenv 装载后显式创建 accessor
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
const env = createEnvAccessor(process.env)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### 必须读取原始值
|
|
106
|
-
|
|
107
|
-
- 使用 `EnvService.getAccessor().raw(key)`,或 accessor 的 `raw(key)`
|
|
108
|
-
- 在代码中简短说明为何 typed getter 不适用
|
|
109
|
-
|
|
110
|
-
## 缺失基础设施时的补齐顺序
|
|
111
|
-
|
|
112
|
-
若扫描结果显示项目尚未形成统一 env 访问方案,按以下顺序补齐:
|
|
113
|
-
|
|
114
|
-
1. 创建 `env.accessor.ts`
|
|
115
|
-
- 提供 `createEnvAccessor`
|
|
116
|
-
- 提供 `defaultEnvAccessor`
|
|
117
|
-
- 至少支持 `str`、`bool`、`int`、`num`、`raw`、`appEnv`、`snapshot`
|
|
118
|
-
2. 创建 `env.service.ts`
|
|
119
|
-
- 包装 `ConfigService`
|
|
120
|
-
- 提供 typed getter 与常用环境判断方法
|
|
121
|
-
3. 创建 `env.module.ts`
|
|
122
|
-
- 暴露 `EnvService`
|
|
123
|
-
4. 将配置层迁移到 `registerAs + defaultEnvAccessor`
|
|
124
|
-
5. 将运行期服务迁移到 `EnvService`
|
|
125
|
-
6. 重新扫描剩余 `process.env` 直读点
|
|
126
|
-
|
|
127
|
-
优先复用现有命名、目录与模块结构;若无统一基础设施,再参考 [references/bootstrap-env-foundation.md](./references/bootstrap-env-foundation.md)。
|
|
128
|
-
|
|
129
|
-
## 例外与判断原则
|
|
130
|
-
|
|
131
|
-
- `env.accessor.ts`、`env.service.ts` 本身允许访问 `process.env`
|
|
132
|
-
- 负责 dotenv 装载、环境注入、测试环境临时覆写的底层入口可保留少量受控访问
|
|
133
|
-
- 测试里对 `process.env` 的显式设值可视为受控例外,但优先复用公共 fixture 或 helper
|
|
134
|
-
- 若某文件同时负责“装载环境”和“消费环境”,优先拆分职责,避免例外扩大
|
|
135
|
-
|
|
136
|
-
## 输出要求
|
|
137
|
-
|
|
138
|
-
最终输出至少包含:
|
|
139
|
-
|
|
140
|
-
1. 基础设施状态
|
|
141
|
-
2. `process.env` 直读文件清单
|
|
142
|
-
3. 每个问题的推荐迁移方式
|
|
143
|
-
4. 是否需要补齐基础设施
|
|
144
|
-
5. 已修改内容、验证结果与剩余风险
|
|
145
|
-
|
|
146
|
-
## 资源
|
|
147
|
-
|
|
148
|
-
- 扫描脚本:`scripts/env_accessor_audit.py`
|
|
149
|
-
- 补齐模板:`references/bootstrap-env-foundation.md`
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: error-handling-audit-fixer
|
|
3
|
-
description: Use when backend、NestJS、领域异常治理或错误处理审查中,需要检查业务代码是否绕过 DomainException / ErrorCode 体系,区分生产代码与 E2E 测试中的异常写法,识别直接抛出 BadRequestException、HttpException、Error 或直接返回中文 DomainException,并在项目缺少统一异常基础设施时给出补齐路径。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 错误处理规范检查与修复建议
|
|
7
|
-
|
|
8
|
-
## 概览
|
|
9
|
-
|
|
10
|
-
先判断项目是否已经具备统一错误处理基础设施,再扫描业务代码是否绕过 `DomainException` / `ErrorCode` 体系。默认只输出审计结果和修复建议,不自动改代码;只有用户明确要求时才进入自动修复。
|
|
11
|
-
|
|
12
|
-
## 扫描范围
|
|
13
|
-
|
|
14
|
-
脚本不预设任何项目路径,需要通过 `--src-dir` / `--e2e-dir` 显式传入。执行前必须先完成项目探索(见下方步骤 0)。
|
|
15
|
-
|
|
16
|
-
以下路径/后缀始终排除,不会产生误报:
|
|
17
|
-
|
|
18
|
-
| 排除类别 | 路径/后缀 |
|
|
19
|
-
|----------|-----------|
|
|
20
|
-
| 单元测试 | `*.spec.ts`、`*.test.ts`、`*.e2e-spec.ts` |
|
|
21
|
-
| 测试辅助 | `*.mock.ts`、`*.stub.ts`、`*.fixture.ts`、`fixtures/`、`test-utils/`、`testing/`、`__tests__/`、`__test__/` |
|
|
22
|
-
| 基础设施 | `*/filters/`、`prisma/`、`scripts/` |
|
|
23
|
-
| 异常定义 | `*.exception.ts` |
|
|
24
|
-
| 入口文件 | `main.ts` |
|
|
25
|
-
|
|
26
|
-
只有在用户**明确要求**评估测试债务时,才传 `--e2e-dir` + `--scope e2e` 扫描测试代码。
|
|
27
|
-
|
|
28
|
-
## 快速开始
|
|
29
|
-
|
|
30
|
-
### 步骤 0:项目探索(每个项目首次执行时必须完成)
|
|
31
|
-
|
|
32
|
-
在调用脚本前,先探索项目结构,识别出后端生产代码和测试代码的实际路径。方法:
|
|
33
|
-
|
|
34
|
-
1. 查看项目根目录结构(`ls` 或 Glob)
|
|
35
|
-
2. 识别后端应用目录(可能是 `apps/backend/src`、`src`、`server/src` 等)
|
|
36
|
-
3. 识别测试目录(可能是 `apps/backend/e2e`、`test`、`e2e`、`__tests__` 等)
|
|
37
|
-
4. 如果是 monorepo,可能有多个后端服务,每个都需要单独传 `--src-dir`
|
|
38
|
-
|
|
39
|
-
典型示例:
|
|
40
|
-
|
|
41
|
-
| 项目类型 | 生产代码 | 测试代码 |
|
|
42
|
-
|----------|----------|----------|
|
|
43
|
-
| NestJS monorepo | `apps/backend/src` | `apps/backend/e2e` |
|
|
44
|
-
| 单体 NestJS | `src` | `test` 或 `e2e` |
|
|
45
|
-
| 多服务 monorepo | `apps/api/src`、`apps/worker/src` | `apps/api/e2e`、`apps/worker/e2e` |
|
|
46
|
-
|
|
47
|
-
### 步骤 1:审计生产代码
|
|
48
|
-
|
|
49
|
-
将探索到的路径传给脚本(`--src-dir` 可传多个):
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
SKILL_HOME="${SKILL_HOME:-$HOME/.claude/skills}"
|
|
53
|
-
python "$SKILL_HOME/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
54
|
-
--workspace "$PWD" \
|
|
55
|
-
--src-dir <探索到的生产代码路径>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
示例(当前项目):
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
python "$SKILL_HOME/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
62
|
-
--workspace "$PWD" \
|
|
63
|
-
--src-dir apps/backend/src
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
多服务示例:
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
python "$SKILL_HOME/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
70
|
-
--workspace "$PWD" \
|
|
71
|
-
--src-dir apps/api/src \
|
|
72
|
-
--src-dir apps/worker/src
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### 步骤 2:(仅在用户明确要求时)审计测试代码
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
python "$SKILL_HOME/error-handling-audit-fixer/scripts/error_handling_audit.py" \
|
|
79
|
-
--workspace "$PWD" \
|
|
80
|
-
--e2e-dir <探索到的测试代码路径> \
|
|
81
|
-
--scope e2e \
|
|
82
|
-
--output-json /tmp/error-handling-audit.json
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
3. 当项目尚未具备 `DomainException` / `ErrorCode` / 领域异常目录等基础设施时,先阅读 [references/foundation-bootstrap.md](./references/foundation-bootstrap.md) 再决定是否补齐。
|
|
86
|
-
|
|
87
|
-
4. 当项目基础设施齐全但出现违规抛错时,按 [references/error-handling-standard.md](./references/error-handling-standard.md) 给出替换建议;如用户明确要求,才实施自动修复。
|
|
88
|
-
|
|
89
|
-
5. 当结果里 `e2e/raw-error` 数量很大时,不要直接把它和生产代码风险混在一起汇报;先给 `src` 结论,再决定是否单独治理 `e2e`。
|
|
90
|
-
|
|
91
|
-
## 执行流程
|
|
92
|
-
|
|
93
|
-
1. 默认只扫描 `apps/backend/src`(生产代码)。测试代码、E2E、prisma seed、脚本等非生产路径全部排除。只有在用户明确要求评估测试债务时,才传 `--scope e2e` 扫描测试代码。
|
|
94
|
-
2. 先判断基础设施状态:
|
|
95
|
-
- 是否存在 `DomainException`
|
|
96
|
-
- 是否存在 `ErrorCode`
|
|
97
|
-
- 是否存在领域异常目录或模块异常类
|
|
98
|
-
- 是否存在全局异常过滤器或结构化错误输出链路
|
|
99
|
-
3. 再识别四类问题:
|
|
100
|
-
- 直接实例化 Nest 标准异常,如 `BadRequestException`、`HttpException`
|
|
101
|
-
- `throw new Error(...)` 或 `Promise.reject(new Error(...))`
|
|
102
|
-
- 直接 `new DomainException(...)` 但 payload 中未显式带 `code`
|
|
103
|
-
- `DomainException` 直接返回中文 message
|
|
104
|
-
4. 对每个命中项给出修复建议,优先级固定如下:
|
|
105
|
-
- 优先复用现有模块异常类
|
|
106
|
-
- 其次建议在模块 `exceptions/` 目录新增领域异常类
|
|
107
|
-
- 最后才允许直接使用 `DomainException`,且必须补齐 `code` 与 `args`
|
|
108
|
-
5. 若基础设施缺失,不直接把全部命中项定性为“应立刻改业务代码”,而是先输出“需补齐基础设施”的诊断与最小落地路径。
|
|
109
|
-
6. 只有在用户明确说“自动修复”“直接改”或等价表述时,才进入落代码阶段。
|
|
110
|
-
7. 若脚本结果与实际代码不一致,必须抽样打开命中文件复核,不要把脚本结果当成绝对真相。
|
|
111
|
-
|
|
112
|
-
## 审计命令(rg 快速复核)
|
|
113
|
-
|
|
114
|
-
以下 rg 命令用于手工复核,将 `<SRC_DIR>` 替换为步骤 0 探索到的实际路径:
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
rg "new (BadRequestException|UnauthorizedException|ForbiddenException|NotFoundException|HttpException|InternalServerErrorException)\(" \
|
|
118
|
-
<SRC_DIR> \
|
|
119
|
-
--glob '!*spec.ts' --glob '!*test.ts' \
|
|
120
|
-
--glob '!*exception.ts' \
|
|
121
|
-
--glob '!*/filters/**' \
|
|
122
|
-
--glob '!*main.ts'
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
rg "new Error\(" <SRC_DIR> --glob '!*spec.ts' --glob '!*test.ts'
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
rg "new DomainException\([^)]*$" -A3 <SRC_DIR>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
rg "DomainException\([^)]*[\u4e00-\u9fa5]" <SRC_DIR> \
|
|
135
|
-
--glob '!*spec.ts' \
|
|
136
|
-
--glob '!*/common/exceptions/**'
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## 修复准则
|
|
140
|
-
|
|
141
|
-
### 1. 优先复用现有领域异常
|
|
142
|
-
|
|
143
|
-
- 若模块 `exceptions/` 已有语义匹配的异常类,直接复用。
|
|
144
|
-
- 不要把已可表达为领域异常的问题继续保留成裸 `BadRequestException('字符串')`。
|
|
145
|
-
|
|
146
|
-
### 2. 缺少模块异常时新增领域异常类
|
|
147
|
-
|
|
148
|
-
- 在模块 `exceptions/` 下新增异常类。
|
|
149
|
-
- 异常类继承统一 `DomainException`。
|
|
150
|
-
- 构造函数中显式指定 `ErrorCode`。
|
|
151
|
-
- 把上下文放进 `args`,不要把业务文案直接写死到 message。
|
|
152
|
-
- 为新增异常补最小单测。
|
|
153
|
-
|
|
154
|
-
### 3. 临时直接使用 DomainException
|
|
155
|
-
|
|
156
|
-
- 仅在尚未抽出专用异常类、但当前修复必须继续推进时使用。
|
|
157
|
-
- payload 中必须显式包含 `code`。
|
|
158
|
-
- `args` 中必须保留排障所需上下文。
|
|
159
|
-
|
|
160
|
-
### 4. 基础设施缺失时的判断
|
|
161
|
-
|
|
162
|
-
- 如果仓库里根本没有 `DomainException` 或 `ErrorCode`,优先建议补基础设施,不要直接发散式新增几十个本地异常实现。
|
|
163
|
-
- 如果已有 `DomainException` 但没有统一 `ErrorCode`,先统一错误码来源,再扩展模块异常。
|
|
164
|
-
- 如果已有异常类与错误码,但缺少结构化输出链路,优先补过滤器或输出映射,保证 `code`、`args`、`requestId` 可稳定透出。
|
|
165
|
-
|
|
166
|
-
## 输出要求
|
|
167
|
-
|
|
168
|
-
执行这个技能时,最终输出至少包含:
|
|
169
|
-
|
|
170
|
-
1. 基础设施状态
|
|
171
|
-
2. 命中文件清单
|
|
172
|
-
3. 每个问题的类型、定位与建议替换方式
|
|
173
|
-
4. 是否可复用现有领域异常
|
|
174
|
-
5. 是否需要先补齐基础设施
|
|
175
|
-
6. 若用户要求自动修复,列出拟修改文件、验证方式与剩余风险
|
|
176
|
-
|
|
177
|
-
补充要求:
|
|
178
|
-
|
|
179
|
-
7. 明确区分 `src` 与 `e2e` 命中数量,避免测试噪音淹没生产代码风险
|
|
180
|
-
8. 标注哪些命中是脚本结果、哪些已经过源码抽样复核
|
|
181
|
-
9. 若脚本疑似误报,要在结论里明确说明“脚本规则限制”而不是直接要求改代码
|
|
182
|
-
|
|
183
|
-
## 资源
|
|
184
|
-
|
|
185
|
-
- 扫描脚本:`scripts/error_handling_audit.py`
|
|
186
|
-
- 规范参考:`references/error-handling-standard.md`
|
|
187
|
-
- 基础设施补齐指南:`references/foundation-bootstrap.md`
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
interface:
|
|
2
|
-
display_name: "错误处理规范检查"
|
|
3
|
-
short_description: "按 src 与 e2e 分开审计后端异常是否绕过 DomainException 与 ErrorCode 体系"
|
|
4
|
-
default_prompt: "使用 $error-handling-audit-fixer 先审计 backend src,再按需审计 e2e,检查错误处理是否绕过 DomainException / ErrorCode 体系,并在基础设施缺失时给出补齐建议。"
|
|
5
|
-
|
|
6
|
-
policy:
|
|
7
|
-
allow_implicit_invocation: true
|