@wdyy/skills 0.1.22 → 0.1.23
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/.well-known/skills/index.json +1 -1
- package/.well-known/skills/wdyy-database-standard/SKILL.md +2 -2
- package/.well-known/skills/wdyy-database-standard/reference/database-rules.md +2 -2
- package/.well-known/skills/wdyy-database-standard/scripts/validate-table-design.mjs +4 -3
- package/.well-known/skills/wdyy-database-standard/scripts/validate-table-design.test.mjs +41 -0
- package/.well-known/skills/wdyy-database-standard/templates/table-design.template.md +2 -2
- package/lib/wdyy-cli.js +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{
|
|
4
4
|
"name": "wdyy-database-standard",
|
|
5
5
|
"description": "将已确认的 PRD 与 DDL 转为 PostgreSQL 18 无外键逻辑关联设计,约束业务域表名前缀、自增主键 {前缀}_id、统一状态字段 {前缀}_status、timestamp(0) 时间类型、字段可空策略、注释、幂等、审计与向前兼容。Use when 审查 DDL、建立 V001 基线、增加后续迁移或验证生产数据库兼容性时。",
|
|
6
|
-
"files": ["SKILL.md", "agents/openai.yaml", "reference/database-rules.md", "scripts/apply-migrations.sh", "scripts/apply-migrations.test.mjs", "scripts/validate-migration-layout.mjs", "scripts/validate-migration-layout.test.mjs", "scripts/validate-table-design.mjs", "templates/table-design.template.md"]
|
|
6
|
+
"files": ["SKILL.md", "agents/openai.yaml", "reference/database-rules.md", "scripts/apply-migrations.sh", "scripts/apply-migrations.test.mjs", "scripts/validate-migration-layout.mjs", "scripts/validate-migration-layout.test.mjs", "scripts/validate-table-design.mjs", "scripts/validate-table-design.test.mjs", "templates/table-design.template.md"]
|
|
7
7
|
},
|
|
8
8
|
{
|
|
9
9
|
"name": "wdyy-deployment-standard",
|
|
@@ -26,7 +26,7 @@ description: 将已确认的 PRD 与 DDL 转为 PostgreSQL 18 无外键逻辑关
|
|
|
26
26
|
## 执行步骤
|
|
27
27
|
|
|
28
28
|
1. 确认 PRD 与 DDL 已通过就绪检查,识别实体、聚合关系、状态机、唯一约束、幂等键和审计责任人。
|
|
29
|
-
2. 为每个表设计小写下划线名称,表名必须添加业务域英文简写前缀(见业务域前缀映射表);若业务实体无对应前缀,须提示用户并给出建议,不得自行决定。首字段固定为 `{业务域前缀}_id`,类型使用自增主键,不得使用 `uuid`;所有时间类型字段统一使用 `timestamp(0)`;统一状态字段 `{业务域前缀}_status`(varchar(
|
|
29
|
+
2. 为每个表设计小写下划线名称,表名必须添加业务域英文简写前缀(见业务域前缀映射表);若业务实体无对应前缀,须提示用户并给出建议,不得自行决定。首字段固定为 `{业务域前缀}_id`,类型使用自增主键,不得使用 `uuid`;所有时间类型字段统一使用 `timestamp(0)`;统一状态字段 `{业务域前缀}_status`(varchar(1),默认空值,仅使用 `e` 表示启用、`d` 表示停用)。除 `created_at`、`updated_at` 和主键外,所有字段默认允许空值,`deleted_flag` 默认为空。
|
|
30
30
|
3. 建立逻辑关联和必要索引,不创建数据库外键;明确每个枚举、默认值和字段业务含义。
|
|
31
31
|
4. 为每张表编写表注释,为每个字段编写字段注释;迁移 SQL 必须包含 `COMMENT ON TABLE` 与 `COMMENT ON COLUMN`。
|
|
32
32
|
5. 新项目将工程师确认的完整 DDL 固化为 `database/migrations/V001__baseline.sql`;后续变更只新增连续编号的 `VNNN__lower_snake_name.sql`,不得修改已执行文件。
|
|
@@ -59,7 +59,7 @@ description: 将已确认的 PRD 与 DDL 转为 PostgreSQL 18 无外键逻辑关
|
|
|
59
59
|
- [ ] 每张表均有表注释,每个字段均有字段注释,迁移 SQL 包含对应 `COMMENT ON TABLE` 与 `COMMENT ON COLUMN`。
|
|
60
60
|
- [ ] 所有业务表名均带有业务域前缀,前缀来自映射表或已获得用户确认。
|
|
61
61
|
- [ ] 首字段为 `{前缀}_id`,自增主键,未使用 uuid。
|
|
62
|
-
- [ ] `{前缀}_status` 字段类型为 varchar(
|
|
62
|
+
- [ ] `{前缀}_status` 字段类型为 varchar(1),默认空值,仅使用 `e`(启用)或 `d`(停用)。
|
|
63
63
|
- [ ] 除主键、`created_at`、`updated_at` 外,所有字段默认允许空值,`deleted_flag` 默认为 NULL。
|
|
64
64
|
- [ ] 所有时间类型字段均使用 `timestamp(0)`,未出现 `timestamptz`。
|
|
65
65
|
- [ ] 每张表的字段、类型、必填、默认值、索引、唯一约束、逻辑关联和枚举均有说明。
|
|
@@ -28,9 +28,10 @@ if (/(^|\n)\s*\|\s*1\s*\|\s*id\s*\|\s*uuid\b/i.test(content) || /\bid\s+uuid\b/i
|
|
|
28
28
|
throw new Error('Primary key must use an auto-increment type, not uuid');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
// 必须包含统一状态字段,且状态类型和取值符合规范
|
|
32
|
+
const statusField = /^\|\s*[^|\n]*\|\s*`?[^|`\n]+_status`?\s*\|\s*varchar\(1\)\s*\|[^\n]*\be\b[^\n]*\bd\b/im;
|
|
33
|
+
if (!statusField.test(content)) {
|
|
34
|
+
throw new Error('Table must include a domain-prefixed status field with varchar(1) and e/d status values');
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// deleted_flag 默认值必须为 NULL,不得为 false
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { execFile as execFileCallback } from 'node:child_process';
|
|
3
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import test from 'node:test';
|
|
7
|
+
import { promisify } from 'node:util';
|
|
8
|
+
|
|
9
|
+
const execFile = promisify(execFileCallback);
|
|
10
|
+
const script = new URL('./validate-table-design.mjs', import.meta.url);
|
|
11
|
+
const template = new URL('../templates/table-design.template.md', import.meta.url);
|
|
12
|
+
|
|
13
|
+
async function withDesign(mutator, assertion) {
|
|
14
|
+
const directory = await mkdtemp(join(tmpdir(), 'wdyy-table-design-'));
|
|
15
|
+
const designPath = join(directory, 'table-design.md');
|
|
16
|
+
try {
|
|
17
|
+
const content = mutator(await readFile(template, 'utf8'));
|
|
18
|
+
await writeFile(designPath, content);
|
|
19
|
+
await assertion(designPath);
|
|
20
|
+
} finally {
|
|
21
|
+
await rm(directory, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test('接受 varchar(1) 且仅声明 e/d 的状态字段', async () => {
|
|
26
|
+
await withDesign((content) => content, async (designPath) => {
|
|
27
|
+
await execFile('node', [script.pathname, designPath]);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('拒绝非 varchar(1) 或未声明 e/d 的状态字段', async () => {
|
|
32
|
+
await withDesign(
|
|
33
|
+
(content) => content.replace('varchar(1)', 'varchar(32)').replace('仅使用 e(启用)或 d(停用)', '状态值待确认'),
|
|
34
|
+
async (designPath) => {
|
|
35
|
+
await assert.rejects(
|
|
36
|
+
execFile('node', [script.pathname, designPath]),
|
|
37
|
+
/varchar\(1\) and e\/d status values/,
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
});
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|---:|---|---|---|---|---|---|---|
|
|
19
19
|
| 1 | `{前缀}_id` | bigint | 是 | generated by default as identity | 自增主标识 | 自增主标识 | 主键索引 |
|
|
20
20
|
| ... | (业务字段) | | 否 | | | | |
|
|
21
|
-
| n-5 | `{前缀}_status` | varchar(
|
|
21
|
+
| n-5 | `{前缀}_status` | varchar(1) | 否 | NULL | 业务状态,仅使用 e(启用)或 d(停用) | 业务状态 | |
|
|
22
22
|
| n-4 | created_by | varchar(64) | 否 | NULL | 创建人 | 创建人标识 | |
|
|
23
23
|
| n-3 | updated_by | varchar(64) | 否 | NULL | 更新人 | 更新人标识 | |
|
|
24
24
|
| n-2 | created_at | timestamp(0) | 是 | now() | 创建时间 | 记录创建时间 | |
|
|
@@ -36,7 +36,7 @@ COMMENT ON COLUMN {前缀}_{表名}.{前缀}_id IS '主标识';
|
|
|
36
36
|
## 枚举与兼容性
|
|
37
37
|
|
|
38
38
|
- 枚举:
|
|
39
|
-
-
|
|
39
|
+
- 状态取值:`e`(启用)、`d`(停用)
|
|
40
40
|
- 迁移向前兼容策略:
|
|
41
41
|
- 基线迁移:`database/migrations/V001__baseline.sql`
|
|
42
42
|
- 当前迁移版本:
|
package/lib/wdyy-cli.js
CHANGED