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.
Files changed (120) hide show
  1. package/README.md +248 -57
  2. package/dist/adapters/next-only/skills.recommend.json +1 -0
  3. package/dist/adapters/node-api/skills.recommend.json +1 -0
  4. package/dist/cli.js +163 -5
  5. package/dist/cli.js.map +1 -1
  6. package/dist/generator.d.ts.map +1 -1
  7. package/dist/generator.js +255 -44
  8. package/dist/generator.js.map +1 -1
  9. package/dist/questions.d.ts +11 -1
  10. package/dist/questions.d.ts.map +1 -1
  11. package/dist/questions.js +103 -16
  12. package/dist/questions.js.map +1 -1
  13. package/dist/templates/claude-md/CLAUDE.zh-CN.md +51 -46
  14. package/dist/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
  15. package/dist/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
  16. package/dist/templates/commands/gstack/cso.md.ejs +213 -0
  17. package/dist/templates/commands/gstack/office-hours.md.ejs +109 -0
  18. package/dist/templates/commands/gstack/review.md.ejs +192 -0
  19. package/dist/templates/commands/gstack/ship.md.ejs +256 -0
  20. package/dist/templates/commands/opsx/apply.md.ejs +106 -0
  21. package/dist/templates/commands/opsx/archive.md.ejs +88 -0
  22. package/dist/templates/commands/opsx/explore.md.ejs +84 -0
  23. package/dist/templates/commands/opsx/propose.md.ejs +185 -0
  24. package/dist/templates/commands/superpowers/brainstorm.md.ejs +240 -0
  25. package/dist/templates/commands/superpowers/tdd.md.ejs +230 -0
  26. package/dist/templates/commands/superpowers/verify.md.ejs +211 -0
  27. package/dist/templates/commands/workflow/plan.md.ejs +219 -0
  28. package/dist/templates/hooks/check-deps.mjs +66 -65
  29. package/dist/templates/memory/.gitkeep +0 -0
  30. package/dist/templates/memory/MEMORY.md.ejs +88 -0
  31. package/dist/templates/memory/dev-notes.md.ejs +61 -0
  32. package/dist/templates/memory/troubleshooting.md.ejs +30 -0
  33. package/dist/templates/rules/agents.md +49 -49
  34. package/dist/templates/rules/coding-style.md +156 -117
  35. package/dist/templates/rules/development-workflow.md +103 -50
  36. package/dist/templates/rules/git-workflow.md +103 -47
  37. package/dist/templates/rules/hooks.md +159 -0
  38. package/dist/templates/rules/hooks.md.ejs +159 -0
  39. package/dist/templates/rules/memory.md +106 -0
  40. package/dist/templates/rules/memory.md.ejs +106 -0
  41. package/dist/templates/rules/patterns.md +117 -48
  42. package/dist/templates/rules/performance.md +108 -0
  43. package/dist/templates/rules/performance.md.ejs +108 -0
  44. package/dist/templates/rules/security.md +52 -37
  45. package/dist/templates/rules/testing.md +83 -30
  46. package/dist/templates/settings/settings.template.json +18 -2
  47. package/dist/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
  48. package/dist/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
  49. package/dist/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
  50. package/dist/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
  51. package/dist/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
  52. package/dist/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
  53. package/dist/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
  54. package/dist/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
  55. package/dist/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
  56. package/dist/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
  57. package/dist/templates/skills/skill-manifest.json +59 -0
  58. package/dist/templates/skills/skills-lock.template.json +12 -0
  59. package/dist/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
  60. package/dist/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
  61. package/dist/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
  62. package/dist/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
  63. package/dist/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
  64. package/dist/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
  65. package/dist/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
  66. package/dist/utils.d.ts +40 -0
  67. package/dist/utils.d.ts.map +1 -0
  68. package/dist/utils.js +110 -0
  69. package/dist/utils.js.map +1 -0
  70. package/package.json +2 -2
  71. package/templates/claude-md/CLAUDE.zh-CN.md +51 -46
  72. package/templates/claude-md/next-only/CLAUDE.zh-CN.md +46 -0
  73. package/templates/claude-md/node-api/CLAUDE.zh-CN.md +47 -0
  74. package/templates/commands/gstack/cso.md.ejs +213 -0
  75. package/templates/commands/gstack/office-hours.md.ejs +109 -0
  76. package/templates/commands/gstack/review.md.ejs +192 -0
  77. package/templates/commands/gstack/ship.md.ejs +256 -0
  78. package/templates/commands/opsx/apply.md.ejs +106 -0
  79. package/templates/commands/opsx/archive.md.ejs +88 -0
  80. package/templates/commands/opsx/explore.md.ejs +84 -0
  81. package/templates/commands/opsx/propose.md.ejs +185 -0
  82. package/templates/commands/superpowers/brainstorm.md.ejs +240 -0
  83. package/templates/commands/superpowers/tdd.md.ejs +230 -0
  84. package/templates/commands/superpowers/verify.md.ejs +211 -0
  85. package/templates/commands/workflow/plan.md.ejs +219 -0
  86. package/templates/hooks/check-deps.mjs +66 -65
  87. package/templates/memory/.gitkeep +0 -0
  88. package/templates/memory/MEMORY.md.ejs +88 -0
  89. package/templates/memory/dev-notes.md.ejs +61 -0
  90. package/templates/memory/troubleshooting.md.ejs +30 -0
  91. package/templates/rules/agents.md +49 -49
  92. package/templates/rules/coding-style.md +156 -117
  93. package/templates/rules/development-workflow.md +103 -50
  94. package/templates/rules/git-workflow.md +103 -47
  95. package/templates/rules/hooks.md +159 -0
  96. package/templates/rules/memory.md +106 -0
  97. package/templates/rules/patterns.md +117 -48
  98. package/templates/rules/performance.md +108 -0
  99. package/templates/rules/security.md +52 -37
  100. package/templates/rules/testing.md +83 -30
  101. package/templates/settings/settings.template.json +18 -2
  102. package/templates/skills/advanced/caveman/SKILL.md.ejs +144 -0
  103. package/templates/skills/advanced/diagnose/SKILL.md.ejs +159 -0
  104. package/templates/skills/advanced/grill-with-docs/SKILL.md.ejs +154 -0
  105. package/templates/skills/advanced/improve-codebase-architecture/SKILL.md.ejs +172 -0
  106. package/templates/skills/backend/backend-patterns/SKILL.md.ejs +263 -0
  107. package/templates/skills/database/database-migrations/SKILL.md.ejs +202 -0
  108. package/templates/skills/database/postgres-patterns/SKILL.md.ejs +235 -0
  109. package/templates/skills/devops/deployment-patterns/SKILL.md.ejs +228 -0
  110. package/templates/skills/devops/docker-patterns/SKILL.md.ejs +215 -0
  111. package/templates/skills/frontend/frontend-patterns/SKILL.md.ejs +195 -0
  112. package/templates/skills/skill-manifest.json +59 -0
  113. package/templates/skills/skills-lock.template.json +12 -0
  114. package/templates/skills/testing/e2e-testing/SKILL.md.ejs +224 -0
  115. package/templates/skills/workflow/coding-standards/SKILL.md.ejs +143 -0
  116. package/templates/skills/workflow/search-first/SKILL.md.ejs +103 -0
  117. package/templates/skills/workflow/security-review/SKILL.md.ejs +146 -0
  118. package/templates/skills/workflow/strategic-compact/SKILL.md.ejs +108 -0
  119. package/templates/skills/workflow/tdd-workflow/SKILL.md.ejs +104 -0
  120. package/templates/skills/workflow/verification-loop/SKILL.md.ejs +144 -0
@@ -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
+ ```
@@ -0,0 +1,235 @@
1
+ # PostgreSQL Patterns — PostgreSQL 数据库模式
2
+
3
+ > 使用此 skill 时:设计表结构、编写查询、优化数据库性能时。
4
+
5
+ ## 索引策略
6
+
7
+ ### 索引类型选择
8
+
9
+ ```text
10
+ B-Tree(默认):
11
+ 适用:等值查询、范围查询、排序
12
+ 不适用:全文搜索、数组包含
13
+
14
+ Hash:
15
+ 适用:等值查询(性能略高于 B-Tree)
16
+ 不适用:范围查询、排序
17
+ 注意:不记录大小,重建时需 REINDEX
18
+
19
+ GiST:
20
+ 适用:全文搜索、地理空间、范围重叠
21
+ 示例:tsvector、geometry、timerange
22
+
23
+ GIN:
24
+ 适用:包含查询(数组、JSONB、全文搜索)
25
+ 示例:JSONB 的 @> 操作符、数组的 @> 操作符
26
+
27
+ BRIN:
28
+ 适用:与物理存储顺序相关的大表(如时间序列)
29
+ 优点:索引体积极小
30
+ 注意:数据插入顺序须与索引列顺序接近
31
+ ```
32
+
33
+ ### 索引设计检查清单
34
+
35
+ ```text
36
+ 是否真正需要?
37
+ [ ] 这个查询是频繁执行的吗?
38
+ [ ] 表大到不用索引会慢吗?(<1000 行不需要)
39
+ [ ] 这个查询会随着数据增长变慢吗?
40
+
41
+ 索引列选择:
42
+ [ ] WHERE 子句中的列优先
43
+ [ ] JOIN 的关联列必须索引
44
+ [ ] ORDER BY 的列考虑包含在索引中
45
+ [ ] 高选择性的列优先(唯一值多)
46
+
47
+ 避免过度索引:
48
+ [ ] 不要为低频查询建索引
49
+ [ ] 不要重复索引(复合索引的前缀列不需要单独索引)
50
+ [ ] 写密集的表索引尽量少(每个索引增加写入开销)
51
+ [ ] 定期用 pg_stat_user_indexes 检查未使用索引
52
+
53
+ 复合索引:
54
+ [ ] = 条件的列放前面
55
+ [ ] 范围条件的列放后面
56
+ [ ] 查询条件中有多个 = 列时,任意顺序均可
57
+ [ ] 考虑 INCLUDE 列(覆盖索引)
58
+ ```
59
+
60
+ ## 数据类型选择
61
+
62
+ ```text
63
+ 【数值型】
64
+ 整数:
65
+ smallint (2B, ±32K) → 枚举/状态码
66
+ integer (4B, ±2B) → 默认选择
67
+ bigint (8B) → 自增 ID 超 2B 时
68
+
69
+ 小数:
70
+ numeric(p,s) → 精确计算(金额)
71
+ double precision → 科学计算(允许小误差)
72
+
73
+ 【文本型】
74
+ text → 没有长度限制,性能与 varchar 相同
75
+ varchar(n) → 有长度约束时(如邮箱限制 254 字符)
76
+ citext → 不区分大小写的文本(扩展)
77
+
78
+ 选择规则:默认用 text,需要约束长度时用 varchar(n)
79
+
80
+ 【时间型】
81
+ timestamptz → 首选(带时区,存储为 UTC)
82
+ timestamp → 不需要时区时
83
+ date → 只需要日期时
84
+ time → 只需要时间时
85
+ interval → 时间间隔
86
+
87
+ 【JSON vs JSONB】
88
+ json → 只存不查(保留原格式、键顺序)
89
+ jsonb → 需要查询/索引(二进制格式,去重键)
90
+
91
+ 总结:90% 场景用 jsonb,只有日志归档等只存不查场景用 json
92
+
93
+ 【数组】
94
+ 适用:标签、分类等有限集合
95
+ 注意:数组查询不能利用普通 B-Tree 索引(需 GIN)
96
+ ```
97
+
98
+ ## 查询优化
99
+
100
+ ### N+1 查询检测
101
+
102
+ ```text
103
+ 症状:一次查询后循环内执行 N 次查询
104
+
105
+ 识别:
106
+ - 日志中出现大量相似查询
107
+ - 翻页/列表接口慢
108
+
109
+ // ❌ N+1
110
+ for each user {
111
+ query("SELECT * FROM orders WHERE user_id = ?", user.id)
112
+ }
113
+
114
+ // ✅ 批量查询
115
+ userIds = users.map(u => u.id)
116
+ orders = query("SELECT * FROM orders WHERE user_id = ANY(?)", [userIds])
117
+ // 在应用层关联
118
+ ```
119
+
120
+ ### JOIN vs 子查询
121
+
122
+ ```text
123
+ 【优先 JOIN】
124
+ 适用:
125
+ - 需要返回父表和子表的列
126
+ - 关联表行数不多
127
+
128
+ 注意:
129
+ - JOIN 的表都应有索引
130
+ - 避免大表的 CROSS JOIN
131
+
132
+ 【子查询(EXISTS)】
133
+ 适用:
134
+ - 只需要检查是否存在
135
+ - 关联条件是聚合结果
136
+
137
+ 注意:
138
+ - EXISTS 找到第一条即停止,比 IN 快
139
+ - NOT EXISTS 比 NOT IN 安全(NOT IN 遇到 NULL 行为异常)
140
+
141
+ 总结:
142
+ 90% 的关联查询用 JOIN
143
+ 存在性检查用 EXISTS
144
+ 聚合子查询用 CTE 或 LATERAL JOIN
145
+ ```
146
+
147
+ ### 分页策略
148
+
149
+ ```text
150
+ 【OFFSET/LIMIT】— 简单但大偏移量慢
151
+ 适用:小数据集、前几页
152
+ 问题:OFFSET 越大越慢(需要扫描并丢弃前面的行)
153
+
154
+ 优化:用复合索引 + 覆盖索引减轻
155
+
156
+ 【游标分页(Keyset Pagination)】— 大数据集推荐
157
+ 适用:无限滚动、实时数据
158
+ 原理:用 WHERE 条件代替 OFFSET
159
+
160
+ SELECT * FROM users
161
+ WHERE createdAt < :lastCreatedAt OR (createdAt = :lastCreatedAt AND id < :lastId)
162
+ ORDER BY createdAt DESC, id DESC
163
+ LIMIT 20
164
+
165
+ 优点:无论翻到第几页,性能恒定
166
+ 缺点:不能直接跳转到特定页
167
+ ```
168
+
169
+ ### EXPLAIN 分析
170
+
171
+ ```text
172
+ EXPLAIN ANALYZE {query};
173
+
174
+ 关键指标:
175
+ - seq scan → 考虑加索引
176
+ - rows 估算偏差大 → 更新统计信息(ANALYZE)
177
+ - actual time 大 → 确认瓶颈
178
+
179
+ 常见问题:
180
+ - 类型不匹配导致隐式转换 → 索引失效
181
+ - OR 条件 → 考虑 UNION ALL
182
+ - IN 子句大量值 → 考虑临时表或 ANY
183
+ ```
184
+
185
+ ## 约束与数据完整性
186
+
187
+ ```text
188
+ NOT NULL — 默认用,除非真有理由允许 NULL
189
+ UNIQUE — 保证业务唯一性(用户名、邮箱)
190
+ CHECK — 业务规则(age > 0, status IN ('a','b','c'))
191
+ FOREIGN KEY — 引用完整性(注意:会加锁)
192
+ EXCLUDE — 排他约束(时间范围不重叠)
193
+
194
+ 注意:
195
+ - 外键约束创建和维护有开销
196
+ - 批量导入时可先禁用约束,导入后重建验证
197
+ - CHECK 约束比应用层验证更可靠
198
+ ```
199
+
200
+ ## Row-Level Security(RLS)
201
+
202
+ ```text
203
+ 适用:多租户隔离(每个用户只能看到自己的数据)
204
+
205
+ 实现:
206
+ 1. 启用行级安全:ALTER TABLE {table} ENABLE ROW LEVEL SECURITY
207
+ 2. 创建策略:允许/禁止特定操作
208
+
209
+ 示例:多租户隔离
210
+ CREATE POLICY tenant_isolation ON orders
211
+ USING (tenant_id = current_setting('app.tenant_id')::int)
212
+
213
+ 规则:
214
+ - RLS 应用层不可绕过
215
+ - 性能影响很小(查询只加一次过滤)
216
+ - 管理员应有一个绕过 RLS 的角色
217
+ ```
218
+
219
+ ## 连接池
220
+
221
+ ```text
222
+ 为什么需要连接池?
223
+ - 建立连接开销大(TCP + TLS + 认证)
224
+ - 数据库并发连接数有限
225
+
226
+ 配置要点:
227
+ - 池大小 = 2 × CPU 核心数 + 磁盘数(经验公式)
228
+ - 不是越大越好(过多连接→上下文切换→性能下降)
229
+ - 设置超时:连接超时、查询超时、闲置超时
230
+
231
+ 连接耗尽处理:
232
+ - 优先保证关键路径的连接
233
+ - 非关键操作降级(缓存结果 / 返回降级响应)
234
+ - 监控连接池使用率
235
+ ```