sdd-skills 1.1.10 → 1.2.0
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/README.md +11 -12
- package/install.js +33 -5
- package/package.json +1 -1
- package/skills/code-reviewer/SKILL.md +182 -15
- package/skills/developer/SKILL.md +564 -0
- package/skills/notifier/SKILL.md +10 -11
- package/skills/tester/SKILL.md +19 -19
- package/uninstall.js +4 -2
- package/skills/backend-engineer/SKILL.md +0 -480
- package/skills/frontend-engineer/SKILL.md +0 -674
package/README.md
CHANGED
|
@@ -20,8 +20,7 @@ sdd-skills
|
|
|
20
20
|
| Skill | 角色 | 职责 |
|
|
21
21
|
|-------|------|------|
|
|
22
22
|
| **sae** | 架构师 | 需求分析、架构设计、技术方案 |
|
|
23
|
-
| **
|
|
24
|
-
| **frontend-engineer** | Vue 前端工程师 | 组件开发、状态管理、用户交互 |
|
|
23
|
+
| **developer** | 研发工程师 | 前后端代码实现(Go后端、Vue/React前端) |
|
|
25
24
|
| **tester** | 测试工程师 | 单元测试、E2E 测试、质量保障 |
|
|
26
25
|
| **code-reviewer** | 代码审查专家 | 代码质量、安全审查、规范检查 |
|
|
27
26
|
| **git-engineer** | Git 工程师 | 预检测、提交规范、MR 创建 |
|
|
@@ -34,8 +33,7 @@ sdd-skills
|
|
|
34
33
|
↓
|
|
35
34
|
🗣️ Pre-Execution Review(多角色讨论)
|
|
36
35
|
├─ SAE 角度:需求清晰度、架构复杂度
|
|
37
|
-
├─
|
|
38
|
-
├─ Frontend Engineer 角度:用户体验、组件设计
|
|
36
|
+
├─ Developer 角度:技术可行性、性能评估
|
|
39
37
|
├─ Tester 角度:测试策略、环境需求
|
|
40
38
|
├─ Code Reviewer 角度:潜在风险、安全关注
|
|
41
39
|
└─ Git Engineer 角度:CI/CD 兼容性
|
|
@@ -44,17 +42,16 @@ sdd-skills
|
|
|
44
42
|
↓
|
|
45
43
|
📐 SAE → 需求规格文档
|
|
46
44
|
↓
|
|
47
|
-
👨💻
|
|
48
|
-
👩💻 Frontend Engineer → 前端 OpenSpec → 代码实现
|
|
45
|
+
👨💻 Developer → OpenSpec → 代码实现(后端 + 前端)
|
|
49
46
|
↓
|
|
50
47
|
🧪 Tester → 测试验证
|
|
51
|
-
├─ 失败 → 📢 钉钉通知 →
|
|
48
|
+
├─ 失败 → 📢 钉钉通知 → 返回 Developer 修复
|
|
52
49
|
└─ 成功 ↓
|
|
53
50
|
👀 Code Reviewer → 代码审查
|
|
54
|
-
├─ 失败 → 📢 钉钉通知 →
|
|
51
|
+
├─ 失败 → 📢 钉钉通知 → 返回 Developer 修复
|
|
55
52
|
└─ 成功 ↓
|
|
56
53
|
🚀 Git Engineer → 预检测 + 提交 + MR
|
|
57
|
-
├─ 失败 → 📢 钉钉通知 →
|
|
54
|
+
├─ 失败 → 📢 钉钉通知 → 返回 Developer 修复
|
|
58
55
|
└─ 成功 ↓
|
|
59
56
|
✅ 完成(等待 MR 批准)
|
|
60
57
|
```
|
|
@@ -96,7 +93,7 @@ Claude (SAE Skill):
|
|
|
96
93
|
- 工作流: user-login
|
|
97
94
|
- 失败阶段: Tester
|
|
98
95
|
- 错误信息: 3/10 测试用例失败
|
|
99
|
-
- 建议操作: 返回
|
|
96
|
+
- 建议操作: 返回 Developer 修复
|
|
100
97
|
|
|
101
98
|
🕐 时间: 2026-01-06 14:30:00
|
|
102
99
|
```
|
|
@@ -143,14 +140,16 @@ npm unlink -g sdd-skills
|
|
|
143
140
|
|
|
144
141
|
## 📚 技术栈说明
|
|
145
142
|
|
|
146
|
-
###
|
|
143
|
+
### Developer Skill (研发工程师)
|
|
144
|
+
|
|
145
|
+
**后端技术栈**:
|
|
147
146
|
- **语言**: Go 1.21+
|
|
148
147
|
- **框架**: Gin / Echo / Fiber
|
|
149
148
|
- **数据库**: PostgreSQL, MySQL, Redis
|
|
150
149
|
- **测试**: go test, testify, gomock
|
|
151
150
|
- **覆盖率要求**: >= 90%
|
|
152
151
|
|
|
153
|
-
|
|
152
|
+
**前端技术栈**:
|
|
154
153
|
- **框架**: Vue 3 / React 18+ (支持多框架)
|
|
155
154
|
- **状态管理**: Pinia / Redux Toolkit / Zustand
|
|
156
155
|
- **构建工具**: Vite
|
package/install.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* to Claude Code's skills directory.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { readFileSync, existsSync, mkdirSync, writeFileSync, cpSync } from 'fs';
|
|
10
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync, cpSync, rmSync } from 'fs';
|
|
11
11
|
import { join, dirname } from 'path';
|
|
12
12
|
import { homedir } from 'os';
|
|
13
13
|
import { fileURLToPath } from 'url';
|
|
@@ -32,6 +32,9 @@ const GLOBAL_SKILLS_DIR = join(homedir(), '.claude', 'skills');
|
|
|
32
32
|
const LOCAL_SKILLS_DIR = join(process.cwd(), '.claude', 'skills');
|
|
33
33
|
const SOURCE_SKILLS_DIR = join(__dirname, 'skills');
|
|
34
34
|
|
|
35
|
+
// Deprecated skills to clean up on upgrade
|
|
36
|
+
const DEPRECATED_SKILLS = ['backend-engineer', 'frontend-engineer'];
|
|
37
|
+
|
|
35
38
|
/**
|
|
36
39
|
* Display welcome banner
|
|
37
40
|
*/
|
|
@@ -133,6 +136,26 @@ async function promptInstallation() {
|
|
|
133
136
|
return answers;
|
|
134
137
|
}
|
|
135
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Clean up deprecated skills from previous installations
|
|
141
|
+
*/
|
|
142
|
+
function cleanupDeprecatedSkills(targetDir) {
|
|
143
|
+
let removedCount = 0;
|
|
144
|
+
for (const skill of DEPRECATED_SKILLS) {
|
|
145
|
+
const skillDir = join(targetDir, skill);
|
|
146
|
+
if (existsSync(skillDir)) {
|
|
147
|
+
try {
|
|
148
|
+
rmSync(skillDir, { recursive: true });
|
|
149
|
+
console.log(chalk.yellow(` ⚠ Removed deprecated: ${skill}`));
|
|
150
|
+
removedCount++;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.log(chalk.red(` ✗ Failed to remove ${skill}: ${error.message}`));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return removedCount;
|
|
157
|
+
}
|
|
158
|
+
|
|
136
159
|
/**
|
|
137
160
|
* Install Skills to target directory
|
|
138
161
|
*/
|
|
@@ -145,11 +168,16 @@ function installSkills(targetDir) {
|
|
|
145
168
|
console.log(chalk.gray(` Created directory: ${targetDir}`));
|
|
146
169
|
}
|
|
147
170
|
|
|
171
|
+
// Clean up deprecated skills first
|
|
172
|
+
const removedCount = cleanupDeprecatedSkills(targetDir);
|
|
173
|
+
if (removedCount > 0) {
|
|
174
|
+
console.log('');
|
|
175
|
+
}
|
|
176
|
+
|
|
148
177
|
// Get list of skills
|
|
149
178
|
const skills = [
|
|
150
179
|
'sae',
|
|
151
|
-
'
|
|
152
|
-
'frontend-engineer',
|
|
180
|
+
'developer',
|
|
153
181
|
'tester',
|
|
154
182
|
'code-reviewer',
|
|
155
183
|
'git-engineer',
|
|
@@ -213,7 +241,7 @@ function displaySummary(location) {
|
|
|
213
241
|
console.log(chalk.bold.green('\n✨ Installation Complete!\n'));
|
|
214
242
|
console.log(chalk.bold('📋 Summary:\n'));
|
|
215
243
|
console.log(` ${chalk.gray('Location:')} ${chalk.cyan(skillsPath)}`);
|
|
216
|
-
console.log(` ${chalk.gray('Skills:')} ${chalk.cyan('
|
|
244
|
+
console.log(` ${chalk.gray('Skills:')} ${chalk.cyan('6')} (SAE, Developer, Tester, Reviewer, Git, Notifier)`);
|
|
217
245
|
|
|
218
246
|
console.log(chalk.bold('\n🚀 Getting Started:\n'));
|
|
219
247
|
console.log(' 1. Open Claude Code');
|
|
@@ -246,7 +274,7 @@ async function install() {
|
|
|
246
274
|
console.log(chalk.bold('\n📋 Installation Summary:\n'));
|
|
247
275
|
console.log(` ${chalk.gray('Location:')} ${chalk.cyan(answers.location === 'global' ? 'Global' : 'Local (Current Project)')}`);
|
|
248
276
|
console.log(` ${chalk.gray('Install to:')} ${chalk.cyan(targetDir)}`);
|
|
249
|
-
console.log(` ${chalk.gray('Skills:')} ${chalk.cyan('
|
|
277
|
+
console.log(` ${chalk.gray('Skills:')} ${chalk.cyan('6')} (SAE, Developer, Tester, Reviewer, Git, Notifier)`);
|
|
250
278
|
if (answers.configureDingTalk) {
|
|
251
279
|
console.log(` ${chalk.gray('DingTalk:')} ${chalk.cyan('Enabled')}`);
|
|
252
280
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-reviewer
|
|
3
|
-
description:
|
|
3
|
+
description: 代码审查专家,负责代码质量、安全审查、接口一致性和规范检查。当代码实现完成需要代码审查时激活。检查代码风格、最佳实践、安全漏洞、性能问题、前后端接口一致性,审查不通过时触发钉钉通知。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Code Reviewer
|
|
@@ -163,7 +163,127 @@ const localUserId = ref(props.userId)
|
|
|
163
163
|
- 使用白名单而非黑名单
|
|
164
164
|
- 文件上传有大小和类型限制
|
|
165
165
|
|
|
166
|
-
#### 3.
|
|
166
|
+
#### 3. 接口一致性审查
|
|
167
|
+
|
|
168
|
+
**重要**:当涉及前后端接口、gRPC、WebSocket 等通信时,必须确保接口定义与实际使用完全一致。
|
|
169
|
+
|
|
170
|
+
✅ **检查点**:
|
|
171
|
+
- [ ] 接口地址(URL/路径)前后端一致
|
|
172
|
+
- [ ] 请求方法(GET/POST/PUT/DELETE)一致
|
|
173
|
+
- [ ] 请求参数名称、类型、必填性一致
|
|
174
|
+
- [ ] 响应字段名称、类型与前端绑定一致
|
|
175
|
+
- [ ] 错误码和错误消息格式一致
|
|
176
|
+
- [ ] 分页参数(page/pageSize/offset/limit)一致
|
|
177
|
+
- [ ] 日期时间格式一致(时间戳 vs ISO 8601)
|
|
178
|
+
|
|
179
|
+
**HTTP API 检查**:
|
|
180
|
+
```go
|
|
181
|
+
// 后端定义 (Go/Gin)
|
|
182
|
+
type LoginRequest struct {
|
|
183
|
+
Email string `json:"email" binding:"required,email"`
|
|
184
|
+
Password string `json:"password" binding:"required,min=8"`
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
type LoginResponse struct {
|
|
188
|
+
Token string `json:"token"`
|
|
189
|
+
ExpiresAt int64 `json:"expires_at"` // 注意:前端需要使用相同字段名
|
|
190
|
+
User User `json:"user"`
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// API 路由
|
|
194
|
+
r.POST("/api/v1/auth/login", handler.Login)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// 前端调用 (Vue/TypeScript)
|
|
199
|
+
interface LoginRequest {
|
|
200
|
+
email: string // ✅ 与后端一致
|
|
201
|
+
password: string // ✅ 与后端一致
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
interface LoginResponse {
|
|
205
|
+
token: string
|
|
206
|
+
expires_at: number // ✅ 与后端一致(注意下划线命名)
|
|
207
|
+
user: User
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// API 调用
|
|
211
|
+
const response = await axios.post<LoginResponse>(
|
|
212
|
+
'/api/v1/auth/login', // ✅ 路径与后端一致
|
|
213
|
+
loginRequest
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
// 页面绑定
|
|
217
|
+
const token = ref(response.data.token) // ✅ 字段名一致
|
|
218
|
+
const expiresAt = ref(response.data.expires_at) // ✅ 字段名一致
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
❌ **常见问题**:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// ❌ 错误:字段名不一致
|
|
225
|
+
interface LoginResponse {
|
|
226
|
+
accessToken: string // 后端是 token
|
|
227
|
+
expiresAt: number // 后端是 expires_at(下划线)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ❌ 错误:路径不一致
|
|
231
|
+
axios.post('/api/auth/login', ...) // 后端是 /api/v1/auth/login
|
|
232
|
+
|
|
233
|
+
// ❌ 错误:参数名不一致
|
|
234
|
+
const params = {
|
|
235
|
+
userName: 'test', // 后端期望 email
|
|
236
|
+
pwd: '123456' // 后端期望 password
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**gRPC 检查**:
|
|
241
|
+
```protobuf
|
|
242
|
+
// proto 定义
|
|
243
|
+
message CreateUserRequest {
|
|
244
|
+
string email = 1;
|
|
245
|
+
string password = 2;
|
|
246
|
+
optional string nickname = 3;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
message CreateUserResponse {
|
|
250
|
+
int64 user_id = 1;
|
|
251
|
+
string created_at = 2;
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// 前端调用必须与 proto 定义一致
|
|
257
|
+
const request: CreateUserRequest = {
|
|
258
|
+
email: 'test@example.com',
|
|
259
|
+
password: 'password123',
|
|
260
|
+
nickname: 'Test User' // optional 字段
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// 响应字段绑定
|
|
264
|
+
const userId = ref(response.userId) // ✅ proto: user_id -> camelCase
|
|
265
|
+
const createdAt = ref(response.createdAt) // ✅ proto: created_at -> camelCase
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**接口一致性审查清单**:
|
|
269
|
+
|
|
270
|
+
| 检查项 | 后端定义 | 前端使用 | 是否一致 |
|
|
271
|
+
|--------|----------|----------|----------|
|
|
272
|
+
| API 路径 | `/api/v1/users` | `/api/v1/users` | ✅ |
|
|
273
|
+
| 请求方法 | `POST` | `POST` | ✅ |
|
|
274
|
+
| 请求参数 | `email`, `password` | `email`, `password` | ✅ |
|
|
275
|
+
| 响应字段 | `token`, `expires_at` | `token`, `expires_at` | ✅ |
|
|
276
|
+
| 错误格式 | `{code, message}` | `{code, message}` | ✅ |
|
|
277
|
+
|
|
278
|
+
**OpenSpec 交叉验证**:
|
|
279
|
+
|
|
280
|
+
审查时应对照 OpenSpec 中的接口定义:
|
|
281
|
+
- 后端 OpenSpec: `openspec/changes/[feature]/backend-spec.md`
|
|
282
|
+
- 前端 OpenSpec: `openspec/changes/[feature]/frontend-spec.md`
|
|
283
|
+
|
|
284
|
+
确保两份规格中定义的接口完全匹配。
|
|
285
|
+
|
|
286
|
+
#### 4. 性能审查
|
|
167
287
|
|
|
168
288
|
**后端性能**:
|
|
169
289
|
- [ ] 避免 N+1 查询问题
|
|
@@ -204,7 +324,7 @@ const HeavyComponent = defineAsyncComponent(() =>
|
|
|
204
324
|
</script>
|
|
205
325
|
```
|
|
206
326
|
|
|
207
|
-
####
|
|
327
|
+
#### 5. 可维护性审查
|
|
208
328
|
|
|
209
329
|
- [ ] 代码结构清晰,模块划分合理
|
|
210
330
|
- [ ] 函数/方法职责单一,长度适中(< 50 行)
|
|
@@ -273,6 +393,7 @@ npm audit
|
|
|
273
393
|
- 审查文件数:15 个
|
|
274
394
|
- 代码质量:✅ 优秀
|
|
275
395
|
- 安全检查:✅ 无安全问题
|
|
396
|
+
- 接口一致性:✅ 前后端接口匹配
|
|
276
397
|
- 性能审查:✅ 无性能隐患
|
|
277
398
|
- 可维护性:✅ 结构清晰
|
|
278
399
|
|
|
@@ -280,6 +401,7 @@ npm audit
|
|
|
280
401
|
1. 错误处理完善,使用了 context 传递
|
|
281
402
|
2. 数据库查询使用了预加载,避免 N+1 问题
|
|
282
403
|
3. 前端组件设计合理,可复用性强
|
|
404
|
+
4. API 接口定义与前端调用完全一致
|
|
283
405
|
|
|
284
406
|
下一步请 Tester 进行测试验证。
|
|
285
407
|
```
|
|
@@ -298,16 +420,20 @@ npm audit
|
|
|
298
420
|
- 问题:N+1 查询
|
|
299
421
|
- 修复建议:使用 Preload 预加载关联数据
|
|
300
422
|
|
|
301
|
-
3.
|
|
423
|
+
3. 【严重】接口不一致 (frontend/src/api/user.ts:23 vs backend/api/user_handler.go:45)
|
|
424
|
+
- 问题:前端使用 `expiresAt`,后端返回 `expires_at`
|
|
425
|
+
- 修复建议:前端字段名改为 `expires_at` 或后端改为 camelCase
|
|
426
|
+
|
|
427
|
+
4. 【中等】代码质量 (frontend/src/components/UserList.vue:89)
|
|
302
428
|
- 问题:未定义 Props 类型
|
|
303
429
|
- 修复建议:使用 TypeScript 接口定义 Props
|
|
304
430
|
|
|
305
|
-
|
|
431
|
+
5. 【轻微】可维护性 (backend/utils/helper.go:23)
|
|
306
432
|
- 问题:魔法数字 100
|
|
307
433
|
- 修复建议:定义为常量 MaxPageSize
|
|
308
434
|
|
|
309
435
|
📊 问题统计:
|
|
310
|
-
- 严重问题:
|
|
436
|
+
- 严重问题:3 个
|
|
311
437
|
- 中等问题:1 个
|
|
312
438
|
- 轻微问题:1 个
|
|
313
439
|
|
|
@@ -339,6 +465,14 @@ npm audit
|
|
|
339
465
|
- [ ] CORS 配置正确
|
|
340
466
|
- [ ] 敏感信息不泄露(日志、错误消息)
|
|
341
467
|
|
|
468
|
+
## 接口一致性
|
|
469
|
+
- [ ] API 路径与前端调用一致
|
|
470
|
+
- [ ] 请求参数名称与前端一致(注意命名风格:snake_case vs camelCase)
|
|
471
|
+
- [ ] 响应字段名称与前端绑定一致
|
|
472
|
+
- [ ] 错误码和错误消息格式与前端处理一致
|
|
473
|
+
- [ ] 分页参数规范一致(page/pageSize 或 offset/limit)
|
|
474
|
+
- [ ] 日期时间格式一致(时间戳或 ISO 8601)
|
|
475
|
+
|
|
342
476
|
## 性能
|
|
343
477
|
- [ ] 无 N+1 查询问题
|
|
344
478
|
- [ ] 数据库索引合理
|
|
@@ -373,6 +507,14 @@ npm audit
|
|
|
373
507
|
- [ ] Token 管理安全(存储、刷新、失效处理)
|
|
374
508
|
- [ ] 表单输入验证完善
|
|
375
509
|
|
|
510
|
+
## 接口一致性
|
|
511
|
+
- [ ] API 路径与后端路由一致
|
|
512
|
+
- [ ] 请求参数名称与后端一致(注意命名风格转换)
|
|
513
|
+
- [ ] 响应字段绑定与后端返回一致
|
|
514
|
+
- [ ] TypeScript 接口定义与后端结构体一致
|
|
515
|
+
- [ ] 错误处理与后端错误格式匹配
|
|
516
|
+
- [ ] 分页参数与后端规范一致
|
|
517
|
+
|
|
376
518
|
## 性能
|
|
377
519
|
- [ ] 组件懒加载
|
|
378
520
|
- [ ] 图片懒加载
|
|
@@ -404,7 +546,7 @@ npm audit
|
|
|
404
546
|
"msgtype": "markdown",
|
|
405
547
|
"markdown": {
|
|
406
548
|
"title": "SDD 工作流失败",
|
|
407
|
-
"text": "❌ **SDD 代码审查不通过**\n\n- **工作流**: user-login\n- **失败阶段**: Code Reviewer\n- **问题数量**: 严重 2 个,中等 1 个,轻微 1 个\n- **主要问题**:\n - 密码明文存储(严重)\n - N+1 查询问题(严重)\n- **建议操作**: 返回
|
|
549
|
+
"text": "❌ **SDD 代码审查不通过**\n\n- **工作流**: user-login\n- **失败阶段**: Code Reviewer\n- **问题数量**: 严重 2 个,中等 1 个,轻微 1 个\n- **主要问题**:\n - 密码明文存储(严重)\n - N+1 查询问题(严重)\n- **建议操作**: 返回 Developer 修复\n\n🕐 **时间**: 2026-01-06 15:00:00"
|
|
408
550
|
}
|
|
409
551
|
}
|
|
410
552
|
```
|
|
@@ -413,10 +555,10 @@ npm audit
|
|
|
413
555
|
|
|
414
556
|
## 与其他 Skills 的协作
|
|
415
557
|
|
|
416
|
-
1. **上游**: 接收
|
|
558
|
+
1. **上游**: 接收 Developer 的代码实现
|
|
417
559
|
2. **下游**:
|
|
418
560
|
- 审查通过 → 交给 Tester 进行测试验证
|
|
419
|
-
- 审查不通过 → **自动调用**
|
|
561
|
+
- 审查不通过 → **自动调用** Developer 修复 → 重新审查
|
|
420
562
|
3. **并行**: 无
|
|
421
563
|
|
|
422
564
|
## 会话管理
|
|
@@ -460,6 +602,7 @@ npm audit
|
|
|
460
602
|
- frontend/src/views/LoginView.vue
|
|
461
603
|
- frontend/src/components/LoginForm.vue
|
|
462
604
|
- frontend/src/stores/authStore.ts
|
|
605
|
+
- frontend/src/api/auth.ts
|
|
463
606
|
|
|
464
607
|
🔍 自动化检查:
|
|
465
608
|
- golangci-lint:✅ 通过
|
|
@@ -467,6 +610,12 @@ npm audit
|
|
|
467
610
|
- ESLint:✅ 通过
|
|
468
611
|
- npm audit:✅ 无安全漏洞
|
|
469
612
|
|
|
613
|
+
🔍 接口一致性检查:
|
|
614
|
+
- 后端 API: POST /api/v1/auth/login
|
|
615
|
+
- 前端调用: POST /api/v1/auth/login ✅
|
|
616
|
+
- 请求参数: email, password ✅
|
|
617
|
+
- 响应字段: ❌ 不一致(见下方详情)
|
|
618
|
+
|
|
470
619
|
❌ 代码审查不通过
|
|
471
620
|
|
|
472
621
|
问题详情:
|
|
@@ -481,7 +630,22 @@ npm audit
|
|
|
481
630
|
user.Password = string(hashedPassword)
|
|
482
631
|
```
|
|
483
632
|
|
|
484
|
-
2.
|
|
633
|
+
2. 【严重】接口不一致 (frontend/src/api/auth.ts:15 vs backend/api/auth_handler.go:32)
|
|
634
|
+
```typescript
|
|
635
|
+
// 前端定义(错误)
|
|
636
|
+
interface LoginResponse {
|
|
637
|
+
accessToken: string // ❌ 后端返回 token
|
|
638
|
+
expiresAt: number // ❌ 后端返回 expires_at
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// 建议修复
|
|
642
|
+
interface LoginResponse {
|
|
643
|
+
token: string // ✅ 与后端一致
|
|
644
|
+
expires_at: number // ✅ 与后端一致
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
3. 【严重】性能问题 (backend/service/user_service.go:45)
|
|
485
649
|
```go
|
|
486
650
|
// 当前代码(N+1 查询)
|
|
487
651
|
for _, user := range users {
|
|
@@ -492,7 +656,7 @@ npm audit
|
|
|
492
656
|
db.Preload("Orders").Find(&users)
|
|
493
657
|
```
|
|
494
658
|
|
|
495
|
-
|
|
659
|
+
4. 【中等】类型安全 (frontend/src/components/LoginForm.vue:12)
|
|
496
660
|
```vue
|
|
497
661
|
<!-- 当前代码(缺少类型定义) -->
|
|
498
662
|
<script setup>
|
|
@@ -509,21 +673,23 @@ npm audit
|
|
|
509
673
|
```
|
|
510
674
|
|
|
511
675
|
建议操作:
|
|
512
|
-
🔄 自动调用 /
|
|
513
|
-
🔄 自动调用 /
|
|
676
|
+
🔄 自动调用 /developer 修复密码加密和 N+1 查询问题
|
|
677
|
+
🔄 自动调用 /developer 修复前端接口定义与后端一致
|
|
678
|
+
🔄 自动调用 /developer 添加 TypeScript 类型定义
|
|
514
679
|
|
|
515
680
|
📢 已发送钉钉通知(审查不通过)
|
|
516
681
|
|
|
517
|
-
[
|
|
682
|
+
[Developer 修复后重新提交审查]
|
|
518
683
|
|
|
519
684
|
重新审查...
|
|
520
685
|
|
|
521
686
|
✅ 代码审查通过
|
|
522
687
|
|
|
523
688
|
📋 审查统计:
|
|
524
|
-
- 审查文件数:
|
|
689
|
+
- 审查文件数:7 个
|
|
525
690
|
- 代码质量:✅ 优秀
|
|
526
691
|
- 安全检查:✅ 无安全问题
|
|
692
|
+
- 接口一致性:✅ 前后端接口匹配
|
|
527
693
|
- 性能审查:✅ 无性能隐患
|
|
528
694
|
- 可维护性:✅ 结构清晰
|
|
529
695
|
|
|
@@ -531,6 +697,7 @@ npm audit
|
|
|
531
697
|
1. 密码使用 bcrypt 加密,安全性强
|
|
532
698
|
2. 数据库查询优化到位,使用了预加载
|
|
533
699
|
3. TypeScript 类型定义完整,类型安全
|
|
700
|
+
4. 前后端接口定义一致,字段名完全匹配
|
|
534
701
|
|
|
535
702
|
下一步请 Tester 进行测试验证。
|
|
536
703
|
```
|