create-vibe-workflow 0.1.0 → 0.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 +248 -57
- package/dist/adapters/next-only/skills.recommend.json +1 -0
- package/dist/adapters/node-api/skills.recommend.json +1 -0
- package/dist/cli.js +163 -5
- package/dist/cli.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +255 -44
- package/dist/generator.js.map +1 -1
- package/dist/questions.d.ts +11 -1
- package/dist/questions.d.ts.map +1 -1
- package/dist/questions.js +103 -16
- package/dist/questions.js.map +1 -1
- package/dist/templates/claude-md/CLAUDE.zh-CN.md +51 -46
- package/dist/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
- package/dist/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
- package/dist/templates/commands/gstack/cso.md.ejs +213 -0
- package/dist/templates/commands/gstack/office-hours.md.ejs +109 -0
- package/dist/templates/commands/gstack/review.md.ejs +192 -0
- package/dist/templates/commands/gstack/ship.md.ejs +256 -0
- package/dist/templates/commands/opsx/apply.md.ejs +106 -0
- package/dist/templates/commands/opsx/archive.md.ejs +88 -0
- package/dist/templates/commands/opsx/explore.md.ejs +84 -0
- package/dist/templates/commands/opsx/propose.md.ejs +185 -0
- package/dist/templates/commands/superpowers/brainstorm.md.ejs +240 -0
- package/dist/templates/commands/superpowers/tdd.md.ejs +230 -0
- package/dist/templates/commands/superpowers/verify.md.ejs +211 -0
- package/dist/templates/commands/workflow/plan.md.ejs +219 -0
- package/dist/templates/hooks/check-deps.mjs +66 -65
- package/dist/templates/memory/.gitkeep +0 -0
- package/dist/templates/memory/MEMORY.md.ejs +88 -0
- package/dist/templates/memory/dev-notes.md.ejs +61 -0
- package/dist/templates/memory/troubleshooting.md.ejs +30 -0
- package/dist/templates/rules/agents.md +49 -49
- package/dist/templates/rules/coding-style.md +156 -117
- package/dist/templates/rules/development-workflow.md +103 -50
- package/dist/templates/rules/git-workflow.md +103 -47
- package/dist/templates/rules/hooks.md +159 -0
- package/dist/templates/rules/hooks.md.ejs +159 -0
- package/dist/templates/rules/memory.md +106 -0
- package/dist/templates/rules/memory.md.ejs +106 -0
- package/dist/templates/rules/patterns.md +117 -48
- package/dist/templates/rules/performance.md +108 -0
- package/dist/templates/rules/performance.md.ejs +108 -0
- package/dist/templates/rules/security.md +52 -37
- package/dist/templates/rules/testing.md +83 -30
- package/dist/templates/settings/settings.template.json +18 -2
- package/dist/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
- package/dist/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
- package/dist/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
- package/dist/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
- package/dist/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
- package/dist/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
- package/dist/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
- package/dist/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
- package/dist/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
- package/dist/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
- package/dist/templates/skills/skill-manifest.json +59 -0
- package/dist/templates/skills/skills-lock.template.json +12 -0
- package/dist/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
- package/dist/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
- package/dist/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
- package/dist/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
- package/dist/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
- package/dist/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
- package/dist/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
- package/dist/utils.d.ts +40 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/package.json +2 -2
- package/templates/claude-md/CLAUDE.zh-CN.md +51 -46
- package/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
- package/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
- package/templates/commands/gstack/cso.md.ejs +213 -0
- package/templates/commands/gstack/office-hours.md.ejs +109 -0
- package/templates/commands/gstack/review.md.ejs +192 -0
- package/templates/commands/gstack/ship.md.ejs +256 -0
- package/templates/commands/opsx/apply.md.ejs +106 -0
- package/templates/commands/opsx/archive.md.ejs +88 -0
- package/templates/commands/opsx/explore.md.ejs +84 -0
- package/templates/commands/opsx/propose.md.ejs +185 -0
- package/templates/commands/superpowers/brainstorm.md.ejs +240 -0
- package/templates/commands/superpowers/tdd.md.ejs +230 -0
- package/templates/commands/superpowers/verify.md.ejs +211 -0
- package/templates/commands/workflow/plan.md.ejs +219 -0
- package/templates/hooks/check-deps.mjs +66 -65
- package/templates/memory/.gitkeep +0 -0
- package/templates/memory/MEMORY.md.ejs +88 -0
- package/templates/memory/dev-notes.md.ejs +61 -0
- package/templates/memory/troubleshooting.md.ejs +30 -0
- package/templates/rules/agents.md +49 -49
- package/templates/rules/coding-style.md +156 -117
- package/templates/rules/development-workflow.md +103 -50
- package/templates/rules/git-workflow.md +103 -47
- package/templates/rules/hooks.md +159 -0
- package/templates/rules/memory.md +106 -0
- package/templates/rules/patterns.md +117 -48
- package/templates/rules/performance.md +108 -0
- package/templates/rules/security.md +52 -37
- package/templates/rules/testing.md +83 -30
- package/templates/settings/settings.template.json +18 -2
- package/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
- package/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
- package/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
- package/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
- package/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
- package/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
- package/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
- package/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
- package/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
- package/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
- package/templates/skills/skill-manifest.json +59 -0
- package/templates/skills/skills-lock.template.json +12 -0
- package/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
- package/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
- package/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
- package/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
- package/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
- package/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
- package/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Improve Codebase Architecture — 代码架构优化
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:代码库变得难以修改、每次改东西都影响多个模块、新需求难以添加时。
|
|
4
|
+
|
|
5
|
+
## 核心理念
|
|
6
|
+
|
|
7
|
+
使用两个概念分析架构健康度:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
【Depth(深度)】— 一个模块的职责有多集中
|
|
11
|
+
浅(Shallow) → 模块做了太多不同的事,没有清晰的抽象
|
|
12
|
+
深(Deep) → 模块封装了复杂逻辑,对外暴露简单接口
|
|
13
|
+
|
|
14
|
+
目标:模块深而窄(内部复杂但接口简单)
|
|
15
|
+
|
|
16
|
+
【Seam(接缝)】— 在不修改代码的情况下改变行为的地方
|
|
17
|
+
好的接缝 → 可以通过配置/注入/参数改变行为
|
|
18
|
+
坏的接缝 → 必须修改代码才能改变行为
|
|
19
|
+
|
|
20
|
+
目标:关键变化点都有清晰的接缝
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 判断方法
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
深度检测:
|
|
27
|
+
问:这个模块的接口有几个方法?
|
|
28
|
+
问:用一个句子能说清这个模块的职责吗?
|
|
29
|
+
问:这个模块隐藏了多少复杂性?
|
|
30
|
+
|
|
31
|
+
如果:
|
|
32
|
+
- 接口方法 > 10 → 可能太浅
|
|
33
|
+
- 一句话说不清职责 → 可能太浅
|
|
34
|
+
- 调用者需要了解实现细节 → 可能太浅
|
|
35
|
+
|
|
36
|
+
接缝检测:
|
|
37
|
+
问:要改变这个行为,需要修改什么文件?
|
|
38
|
+
问:想用 mock 替换这个依赖,需要改代码吗?
|
|
39
|
+
问:添加同类功能要改几个地方?
|
|
40
|
+
|
|
41
|
+
如果:
|
|
42
|
+
- 改行为必须改具体实现文件 → 没有接缝
|
|
43
|
+
- 难以 mock → 没有接缝
|
|
44
|
+
- 加同类功能要改 N 个文件(N > 1)→ 没有接缝
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 重构优先级矩阵
|
|
48
|
+
|
|
49
|
+
| 对业务影响 | 架构问题严重 | 架构问题轻微 |
|
|
50
|
+
|-----------|------------|------------|
|
|
51
|
+
| **变更频繁** | **立即重构(P0)** | **计划重构** |
|
|
52
|
+
| **变更稀少** | 监控,等变更时再重构 | 忽略 |
|
|
53
|
+
|
|
54
|
+
### 优先级说明
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
P0 — 立即重构
|
|
58
|
+
症状:
|
|
59
|
+
- 每次改这个功能都很痛苦
|
|
60
|
+
- 频繁出现 Bug
|
|
61
|
+
- 修改一处需要同步改多处
|
|
62
|
+
|
|
63
|
+
做法:
|
|
64
|
+
- 提取清晰抽象
|
|
65
|
+
- 建立接缝
|
|
66
|
+
- 写测试固定行为
|
|
67
|
+
|
|
68
|
+
P1 — 计划重构
|
|
69
|
+
症状:
|
|
70
|
+
- 代码难以理解但暂时不改
|
|
71
|
+
- 测试写起来费劲
|
|
72
|
+
|
|
73
|
+
做法:
|
|
74
|
+
- 在 todolist 中加入重构任务
|
|
75
|
+
- 等有相关需求时顺便重构
|
|
76
|
+
|
|
77
|
+
P2 — 监控
|
|
78
|
+
症状:
|
|
79
|
+
- 代码不够理想但很少改
|
|
80
|
+
- 没有实际的痛苦
|
|
81
|
+
|
|
82
|
+
做法:
|
|
83
|
+
- 不做主动重构
|
|
84
|
+
- 下次改时评估是否需要重构
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 常见架构问题及修复
|
|
88
|
+
|
|
89
|
+
### 上帝对象(God Object)
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
症状:
|
|
93
|
+
- 一个模块/类/文件 > 800 行
|
|
94
|
+
- 一个模块做了多件事
|
|
95
|
+
- 团队所有人都在改同一个模块
|
|
96
|
+
|
|
97
|
+
修复:
|
|
98
|
+
1. 识别出独立的职责
|
|
99
|
+
2. 逐个提取为新模块
|
|
100
|
+
3. 原模块只做编排
|
|
101
|
+
4. 每个新模块有自己的测试
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 循环依赖
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
症状:
|
|
108
|
+
- A → B → A (直接或间接)
|
|
109
|
+
- 初始化时需要特殊顺序
|
|
110
|
+
- 修改 A 导致 B 异常
|
|
111
|
+
|
|
112
|
+
修复:
|
|
113
|
+
1. 提取共用的部分为第三个模块
|
|
114
|
+
2. 或使用依赖倒置(接口定义在调用方)
|
|
115
|
+
3. 或引入事件机制解耦
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 隐式依赖
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
症状:
|
|
122
|
+
- 需要按特定顺序调用方法
|
|
123
|
+
- 依赖全局/单例状态
|
|
124
|
+
- 构造函数做了大量初始化
|
|
125
|
+
|
|
126
|
+
修复:
|
|
127
|
+
1. 显式参数化依赖
|
|
128
|
+
2. 依赖注入(构造函数参数)
|
|
129
|
+
3. 消除隐式的"必须按顺序调用"的约束
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 散弹式修改(Shotgun Surgery)
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
症状:
|
|
136
|
+
- 改一个需求需要改 N 个文件(N > 3)
|
|
137
|
+
- 改完后总有一两个文件忘记改
|
|
138
|
+
|
|
139
|
+
修复:
|
|
140
|
+
1. 识别变化的原因
|
|
141
|
+
2. 使用策略模式、钩子或配置集中变化点
|
|
142
|
+
3. 新加同类功能不用改已有代码(开闭原则)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 优化流程
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
1. 识别痛点
|
|
149
|
+
- 哪些模块改起来最痛苦?
|
|
150
|
+
- 团队抱怨最多的是什么?
|
|
151
|
+
- 测试最难写的是什么?
|
|
152
|
+
|
|
153
|
+
2. 分析根因
|
|
154
|
+
- 使用 Depth/Seam 分析
|
|
155
|
+
- 识别违反了什么原则
|
|
156
|
+
|
|
157
|
+
3. 制定方案
|
|
158
|
+
- 提取接口
|
|
159
|
+
- 拆分职责
|
|
160
|
+
- 集中变化点
|
|
161
|
+
- 消除隐式依赖
|
|
162
|
+
|
|
163
|
+
4. 分步实施
|
|
164
|
+
- 先加测试(固定当前行为)
|
|
165
|
+
- 小步重构(每次只提取一个职责)
|
|
166
|
+
- 每个步骤都保持可运行
|
|
167
|
+
|
|
168
|
+
5. 验证
|
|
169
|
+
- 所有测试通过
|
|
170
|
+
- 行为不变
|
|
171
|
+
- 新需求实现起来更顺畅
|
|
172
|
+
```
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Backend Patterns — 后端开发模式
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:设计 API、实现业务逻辑、组织服务层代码时。
|
|
4
|
+
|
|
5
|
+
## API 设计模式
|
|
6
|
+
|
|
7
|
+
### RESTful 命名规范
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
资源命名(名词复数):
|
|
11
|
+
GET /resources → 列表
|
|
12
|
+
GET /resources/:id → 详情
|
|
13
|
+
POST /resources → 创建
|
|
14
|
+
PUT /resources/:id → 全量更新
|
|
15
|
+
PATCH /resources/:id → 部分更新
|
|
16
|
+
DELETE /resources/:id → 删除
|
|
17
|
+
|
|
18
|
+
子资源:
|
|
19
|
+
GET /resources/:id/sub-resources
|
|
20
|
+
POST /resources/:id/sub-resources
|
|
21
|
+
|
|
22
|
+
动作(非 CRUD):
|
|
23
|
+
POST /resources/:id/{action} → 如 archive、approve
|
|
24
|
+
|
|
25
|
+
筛选/排序/分页(查询参数):
|
|
26
|
+
GET /resources?status=active&sort=-createdAt&page=1&limit=20
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 统一响应格式
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
成功响应:
|
|
33
|
+
{
|
|
34
|
+
"success": true,
|
|
35
|
+
"data": { ... },
|
|
36
|
+
"error": null,
|
|
37
|
+
"meta": { // 分页时
|
|
38
|
+
"total": 100,
|
|
39
|
+
"page": 1,
|
|
40
|
+
"limit": 20
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
错误响应:
|
|
45
|
+
{
|
|
46
|
+
"success": false,
|
|
47
|
+
"data": null,
|
|
48
|
+
"error": {
|
|
49
|
+
"code": "VALIDATION_ERROR",
|
|
50
|
+
"message": "用户友好的错误描述",
|
|
51
|
+
"details": [ // 验证错误时包含字段级错误
|
|
52
|
+
{ "field": "email", "message": "邮箱格式不正确" }
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### HTTP 状态码使用
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
200 — 成功(GET、PATCH)
|
|
62
|
+
201 — 创建成功(POST)
|
|
63
|
+
204 — 无内容(DELETE)
|
|
64
|
+
400 — 请求参数错误(验证失败)
|
|
65
|
+
401 — 未认证
|
|
66
|
+
403 — 无权限
|
|
67
|
+
404 — 资源不存在
|
|
68
|
+
409 — 冲突(如重复创建)
|
|
69
|
+
422 — 业务逻辑错误
|
|
70
|
+
429 — 请求过频(限流)
|
|
71
|
+
500 — 服务器内部错误
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 仓储模式(Repository Pattern)
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
作用:将数据访问逻辑与业务逻辑分离
|
|
78
|
+
|
|
79
|
+
结构:
|
|
80
|
+
[接口层] I{Entity}Repository
|
|
81
|
+
- findAll(filter, sort, page)
|
|
82
|
+
- findById(id)
|
|
83
|
+
- create(data)
|
|
84
|
+
- update(id, data)
|
|
85
|
+
- delete(id)
|
|
86
|
+
|
|
87
|
+
[实现层] {Entity}Repository
|
|
88
|
+
- 具体的数据访问实现(数据库/API/文件)
|
|
89
|
+
- 接口与实现一一对应
|
|
90
|
+
|
|
91
|
+
[业务层] {Entity}Service
|
|
92
|
+
- 只依赖接口,不依赖具体实现
|
|
93
|
+
- 测试时替换为 mock 实现
|
|
94
|
+
|
|
95
|
+
规则:
|
|
96
|
+
- 仓储方法名用领域语言(如 `findActiveUsers` 而非 `findByStatus`)
|
|
97
|
+
- 仓储返回领域对象,不返回数据行
|
|
98
|
+
- 业务层不拼 SQL / 查询语句
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 服务层模式(Service Layer)
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
作用:编排业务逻辑,协调多个仓储和外部服务
|
|
105
|
+
|
|
106
|
+
职责:
|
|
107
|
+
- 业务规则验证
|
|
108
|
+
- 事务管理(跨仓储操作)
|
|
109
|
+
- 外部服务调用编排
|
|
110
|
+
- 事件发布/消息发送
|
|
111
|
+
- 缓存管理
|
|
112
|
+
|
|
113
|
+
不做的:
|
|
114
|
+
- 不处理 HTTP 请求/响应
|
|
115
|
+
- 不直接暴露给外部
|
|
116
|
+
|
|
117
|
+
典型结构:
|
|
118
|
+
Service {
|
|
119
|
+
constructor(repositories, services, events) {
|
|
120
|
+
// 依赖注入
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async create(input) {
|
|
124
|
+
// 1. 校验业务规则
|
|
125
|
+
// 2. 写入数据库(可跨多个仓储)
|
|
126
|
+
// 3. 发送事件
|
|
127
|
+
// 4. 返回结果
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 中间件模式(Middleware Pattern)
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
请求处理管道:
|
|
136
|
+
Request → [Middleware 1] → [Middleware 2] → ... → [Handler]
|
|
137
|
+
|
|
138
|
+
常见中间件(按顺序):
|
|
139
|
+
1. 请求日志(Request Logging)
|
|
140
|
+
2. 安全头(Security Headers)
|
|
141
|
+
3. CORS
|
|
142
|
+
4. 请求体解析(Body Parser)
|
|
143
|
+
5. 认证(Authentication)
|
|
144
|
+
6. 授权(Authorization)
|
|
145
|
+
7. 限流(Rate Limiting)
|
|
146
|
+
8. 请求验证(Request Validation)
|
|
147
|
+
9. 响应转换(Response Transform)
|
|
148
|
+
|
|
149
|
+
中间件规则:
|
|
150
|
+
- 每个中间件只做一件事
|
|
151
|
+
- 可配置(通过工厂函数)
|
|
152
|
+
- 执行完毕后调用 next()
|
|
153
|
+
- 错误中间件四个参数(err, req, res, next)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 错误处理模式
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
统一错误层次:
|
|
160
|
+
|
|
161
|
+
基类 AppError
|
|
162
|
+
├── ValidationError — 输入验证失败
|
|
163
|
+
├── AuthenticationError — 认证失败(401)
|
|
164
|
+
├── AuthorizationError — 权限不足(403)
|
|
165
|
+
├── NotFoundError — 资源不存在(404)
|
|
166
|
+
├── ConflictError — 冲突(409)
|
|
167
|
+
└── InternalError — 内部错误(500)
|
|
168
|
+
|
|
169
|
+
全局错误处理中间件:
|
|
170
|
+
try {
|
|
171
|
+
await handler(req, res)
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error instanceof AppError) {
|
|
174
|
+
// 已知错误 → 返回对应的状态码和消息
|
|
175
|
+
} else {
|
|
176
|
+
// 未知错误 → 记录日志,返回 500
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 认证与授权模式
|
|
182
|
+
|
|
183
|
+
### JWT 认证流程
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
登录:
|
|
187
|
+
1. 验证凭据(用户名/密码等)
|
|
188
|
+
2. 生成 Access Token(短期,15-60 分钟)
|
|
189
|
+
3. 生成 Refresh Token(长期,7-30 天)
|
|
190
|
+
4. 返回双 Token
|
|
191
|
+
|
|
192
|
+
验证:
|
|
193
|
+
1. 从请求头提取 Token(Authorization: Bearer <token>)
|
|
194
|
+
2. 验证签名和过期时间
|
|
195
|
+
3. 提取用户信息
|
|
196
|
+
4. 注入请求上下文
|
|
197
|
+
|
|
198
|
+
刷新:
|
|
199
|
+
1. 验证 Refresh Token
|
|
200
|
+
2. 生成新的 Access Token
|
|
201
|
+
3. 可选:轮换 Refresh Token
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### RBAC 权限模型
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
角色 → 权限 → 资源
|
|
208
|
+
|
|
209
|
+
结构:
|
|
210
|
+
User → Role → Permission → Resource:Action
|
|
211
|
+
|
|
212
|
+
示例:
|
|
213
|
+
"管理员" → "user:read", "user:write" → "用户模块"
|
|
214
|
+
|
|
215
|
+
检查流程:
|
|
216
|
+
1. 获取用户角色
|
|
217
|
+
2. 获取角色关联的权限列表
|
|
218
|
+
3. 检查当前请求的 {资源:动作} 是否在权限列表中
|
|
219
|
+
4. 通过/拒绝
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 缓存模式
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
Cache-Aside(旁路缓存):
|
|
226
|
+
读:先查缓存 → 命中返回 / 未命中查 DB → 写入缓存 → 返回
|
|
227
|
+
写:先写 DB → 使缓存失效 / 更新缓存
|
|
228
|
+
|
|
229
|
+
缓存失效策略:
|
|
230
|
+
- 基于时间(TTL)
|
|
231
|
+
- 基于事件(数据变更时主动失效)
|
|
232
|
+
- 基于版本(数据带版本号,版本变化时重新加载)
|
|
233
|
+
|
|
234
|
+
什么该缓存:
|
|
235
|
+
- 频繁读取不频繁修改的数据
|
|
236
|
+
- 计算开销大的结果
|
|
237
|
+
- 聚合/统计结果
|
|
238
|
+
|
|
239
|
+
什么不该缓存:
|
|
240
|
+
- 实时性要求极高的数据
|
|
241
|
+
- 频繁变化的数据(缓存命中率低)
|
|
242
|
+
- 用户敏感的私有数据(除非小心处理)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## 后台任务模式
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
适用场景:
|
|
249
|
+
耗时操作(文件处理、邮件发送)
|
|
250
|
+
定时任务(报表生成、数据清理)
|
|
251
|
+
异步消息(事件驱动处理)
|
|
252
|
+
|
|
253
|
+
方案:
|
|
254
|
+
- 轻量级:内存队列 + Worker
|
|
255
|
+
- 生产级:消息队列(如 RabbitMQ、Redis Streams)
|
|
256
|
+
- 定时任务:Cron/Scheduler
|
|
257
|
+
|
|
258
|
+
设计要点:
|
|
259
|
+
- 任务可重试(幂等性)
|
|
260
|
+
- 失败有死信队列
|
|
261
|
+
- 有监控和告警
|
|
262
|
+
- 不影响主请求路径
|
|
263
|
+
```
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Database Migrations — 数据库迁移模式
|
|
2
|
+
|
|
3
|
+
> 使用此 skill 时:设计数据模型变更、安排迁移执行、处理回滚时。
|
|
4
|
+
|
|
5
|
+
## 安全变更原则
|
|
6
|
+
|
|
7
|
+
### 黄金法则
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
1. 每次迁移可回滚(有 up 必有 down)
|
|
11
|
+
2. 迁移不破坏已有数据
|
|
12
|
+
3. 兼容性先行(旧代码 + 新模式 能正常工作)
|
|
13
|
+
4. 不阻塞读写(生产环境零停机)
|
|
14
|
+
5. 小步提交(一个迁移只做一件事)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 变更影响评估
|
|
18
|
+
|
|
19
|
+
每次迁移前评估:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
[ ] 新字段是否可为 NULL?(旧数据不需要回填)
|
|
23
|
+
[ ] 添加 NOT NULL 字段前是否已回填数据?
|
|
24
|
+
[ ] 重命名列是否会中断正在运行的应用?
|
|
25
|
+
[ ] 修改列类型是否需要显式 CAST?
|
|
26
|
+
[ ] 删除列/表是否确认没有引用?
|
|
27
|
+
[ ] 添加索引是否会长时间锁表?
|
|
28
|
+
[ ] 大数据表操作是否有性能影响预估?
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 零停机迁移模式
|
|
32
|
+
|
|
33
|
+
### 安全模式:三段式迁移
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
场景:重构一个表(拆分字段、修改类型)
|
|
37
|
+
|
|
38
|
+
阶段一:添加(向前兼容)
|
|
39
|
+
1. 添加新列(可为 NULL)
|
|
40
|
+
2. 启动双写(新旧列都写入)
|
|
41
|
+
3. 回填旧数据到新列
|
|
42
|
+
|
|
43
|
+
阶段二:切换(应用层切换)
|
|
44
|
+
1. 部署新版本,应用读取新列
|
|
45
|
+
2. 确认稳定后停用旧列读取
|
|
46
|
+
3. 停止双写
|
|
47
|
+
|
|
48
|
+
阶段三:清理
|
|
49
|
+
1. 验证新列数据完整
|
|
50
|
+
2. 删除旧列
|
|
51
|
+
3. 清理不再使用的索引
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 大表索引创建
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
CREATE INDEX CONCURRENTLY — 不阻塞写入
|
|
58
|
+
适用于:生产环境、大表
|
|
59
|
+
|
|
60
|
+
CREATE INDEX CONCURRENTLY idx_name ON table(column);
|
|
61
|
+
-- 然后:ALTER TABLE ... 关联索引
|
|
62
|
+
|
|
63
|
+
注意:
|
|
64
|
+
- 耗时更长(两阶段构建)
|
|
65
|
+
- 如果失败需要清理(DROP INDEX)
|
|
66
|
+
- 不能在事务中执行
|
|
67
|
+
|
|
68
|
+
DROP INDEX CONCURRENTLY — 不阻塞写入
|
|
69
|
+
DROP INDEX CONCURRENTLY idx_name
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 修改列类型
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
安全做法:
|
|
76
|
+
1. 添加新列(可为 NULL)
|
|
77
|
+
2. 双写(应用层同时维护新旧列)
|
|
78
|
+
3. 回填旧数据
|
|
79
|
+
4. 切换读取到新列
|
|
80
|
+
5. 验证通过后删除旧列
|
|
81
|
+
|
|
82
|
+
直接修改的替代:
|
|
83
|
+
ALTER TABLE ... ALTER COLUMN ... TYPE ... USING ...
|
|
84
|
+
但会锁表和重写整表!
|
|
85
|
+
|
|
86
|
+
除非是 VARCHAR(n) 增加长度等不影响存储格式的修改。
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 迁移文件规范
|
|
90
|
+
|
|
91
|
+
### 命名规则
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
格式:{YYYYMMDD}_{HHMM}_{描述}.{ext}
|
|
95
|
+
|
|
96
|
+
示例:
|
|
97
|
+
20250401_0001_create_users.{ext}
|
|
98
|
+
20250402_0830_add_email_to_users.{ext}
|
|
99
|
+
20250403_1200_create_orders_index.{ext}
|
|
100
|
+
|
|
101
|
+
描述规则:
|
|
102
|
+
- 动词开头:create、add、alter、rename、drop
|
|
103
|
+
- 小写 + 下划线
|
|
104
|
+
- 15-50 字符
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 迁移文件模板
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
-- up: 正向迁移
|
|
111
|
+
-- 描述:添加 email 字段到 users 表
|
|
112
|
+
|
|
113
|
+
ALTER TABLE users
|
|
114
|
+
ADD COLUMN email text;
|
|
115
|
+
|
|
116
|
+
-- 注意:email 字段可为 NULL,旧数据不需要处理
|
|
117
|
+
|
|
118
|
+
-- down: 回滚迁移
|
|
119
|
+
ALTER TABLE users
|
|
120
|
+
DROP COLUMN IF EXISTS email;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Seed 数据 vs 迁移数据
|
|
124
|
+
|
|
125
|
+
| 类型 | 用途 | 说明 |
|
|
126
|
+
|------|------|------|
|
|
127
|
+
| **Seed 数据** | 开发/测试环境基础数据 | 角色、权限、配置项、演示数据 |
|
|
128
|
+
| **迁移数据** | 生产环境数据转换 | 数据回填、格式转换、数据清洗 |
|
|
129
|
+
|
|
130
|
+
### Seed 数据规范
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
特点:
|
|
134
|
+
- 可重复运行(幂等)
|
|
135
|
+
- 只在开发/测试环境运行
|
|
136
|
+
- 不包含生产敏感数据
|
|
137
|
+
|
|
138
|
+
常见内容:
|
|
139
|
+
- 管理员账号(开发用)
|
|
140
|
+
- 角色/权限数据
|
|
141
|
+
- 配置项
|
|
142
|
+
- 演示用的示例数据
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 迁移数据规范
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
特点:
|
|
149
|
+
- 只运行一次(和迁移绑定)
|
|
150
|
+
- 在应用代码部署前运行
|
|
151
|
+
- 必须可回滚
|
|
152
|
+
|
|
153
|
+
常见内容:
|
|
154
|
+
- 新字段的默认值回填
|
|
155
|
+
- 数据格式转换
|
|
156
|
+
- 数据去重/清洗
|
|
157
|
+
- 表拆分/合并的数据迁移
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 回滚策略
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
自动回滚:
|
|
164
|
+
- 每个迁移有对应的 down 脚本
|
|
165
|
+
- 回滚按时间逆序执行
|
|
166
|
+
|
|
167
|
+
手动回滚:
|
|
168
|
+
- 确认当前版本 → 执行逆序迁移
|
|
169
|
+
- 验证数据完整性
|
|
170
|
+
- 更新迁移跟踪表
|
|
171
|
+
|
|
172
|
+
回滚注意事项:
|
|
173
|
+
- 回滚会丢失数据(新增列的内容、转换后的数据)
|
|
174
|
+
- 回滚前确认应用版本也回退了
|
|
175
|
+
- 大数据表回滚可能耗时较长
|
|
176
|
+
- 有依赖的迁移(外键、视图)需按依赖顺序回滚
|
|
177
|
+
|
|
178
|
+
灾难恢复:
|
|
179
|
+
- 保留回滚前的数据库快照(pg_dump)
|
|
180
|
+
- 先恢复快照,再执行迁移
|
|
181
|
+
- 验证数据完整性后切换
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 迁移运行策略
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
CI/CD 集成:
|
|
188
|
+
- 部署流水线包含迁移步骤
|
|
189
|
+
- 自动执行未运行的迁移
|
|
190
|
+
- 迁移失败阻断后续部署
|
|
191
|
+
|
|
192
|
+
生产环境操作:
|
|
193
|
+
- 非工作时间执行
|
|
194
|
+
- 执行前备份数据库
|
|
195
|
+
- 监控数据库性能(慢查询、锁等待)
|
|
196
|
+
- 准备回滚方案
|
|
197
|
+
|
|
198
|
+
迁移跟踪表:
|
|
199
|
+
自动维护(通常由迁移库管理)
|
|
200
|
+
schema_migrations / _migrations
|
|
201
|
+
记录:版本号、文件名、执行时间、校验和
|
|
202
|
+
```
|