@wdyy/skills 0.1.21 → 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.
@@ -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(32),默认空值,取值自 `mdm_dictionary_item.item_code`)。除 `created_at`、`updated_at` 和主键外,所有字段默认允许空值,`deleted_flag` 默认为空。
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(32),默认空值,取值来源为 `mdm_dictionary_item.item_code`。
62
+ - [ ] `{前缀}_status` 字段类型为 varchar(1),默认空值,仅使用 `e`(启用)或 `d`(停用)。
63
63
  - [ ] 除主键、`created_at`、`updated_at` 外,所有字段默认允许空值,`deleted_flag` 默认为 NULL。
64
64
  - [ ] 所有时间类型字段均使用 `timestamp(0)`,未出现 `timestamptz`。
65
65
  - [ ] 每张表的字段、类型、必填、默认值、索引、唯一约束、逻辑关联和枚举均有说明。
@@ -43,8 +43,8 @@
43
43
  ## 统一状态字段
44
44
 
45
45
  - 字段名 `{业务域前缀}_status`。
46
- - 类型 `varchar(32)`,允许空值,默认为空。
47
- - 状态值通过字典表 `mdm_dictionary_item.item_code` 获取。
46
+ - 类型 `varchar(1)`,允许空值,默认为空。
47
+ - 状态值仅使用 `e`(启用)或 `d`(停用)。
48
48
 
49
49
  ## 关联与约束
50
50
 
@@ -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
- // 必须包含 _status 统一状态字段
32
- if (!/_status\b/.test(content)) {
33
- throw new Error('Table must include a domain-prefixed status field (e.g. pat_status)');
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(32) | 否 | NULL | 业务状态,取值自 mdm_dictionary_item.item_code | 业务状态码 | |
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
- - 状态字典:`mdm_dictionary_item.item_code`
39
+ - 状态取值:`e`(启用)、`d`(停用)
40
40
  - 迁移向前兼容策略:
41
41
  - 基线迁移:`database/migrations/V001__baseline.sql`
42
42
  - 当前迁移版本:
package/lib/wdyy-cli.js CHANGED
@@ -65,7 +65,7 @@ const generatedAgentsContent = `# 企业开发规则
65
65
 
66
66
  ## 固定技术栈
67
67
 
68
- - Node.js 24、pnpm workspace、TypeScript。
68
+ - Node.js 24、pnpm workspace、TypeScript 6.0
69
69
  - 前端:Vue 3、Vite、Pinia、Vue Router、Element Plus。
70
70
  - 后端:NestJS。
71
71
  - 数据库:PostgreSQL 18。
@@ -91,7 +91,6 @@ const generatedAgentsContent = `# 企业开发规则
91
91
  ## 通用边界
92
92
 
93
93
  - 项目根目录应提供真实可执行的 \`pnpm dev\`、\`pnpm build\`、\`pnpm test\`、\`pnpm lint\` 命令;\`pnpm dev\` 只负责前后端的启动,不得启动或管理数据库。
94
- - 接口实现仅以工程师人工提供的 YAML 文件为依据。未提供 YAML 或 YAML 中的接口契约不完整时,必须询问工程师;不得从已删除的 Skill、旧 reference、远程目录或其他来源推断或编造接口细节。
95
94
  - 生成的接口文档必须符合 OpenAPI 3.1 规范,并声明 \`openapi: 3.1.0\`。
96
95
  - 在下载或安装任何项目依赖前,必须先从官方发布渠道确认当前最新稳定版本,并检查该版本及其传递依赖的公开漏洞修复状态。原则上必须使用最新稳定版本;不得使用已过时的依赖,也不得使用存在未修复高危(High/Critical)漏洞的依赖。若最新稳定版本不兼容,或不存在满足安全要求的版本,必须停止安装并报告依赖名称、候选版本、兼容性及漏洞证据,等待工程师确认;不得擅自降级、忽略审计结果或添加豁免。
97
96
  - 代码、配置、迁移、测试与部署文件必须以实际实现为准;不得用模板虚构已实现能力。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdyy/skills",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "企业内部开发 Skill 与项目初始化命令",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@12.1.0",