create-dwy 0.8.0 → 0.9.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 (95) hide show
  1. package/package.json +1 -1
  2. package/src/create.js +50 -3
  3. package/src/utils.js +4 -0
  4. package/templates/claude-global/CLAUDE.md +81 -6
  5. package/templates/claude-global/rules/dwy-postgres.md +89 -0
  6. package/templates/claude-global/rules/dwy-python-backend.md +492 -0
  7. package/templates/claude-global/rules/dwy-python-core.md +94 -634
  8. package/templates/claude-global/rules/dwy-python-testing.md +115 -13
  9. package/templates/claude-global/rules/dwy-redis.md +88 -0
  10. package/templates/claude-global/rules/dwy-vue-core.md +341 -645
  11. package/templates/claude-global/rules/dwy-vue-pinia.md +47 -34
  12. package/templates/claude-global/rules/dwy-vue-testing.md +120 -55
  13. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-network.md +1 -1
  14. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_nginx.sh +1 -1
  15. package/templates/claude-global/skills/dwy-dolphindb/SKILL.md +22 -15
  16. package/templates/claude-global/skills/dwy-dolphindb/evals/evals.json +23 -0
  17. package/templates/claude-global/skills/dwy-dolphindb/references/dolphindb-rules.md +100 -1
  18. package/templates/claude-global/skills/dwy-ekit/SKILL.md +142 -276
  19. package/templates/claude-global/skills/dwy-eui/SKILL.md +264 -182
  20. package/templates/claude-global/skills/dwy-fullstack-scaffold/SKILL.md +117 -129
  21. package/templates/claude-global/skills/dwy-git-commit/SKILL.md +125 -0
  22. package/templates/claude-global/skills/dwy-publish/SKILL.md +1 -1
  23. package/templates/claude-global/{rules/dwy-tech-stack.md → skills/dwy-tech-stack/SKILL.md} +4 -3
  24. package/templates/project/fullstack-monorepo/CLAUDE.md.hbs +81 -0
  25. package/templates/project/fullstack-monorepo/backend/.python-version +1 -0
  26. package/templates/project/fullstack-monorepo/backend/CLAUDE.md.hbs +68 -0
  27. package/templates/project/fullstack-monorepo/backend/Dockerfile.dev +23 -0
  28. package/templates/project/fullstack-monorepo/backend/alembic/env.py.hbs +68 -0
  29. package/templates/project/fullstack-monorepo/backend/alembic/script.py.mako +26 -0
  30. package/templates/project/fullstack-monorepo/backend/alembic.ini.hbs +43 -0
  31. package/templates/project/fullstack-monorepo/backend/packages/dwy-shared/pyproject.toml +16 -0
  32. package/templates/project/fullstack-monorepo/backend/packages/dwy-shared/src/dwy_shared/__init__.py +12 -0
  33. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/pyproject.toml.hbs +20 -0
  34. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/__init__.py.hbs +40 -0
  35. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/config.py +9 -0
  36. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/models.py.hbs +17 -0
  37. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/protocols.py +14 -0
  38. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/router.py.hbs +22 -0
  39. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/schemas.py +21 -0
  40. package/templates/project/fullstack-monorepo/backend/packages/{{scopePrefix}}-{{initialDomain}}/src/{{scopePrefix}}_{{initialDomain}}/service.py +11 -0
  41. package/templates/project/fullstack-monorepo/backend/pyproject.toml.hbs +84 -0
  42. package/templates/project/fullstack-monorepo/backend/src/app/__init__.py +3 -0
  43. package/templates/project/fullstack-monorepo/backend/src/app/config.py.hbs +21 -0
  44. package/templates/project/fullstack-monorepo/backend/src/app/exceptions.py +26 -0
  45. package/templates/project/fullstack-monorepo/backend/src/app/factories.py +16 -0
  46. package/templates/project/fullstack-monorepo/backend/src/app/infra/__init__.py +1 -0
  47. package/templates/project/fullstack-monorepo/backend/src/app/main.py.hbs +65 -0
  48. package/templates/project/fullstack-monorepo/backend/src/app/middleware/__init__.py +1 -0
  49. package/templates/project/fullstack-monorepo/backend/tests/__init__.py +0 -0
  50. package/templates/project/fullstack-monorepo/backend/tests/conftest.py.hbs +42 -0
  51. package/templates/project/fullstack-monorepo/dev.sh.hbs +83 -0
  52. package/templates/project/fullstack-monorepo/docker-compose.dev.yml.hbs +36 -0
  53. package/templates/project/fullstack-monorepo/frontend/CLAUDE.md.hbs +35 -0
  54. package/templates/project/fullstack-monorepo/frontend/Dockerfile +18 -0
  55. package/templates/project/fullstack-monorepo/frontend/apps/web/index.html.hbs +13 -0
  56. package/templates/project/fullstack-monorepo/frontend/apps/web/package.json.hbs +31 -0
  57. package/templates/project/fullstack-monorepo/frontend/apps/web/src/App.vue.hbs +10 -0
  58. package/templates/project/fullstack-monorepo/frontend/apps/web/src/api/client.ts.hbs +11 -0
  59. package/templates/project/fullstack-monorepo/frontend/apps/web/src/features/{{initialDomain}}/.gitkeep +0 -0
  60. package/templates/project/fullstack-monorepo/frontend/apps/web/src/index.css +12 -0
  61. package/templates/project/fullstack-monorepo/frontend/apps/web/src/main.ts +17 -0
  62. package/templates/project/fullstack-monorepo/frontend/apps/web/src/router/index.ts.hbs +24 -0
  63. package/templates/project/fullstack-monorepo/frontend/apps/web/src/stores/.gitkeep +0 -0
  64. package/templates/project/fullstack-monorepo/frontend/apps/web/src/types/.gitkeep +0 -0
  65. package/templates/project/fullstack-monorepo/frontend/apps/web/src/views/HomeView.vue.hbs +36 -0
  66. package/templates/project/fullstack-monorepo/frontend/apps/web/tsconfig.json +7 -0
  67. package/templates/project/fullstack-monorepo/frontend/apps/web/vite.config.ts.hbs +27 -0
  68. package/templates/project/fullstack-monorepo/frontend/nginx.conf +11 -0
  69. package/templates/project/fullstack-monorepo/frontend/package.json.hbs +13 -0
  70. package/templates/project/fullstack-monorepo/frontend/packages/core/package.json.hbs +15 -0
  71. package/templates/project/fullstack-monorepo/frontend/packages/core/src/index.ts +3 -0
  72. package/templates/project/fullstack-monorepo/frontend/packages/features/{{initialDomain}}/package.json.hbs +14 -0
  73. package/templates/project/fullstack-monorepo/frontend/packages/features/{{initialDomain}}/src/index.ts.hbs +16 -0
  74. package/templates/project/fullstack-monorepo/frontend/packages/features/{{initialDomain}}/src/pages/IndexPage.vue.hbs +9 -0
  75. package/templates/project/fullstack-monorepo/frontend/packages/ui/package.json.hbs +15 -0
  76. package/templates/project/fullstack-monorepo/frontend/packages/ui/src/index.ts +3 -0
  77. package/templates/project/fullstack-monorepo/frontend/pnpm-workspace.yaml.hbs +23 -0
  78. package/templates/project/fullstack-monorepo/frontend/tsconfig.base.json.hbs +23 -0
  79. package/templates/claude-global/rules/dwy-api-design.md +0 -110
  80. package/templates/claude-global/rules/dwy-git-commit-convention.md +0 -82
  81. package/templates/claude-global/rules/dwy-git-security.md +0 -53
  82. package/templates/claude-global/rules/dwy-payload-limits.md +0 -186
  83. package/templates/claude-global/rules/dwy-prefer-open-source.md +0 -32
  84. package/templates/claude-global/rules/dwy-project-structure.md +0 -181
  85. package/templates/claude-global/rules/dwy-python-fastapi.md +0 -272
  86. package/templates/claude-global/rules/dwy-python-orm.md +0 -61
  87. package/templates/claude-global/rules/dwy-python-security.md +0 -636
  88. package/templates/claude-global/rules/dwy-server-security.md +0 -518
  89. package/templates/claude-global/rules/dwy-vue-api.md +0 -146
  90. package/templates/claude-global/skills/dwy-ekit/references/data.md +0 -135
  91. package/templates/claude-global/skills/dwy-ekit/references/form.md +0 -68
  92. package/templates/claude-global/skills/dwy-ekit/references/request.md +0 -183
  93. package/templates/claude-global/skills/dwy-ekit/references/ui.md +0 -109
  94. package/templates/claude-global/skills/dwy-vue-core/SKILL.md +0 -890
  95. /package/templates/{claude-global/commands → project/fullstack-monorepo/backend/alembic/versions}/.gitkeep +0 -0
@@ -1,214 +1,202 @@
1
1
  ---
2
2
  name: dwy-fullstack-scaffold
3
- description: "按 quant-cloud monorepo 架构生成 Web 全栈项目骨架。触发条件:用户说'创建新项目'、'搭骨架'、'新建全栈项目'、'按 quant-cloud 架构创建'、'全栈脚手架'、'scaffold'、'新项目按这个架构'、'开新项目'时。"
3
+ description: "调用 dwy create CLI 生成全栈 Vue 3 + FastAPI monorepo 骨架,并完成 post-create 安装 + health check 编排。触发条件:用户说'创建新项目'、'搭骨架'、'新建全栈项目'、'fullstack monorepo'、'全栈脚手架'、'scaffold'、'开新项目'时。"
4
4
  ---
5
5
 
6
6
  # dwy-fullstack-scaffold
7
7
 
8
- 按照 quant-cloud(/Users/chances/WebstormProjects/ai-quant/quant-cloud/) 的 monorepo 架构生成全栈项目骨架。
8
+ 调用 `dwy create` CLI 选 `fullstack-monorepo` 模板生成全栈 monorepo 骨架,然后用 Bash 编排 post-action(依赖安装 + health check)。
9
9
 
10
10
  ## 触发后该做什么(决策树)
11
11
 
12
12
  ```
13
13
  用户说 "创建新项目 xxx" / "搭骨架"
14
14
  ↓
15
- 1. 用 AskUserQuestion 收集 5 个关键参数:
16
- - project_name (kebab-case, 用作目录名 + Docker 服务名)
17
- - target_dir (默认 /Users/chances/WebstormProjects/<project_name>)
18
- - scope_prefix (业务包前缀, 默认 'app', 也可填 'quant' / 'foo' 等)
19
- - initial_domain (示例业务域, 默认 'core', 用户可填 'order' / 'user' 等)
20
- - include_frontend (默认 true; false 则只生成 backend + 根级)
15
+ 1. 用 AskUserQuestion 收集 5 个关键参数(如用户已说明部分,直接用,缺什么问什么):
16
+ - project_name (kebab-case, 用作目录名 + Docker DB 名)
17
+ - target_parent_dir (默认 /Users/chances/WebstormProjects)
18
+ - scope_prefix (业务包前缀, 默认 'app')
19
+ - initial_domain (示例业务域, 默认 'core')
20
+ - include_frontend (默认 true)
21
+ - port_prefix (端口前缀数字, 1-9, 默认 '2')
21
22
  ↓
22
- 2. 检查 target_dir 不存在或为空。如已存在且非空, AskUserQuestion 确认是否清理。
23
+ 2. 检查 <target_parent_dir>/<project_name> 不存在或为空。已存在且非空 → AskUserQuestion 确认是否清理。
23
24
  ↓
24
- 3. 调用 scripts/scaffold.py 生成全部文件:
25
- uv run python /Users/chances/.claude/skills/dwy-fullstack-scaffold/scripts/scaffold.py \
26
- --project-name <name> \
27
- --target-dir <dir> \
28
- --scope-prefix <prefix> \
29
- --initial-domain <domain> \
30
- --include-frontend <true|false>
25
+ 3. 调用 dwy create(在 target_parent_dir 下执行):
26
+ cd <target_parent_dir>
27
+ dwy create <project_name>
28
+ 交互时回答:
29
+ - 项目模板: fullstack-monorepo
30
+ - 业务包前缀: <scope_prefix>
31
+ - 初始业务域: <initial_domain>
32
+ - 是否生成 frontend: <include_frontend>
33
+ - 端口前缀数字: <port_prefix>
34
+
35
+ 或者用环境变量 / 配置非交互模式(如果 dwy CLI 支持)。当前最稳的做法是用 expect 模拟交互,或者让用户自己跑 dwy create,本 skill 负责后续编排。
36
+
37
+ **推荐做法**:让用户在终端跑 `dwy create <project_name>` 自己回答交互(每次脚手架问题需要人 review),然后 skill 介入做 post-action。
31
38
  ↓
32
- 4. 生成完成后自动执行(脚本内做):
33
- - cd <target_dir>/backend && uv sync --dev
34
- - cd <target_dir>/frontend && pnpm install (如开 frontend)
39
+ 4. 安装依赖(在 <target_parent_dir>/<project_name> 下):
40
+ - cp .env.example .env (如未存在)
41
+ - cd backend && uv sync --dev
42
+ - cd frontend && pnpm install (仅当 include_frontend=true)
35
43
  ↓
36
- 5. Health check (脚本内做, 临时端口避免冲突):
37
- - 启 backend: uv run uvicorn app.main:app --port <free_port_be>
38
- - curl http://127.0.0.1:<free_port_be>/api/health 期望 {"status":"ok"}
39
- - 启 frontend: pnpm --filter web dev --port <free_port_fe>
40
- - curl http://127.0.0.1:<free_port_fe>/ 期望 200
41
- - 全部 kill 干净
44
+ 5. Health check(用临时端口避免冲突):
45
+ - free_port_be=$(python3 -c "import socket;s=socket.socket();s.bind(('',0));print(s.getsockname()[1])")
46
+ - 临时启 backend: uv run uvicorn app.main:app --port $free_port_be &
47
+ - 等 1-3 秒,curl http://127.0.0.1:$free_port_be/api/health 期望 {"status":"ok",...}
48
+ - kill backend 进程
49
+ - 如 include_frontend=true:
50
+ - free_port_fe=$(...)
51
+ - pnpm --filter @<project_name>/web dev --port $free_port_fe &
52
+ - 等 3-5 秒,curl http://127.0.0.1:$free_port_fe/ 期望 200
53
+ - kill frontend 进程
42
54
  ↓
43
55
  6. 报告结果 + 下一步指引
44
56
  ```
45
57
 
46
58
  ## 生成的目录结构
47
59
 
60
+ `dwy create` 选 `fullstack-monorepo` 模板会生成:
61
+
48
62
  ```
49
63
  <project_name>/
50
- ├── CLAUDE.md # 项目级总入口(融入 quant-cloud 关键约束)
51
- ├── dev.sh # 一键启动: 杀端口 + Docker + backend + frontend
52
- ├── docker-compose.dev.yml # PG + Redis 基础设施(端口前缀 2xxxx 避冲突)
53
- ├── docker-compose.prod.yml # 生产:三服务硬资源限制 + Redis 双持久化 + 日志轮转
54
- ├── deploy/ # 部署脚本占位
55
- ├── docs/ # 设计文档占位
64
+ ├── CLAUDE.md # 项目级总入口
65
+ ├── dev.sh # 一键启动: 杀端口 + Docker + backend + frontend
66
+ ├── docker-compose.dev.yml # PG + Redis(端口前缀 <port_prefix>xxxx)
56
67
  ├── .env.example
57
68
  ├── .gitignore
58
69
  ├── backend/
59
- │ ├── CLAUDE.md # 后端约束(分层/Provider/异常/eapi 优先使用等)
60
- │ ├── pyproject.toml # 单一版本中心 + uv workspace + 双 index(aliyun + pypi)
70
+ │ ├── CLAUDE.md # 后端约束(域分包 / Provider / dwyeapi 优先)
71
+ │ ├── pyproject.toml # uv workspace + 双 index + 版本中心
61
72
  │ ├── Dockerfile.dev
62
- │ ├── alembic.ini # 数据库迁移
63
- │ ├── alembic/env.py
64
- │ ├── src/app/ # 装配层
65
- │ │ ├── __init__.py # __version__
66
- │ │ ├── main.py # FastAPI lifespan + 装载 packages
67
- │ │ ├── config.py # eapi BaseSettings 嵌套分组
73
+ │ ├── alembic.ini + alembic/env.py
74
+ │ ├── src/app/ # 装配层
75
+ │ │ ├── main.py # FastAPI lifespan + register 业务包
76
+ │ │ ├── config.py # Settings 嵌套配置
77
+ │ │ ├── factories.py # Provider 工厂占位
68
78
  │ │ ├── exceptions.py
69
- │ │ ├── factories.py # Provider 工厂(配置驱动切换实现)
70
- │ │ ├── middleware/__init__.py
71
- │ │ └── infra/__init__.py
79
+ │ │ ├── middleware/ infra/
72
80
  │ ├── packages/
73
- │ │ ├── dwy-shared/ # 跨项目可复用 kernel
74
- │ │ │ ├── pyproject.toml
75
- │ │ │ └── src/dwy_shared/__init__.py
81
+ │ │ ├── dwy-shared/ # 跨项目通用 kernel
76
82
  │ │ └── <scope_prefix>-<initial_domain>/ # 业务包雏形
77
- │ │ ├── pyproject.toml
78
- │ │ └── src/<scope_prefix>_<initial_domain>/
79
- │ │ ├── __init__.py # register(app) 装载入口
80
- │ │ ├── router.py # /api/health endpoint
83
+ │ │ └── src/<scope>_<domain>/
84
+ │ │ ├── __init__.py # register(app, *, config) 装载入口
85
+ │ │ ├── config.py # DomainConfig
86
+ │ │ ├── router.py # /api/<domain>/health endpoint
81
87
  │ │ ├── service.py
82
88
  │ │ ├── schemas.py
83
89
  │ │ ├── models.py
84
- │ │ └── protocols.py # Provider 协议定义
85
- │ └── tests/
86
- │ └── conftest.py
87
- └── frontend/
88
- ├── CLAUDE.md # 前端约束(eui 优先 / pnpm catalog / features 域分包)
90
+ │ │ └── protocols.py
91
+ │ └── tests/conftest.py
92
+ └── frontend/ # 仅当 include_frontend=true
93
+ ├── CLAUDE.md # 前端约束(eui 优先 / catalog / features 域分包)
89
94
  ├── package.json
90
- ├── pnpm-workspace.yaml # catalog: 第三方依赖版本统一管理
95
+ ├── pnpm-workspace.yaml # catalog 统一版本
91
96
  ├── tsconfig.base.json
92
- ├── Dockerfile
93
- ├── apps/
94
- │ └── web/
95
- │ ├── package.json
96
- │ ├── vite.config.ts
97
- │ ├── tsconfig.json
98
- │ ├── index.html
99
- │ └── src/
100
- │ ├── main.ts
101
- │ ├── App.vue # 起始页含 "Welcome <project_name>" + /api/health 探活
102
- │ ├── index.css
103
- │ ├── api/client.ts
104
- │ ├── router/index.ts
105
- │ ├── stores/.gitkeep
106
- │ ├── types/.gitkeep
107
- │ └── features/<initial_domain>/.gitkeep
97
+ ├── Dockerfile + nginx.conf
98
+ ├── apps/web/
99
+ │ ├── vite.config.ts # 端口前缀 + /api proxy
100
+ │ └── src/{main.ts, App.vue, router, api, views, features/, stores/, types/}
108
101
  └── packages/
109
- ├── core/ # 横切核心(如全局 logger / 类型)
110
- │ ├── package.json
111
- │ └── src/index.ts
112
- ├── ui/ # 共享 UI 组件包(可选挂载 @dwydev/eui 默认)
113
- │ ├── package.json
114
- │ └── src/index.ts
115
- └── features/
116
- └── <initial_domain>/
117
- ├── package.json
118
- └── src/index.ts
102
+ ├── core/ # 横切核心
103
+ ├── ui/ # 项目级共享 UI(基于 @dwydev/eui)
104
+ └── features/<initial_domain>/ # 业务功能包雏形(导出 createFeatureRoutes())
119
105
  ```
120
106
 
121
- ## 关键模式(由模板严格保留)
107
+ ## 关键模式
122
108
 
123
- 参考 references/architecture.md 的详细说明。要点:
109
+ 详细参考生成的项目内 `CLAUDE.md`。要点:
124
110
 
125
- 1. **单一版本中心**:backend `pyproject.toml` 集中管理所有外部依赖版本号; frontend `pnpm-workspace.yaml` 的 catalog 集中管理 npm 依赖版本。子包 pyproject/package.json 只写包名,不写版本。
126
- 2. **装配层**:`backend/src/app/main.py` 只做"装配",装载 `packages/` 内 `register(app)` 函数。业务逻辑严禁出现在装配层。
127
- 3. **域分包**:每个业务 package 内按域(domain)子目录,域内再分 router/service/schemas/models/protocols 五件套。
128
- 4. **Provider 模式**:外部服务(数据库 / Redis / SMS / OSS / 第三方 API) 抽象为 Protocol; `factories.py` 按 settings 选具体实现。改实现不改业务代码。
129
- 5. **dwy- vs 业务-前缀**:`packages/dwy-*` 是跨项目可复用 kernel; `packages/<scope>-*` 是项目业务专属。
130
- 6. **dwyeapi 优先**:后端基础设施(配置 / 异常 / 健康检查 / 缓存 / 任务)先用 dwyeapi,不重复实现。
131
- 7. **端口前缀隔离**:每个项目用 1xxxx / 2xxxx / 3xxxx 万位前缀,避免与其他项目冲突。Skill 默认用 2xxxx。
132
- 8. **eui / ekit 默认**:前端 catalog 默认含 `@dwydev/eui` + `@dwydev/ekit`(项目可去掉)。
111
+ 1. **单一版本中心**:backend `pyproject.toml` 集中管理外部依赖版本;frontend `pnpm-workspace.yaml` 的 `catalog:` 集中管理 npm 依赖版本
112
+ 2. **装配层只装配**:业务逻辑在 `packages/<scope>-<domain>/`,不在 `src/app/`
113
+ 3. **域分包**:每业务包五件套 router/service/schemas/models/protocols + 一个 config
114
+ 4. **Provider 模式**:外部服务抽象为 Protocol,`factories.py` 选实现
115
+ 5. **dwy- vs 业务-前缀**:`packages/dwy-*` 跨项目;`packages/<scope>-*` 项目专属
116
+ 6. **dwyeapi 优先**:后端基础设施先用 dwyeapi
117
+ 7. **端口前缀**:`<port_prefix>xxxx`,默认 2(28001/25173/25432/26379)
118
+ 8. **eui / ekit 默认**:前端 catalog 默认含 `@dwydev/eui` + `@dwydev/ekit`
133
119
 
134
- ## 用户参数收集
120
+ ## 用户参数收集(必做)
135
121
 
136
- 调用脚本前 **必须** 用 AskUserQuestion 收集 5 个参数。提供合理默认值:
122
+ 调用 `dwy create` 前 **必须** 用 AskUserQuestion 收集 5 个参数(用户已明确给出的省去):
137
123
 
138
124
  | 参数 | 含义 | 默认 | 示例 |
139
125
  |------|------|------|------|
140
- | project_name | kebab-case 项目名 | (无默认,必问) | `my-app` / `quant-admin` |
141
- | target_dir | 目标父目录 | `/Users/chances/WebstormProjects/<project_name>` | 同上 |
126
+ | project_name | kebab-case 项目名 | (无默认,必问) | `my-app` |
142
127
  | scope_prefix | 业务包前缀 | `app` | `quant`, `foo` |
143
- | initial_domain | 初始示例业务域 | `core` | `order`, `user`, `factor` |
128
+ | initial_domain | 初始示例业务域 | `core` | `order`, `user` |
144
129
  | include_frontend | 是否生成 frontend | `true` | `true` / `false` |
130
+ | port_prefix | 端口万位前缀 (1-9) | `2` | `2`, `3` |
145
131
 
146
- **target_dir 检查**:已存在且非空 → 用 AskUserQuestion 让用户确认"清理后重建"或"换个目录"或"放弃"。
132
+ **目录检查**:`<target_parent_dir>/<project_name>` 已存在且非空 → AskUserQuestion 让用户确认"清理后重建"或"换个目录"或"放弃"。
147
133
 
148
134
  ## 不要做的事
149
135
 
150
- - **不要**改 `templates/` 里的内容(那是 skill 资产,改了影响后续生成)。如要扩展架构,在 SKILL.md 添加描述、补充模板文件,不要 in-place 修改。
151
- - **不要**生成业务代码(订单、用户管理等)。skill 只产出"骨架 + 1 个示意 endpoint"。业务代码由 AI 后续按 CLAUDE.md 引导补。
152
- - **不要**跳过 health check。生成完成必须验证 backend `/api/health` + frontend 首页 200。失败要报告原因,不能假装成功。
153
- - **不要**生成 `.git/`(让用户自己 `git init`)。
154
- - **不要**安装 `@dwydev/eui` 之外的额外 UI 库(如 Element Plus / Ant Design Vue)。
136
+ - **不要**直接写脚本生成模板。模板由 `dwy create` 渲染,本 skill 只负责参数收集 + post-action 编排
137
+ - **不要**修改生成的项目骨架(除非用户要求扩展业务)。生成完后的业务代码由 AI 后续按生成项目里的 `CLAUDE.md` 引导补
138
+ - **不要**跳过 health check。失败要报告原因,不能假装成功
139
+ - **不要**生成 `.git/`(让用户自己 `git init`)
140
+ - **不要**在生成后强行 `git init && commit`(让用户决策)
141
+ - **不要**安装 `@dwydev/eui` 之外的额外 UI 库
155
142
 
156
143
  ## 生成完成后的报告模板
157
144
 
158
145
  ```markdown
159
146
  ✅ 项目 <project_name> 骨架已生成
160
147
 
161
- 📁 路径: <target_dir>
148
+ 📁 路径: /Users/chances/WebstormProjects/<project_name>
162
149
 
163
150
  📦 已安装依赖:
164
151
  - backend (uv sync --dev): <duration> s
165
- - frontend (pnpm install): <duration> s [仅当 include_frontend=true]
152
+ - frontend (pnpm install): <duration> s [仅当 include_frontend=true]
166
153
 
167
154
  ✅ Health check:
168
- - GET http://127.0.0.1:<be_port>/api/health → 200 {"status":"ok"}
169
- - GET http://127.0.0.1:<fe_port>/ → 200 [仅当 include_frontend=true]
155
+ - GET http://127.0.0.1:<free_port_be>/api/health → 200 {"status":"ok",...}
156
+ - GET http://127.0.0.1:<free_port_fe>/ → 200 [仅当 include_frontend=true]
170
157
 
171
158
  🚀 下一步:
172
- cd <target_dir>
159
+ cd /Users/chances/WebstormProjects/<project_name>
160
+ cp .env.example .env # 修改 DATABASE_URL / SECRET_KEY 等
173
161
  ./dev.sh
174
162
 
175
163
  🛠 业务开发起点:
176
164
  - backend: backend/src/app/main.py 装载 packages/<scope>-<domain>/
177
- -> 加新业务: 复制 <scope>-<domain>/ 整个目录,改名后在 main.py 装载
178
- - frontend: frontend/apps/web/src/features/<domain>/ + packages/features/<domain>/
179
- -> 加新功能: 在 features/ 下加目录,在 router/index.ts 注册路由
165
+ → 加新业务: 复制 packages/<scope>-<domain>/ 整体改名 + 在 main.py 装载
166
+ - frontend: frontend/packages/features/<domain>/ + frontend/apps/web/src/features/<domain>/
167
+ → 加新功能: 在 features/ 下加目录,在 router/index.ts 注册路由
180
168
 
181
169
  📋 待办(skill 没替你做):
182
- - git init && git add . && git commit -m "chore: initial scaffold from dwy-fullstack-scaffold"
170
+ - cd /Users/chances/WebstormProjects/<project_name> && git init && git add . && git commit -m "chore: initial scaffold"
183
171
  - 在 .env 中填真实 DATABASE_URL / REDIS_URL / SECRET_KEY (默认值仅适合本地)
184
- - 按需调整 packages/dwy-shared/ 的依赖范围
185
- - 按需启用 alembic: cd backend && uv run alembic init -t async alembic (skill 已留 alembic.ini, env.py 雏形)
172
+ - 按需 alembic init: cd backend && uv run alembic upgrade head
186
173
  ```
187
174
 
188
175
  ## 失败排错
189
176
 
190
- 生成或 health check 失败时,先看脚本输出最后 50 行(脚本会打印每一步的命令 + stderr)。常见失败:
191
-
192
177
  | 症状 | 原因 | 解决 |
193
178
  |------|------|------|
194
- | `uv sync` 报 dwyeapi 找不到 | 默认 aliyun 镜像可能没同步 | pyproject 里 dwyeapi 已声明 `index = "pypi-org"`,确保 uv >=0.4 |
195
- | `pnpm install` 报 catalog 找不到 | pnpm <8.x 不支持 catalog | 升 pnpm: `npm i -g pnpm@latest` |
196
- | backend health check 端口冲突 | 别的进程占了 28001 | 脚本会自动找 free port,不应发生; 看脚本日志 |
197
- | `vite` 启不来 | apps/web 缺 `@vitejs/plugin-vue` | catalog 已含,确认 pnpm install 没出错 |
198
- | `register()` 找不到 | scope_prefix 含特殊字符 | 用 lowercase + 字母数字下划线,kebab-case |
179
+ | `dwy create` 命令找不到 | create-dwy 未安装或不在 PATH | `pnpm i -g create-dwy` 或在 dwy-shared 仓库 `pnpm link --global` |
180
+ | `dwy create` 报模板找不到 | Gitee 缓存过期或 dwy-shared 未推送最新版 | 删 `~/.dwy/cache/` 重试,确认 Gitee 上 dwy-shared 含 `fullstack-monorepo` 模板 |
181
+ | `uv sync` 报 dwyeapi 找不到 | aliyun 镜像未同步 | pyproject 已声明 pypi-org 备 index,确保 uv >=0.4 |
182
+ | `pnpm install` 报 catalog 找不到 | pnpm <10 不支持 catalog | 升级: `npm i -g pnpm@latest` |
183
+ | backend health check 失败 | DATABASE_URL/SECRET_KEY 用了占位值导致启动报错 | 检查 .env 是否已 cp 自 .env.example;查 uvicorn stderr 输出 |
184
+ | frontend health check 失败 | catalog 版本未对齐或 EUI peerDep 缺失 | 看 pnpm install 输出错误,按 catalog 加缺失版本 |
185
+ | `register()` 找不到 | scope_prefix 含特殊字符 | scope_prefix 只允许小写字母开头 + 字母数字 |
199
186
 
200
187
  ## 后续扩展
201
188
 
202
- 加新业务 package(例如订单系统 `quant-order`):
189
+ **加新后端业务包**(如 `app-order`):
203
190
 
204
- 1. 复制 `backend/packages/<scope>-<initial_domain>/` 整体到 `<scope>-<new_domain>/`
191
+ 1. 复制 `backend/packages/<scope_prefix>-<initial_domain>/` 整体改名 `app-order/`
205
192
  2. 改 `pyproject.toml` 的 `name` 字段
206
- 3. 改 `src/<scope>_<new_domain>/__init__.py` 的 `register()` 函数名(可选,主要是 import 路径)
207
- 4. 改 `src/app/main.py` 加 `from <scope>_<new_domain> import register as register_<new_domain>`
208
- 5. lifespan 里调 `register_<new_domain>(app)`
193
+ 3. 改 `src/app_order/__init__.py` 的导入路径
194
+ 4. 改 `src/app/main.py` 加 `from app_order import register as register_order; register_order(app, config=settings.order)`
195
+ 5. 在 `src/app/config.py` 加 `order: DomainConfig` 字段
209
196
 
210
- 加新前端 feature:
197
+ **加新前端 feature**(如 `order`):
211
198
 
212
- 1. 在 `frontend/packages/features/` 复制示例 feature 整体改名
213
- 2. 在 `frontend/apps/web/src/features/` 加同名目录(页面层)
214
- 3. `apps/web/src/router/index.ts` 注册路由
199
+ 1. 复制 `frontend/packages/features/<initial_domain>/` 改名 `frontend/packages/features/order/`
200
+ 2. 在 `frontend/apps/web/src/router/index.ts` 加 `import { createFeatureRoutes as createOrderRoutes } from '@<project_name>/features-order'` 并装载
201
+ 3. 在 `frontend/tsconfig.base.json` 加路径别名 `@<project_name>/features-order`
202
+ 4. 在 `frontend/apps/web/package.json` 加 workspace 依赖 `@<project_name>/features-order: workspace:*`
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: dwy-git-commit
3
+ description: "Git commit 强制规范(敏感数据扫描 + message 格式 + 禁 AI 署名)。触发场景:用户说'提交' / 'commit' / 'git commit' / 'git add';AI 准备执行 `git add` / `git commit` 之前;用户让你帮忙写 commit message;review 已有 commit message。强制:先扫描暂存物是否含 .env / 密钥 / API Key / 连接串等敏感数据;再检查 CLAUDE.md 的 Git Commit Scope 段;subject 用中文动宾短语 ≤72 字符;message 任何位置禁止 Claude / GPT / Copilot / AI / LLM 字样及 Co-Authored-By trailer。"
4
+ ---
5
+
6
+ # Git Commit 强制规范
7
+
8
+ 每次 `git add` / `git commit` 前按顺序执行以下检查,任一步未通过 → **STOP,不得提交**。
9
+
10
+ ## Step 0: 敏感数据扫描
11
+
12
+ `git diff --cached` + `git diff --cached --name-only` 同时扫文件名和内容。
13
+
14
+ ### 禁止提交的文件
15
+
16
+ | 类型 | 示例 |
17
+ |---|---|
18
+ | 环境变量 | `.env`, `.env.*`, `*.env` |
19
+ | SSH 密钥 | `id_rsa`, `id_ed25519`, `*.pem`, `*.key` |
20
+ | 证书 | `*.p12`, `*.pfx`, `*.jks`, `*.keystore` |
21
+ | 数据库 | `*.sql`(含真实数据)、`*.dump`, `*.sqlite` |
22
+ | 原始数据 | `*.xlsx`, `*.csv`(含用户/学生等敏感数据) |
23
+ | 日志 | `*.log` |
24
+ | Docker 卷 | `pgdata/`, `cache/*.json` |
25
+
26
+ ### 禁止出现的敏感内容
27
+
28
+ **总则**:代码、文档、规则文件、注释里禁止出现真实的 API Key / Token / 密码 / IP / 凭证,即使作为"示例"也不行。GitHub Secret Scanning 不区分上下文,真实格式的 key 写在文档里也会触发泄露告警。示例必须用明显假值(`sk-xxxxxxxxxxxx`、`your-key-here`、`192.168.x.x`)。
29
+
30
+ | 类型 | 匹配模式 |
31
+ |---|---|
32
+ | API Key | `sk-[a-zA-Z0-9]{20,}` |
33
+ | AWS Key | `AKIA[0-9A-Z]{16}` |
34
+ | GitHub Token | `ghp_[a-zA-Z0-9]{36}` |
35
+ | 密码赋值 | `password\s*[:=]\s*["'][^"']{4,}` |
36
+ | 数据库连接串 | `://\w+:[^@\s]+@`(含密码) |
37
+ | 私钥内容 | `-----BEGIN (RSA \|EC )?PRIVATE KEY-----` |
38
+ | Token 赋值 | `token\s*[:=]\s*["'][a-zA-Z0-9_\-]{20,}` |
39
+ | Secret 赋值 | `secret\s*[:=]\s*["'][^"']{8,}` |
40
+ | 服务器 IP+端口 | `\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+` |
41
+ | SSH 连接 | `ssh\s+.*@\d{1,3}\.\d{1,3}` |
42
+
43
+ **例外(不算违规)**:`.env.example` 占位符;从环境变量读取(`os.getenv("API_KEY")`);`localhost` / `127.0.0.1` 的连接串;文档假数据;配置文件空字符串默认值。
44
+
45
+ ### 违规处理
46
+
47
+ 1. **立即停止** `git add` / `git commit`
48
+ 2. **列出违规项**:文件 + 行号 + 匹配的敏感模式 + 脱敏摘要(如 `sk-5522****dc3`)
49
+ 3. **建议修复**:加入 `.gitignore` / 移到 `.env` / 改用环境变量 / 替换为占位符
50
+ 4. **等用户明确确认**后才能继续;确认强制提交时,commit body 附 `GIT-SECURITY: 用户已确认提交此内容`
51
+
52
+ ## Step 1: 分析变更
53
+
54
+ `git diff --cached` 回答:这次改做了几件事?涉及哪些模块?
55
+
56
+ **做了多件事(无法用 ≤72 字符 subject 清晰描述)→ 必须拆成多个 commit。**
57
+
58
+ ## Step 2: 确定 scope
59
+
60
+ 读当前项目 CLAUDE.md 的 `## Git Commit Scope` 段:
61
+
62
+ - **找到** → scope 从枚举值中选,不得自造
63
+ - **没找到** → 提醒用户「当前项目 CLAUDE.md 未定义 Git Commit Scope,建议添加」,scope 可省略
64
+
65
+ 单模块变更 → **必须**带 scope;跨模块变更 → 省略 scope。
66
+
67
+ ## Step 3: 生成 message
68
+
69
+ 格式:`<type>(<scope>): <subject>` 或(无 scope)`<type>: <subject>`
70
+
71
+ **type 枚举(只能从中选)**:
72
+
73
+ | type | 用途 |
74
+ |------|------|
75
+ | feat | 新功能 |
76
+ | fix | 修复 bug |
77
+ | refactor | 重构(不改外部行为) |
78
+ | chore | 构建/依赖/配置/发版等杂务 |
79
+ | docs | 文档 |
80
+ | test | 测试 |
81
+ | perf | 性能优化 |
82
+ | style | 代码格式(不影响逻辑) |
83
+ | ci | CI/CD 配置 |
84
+
85
+ **subject**:中文、无句号、≤72 字符、动宾短语(添加/修复/移除/重构/升级)。
86
+
87
+ **body(可选)**:空一行后写;中文;只写 why 不复述 what;破坏性变更加 `BREAKING CHANGE:` 前缀(subject 用 `feat!:` / `fix!:` 标记)。
88
+
89
+ ## Step 4: 禁止大模型署名
90
+
91
+ commit message(subject、body、footer、trailer)**禁止出现任何大模型 / AI 工具相关内容**,覆盖系统默认的 `Co-Authored-By` 追加行为。
92
+
93
+ **禁止出现(不完全列举)**:
94
+
95
+ - `Co-Authored-By: Claude ...` / `Co-Authored-By: GPT ...` / `Co-Authored-By: Copilot ...` 等 AI 署名 trailer
96
+ - `Generated with Claude Code` / `🤖 Generated with ...` 等生成声明
97
+ - `noreply@anthropic.com` / `noreply@openai.com` 等 AI 厂商邮箱
98
+ - 任何提到 Claude / ChatGPT / GPT / Copilot / Cursor / AI / 大模型 / LLM 的字样
99
+
100
+ **执行要点**:
101
+
102
+ - `git commit -m "..."` 只写规范内容,**绝不**附加 `Co-Authored-By` trailer
103
+ - HEREDOC 传 message 时,HEREDOC 内容也不得包含上述字样
104
+ - 暂存的 message 含大模型信息 → **立即删除**后再提交
105
+
106
+ ## 常见错误 vs 正确
107
+
108
+ | 错误 | 正确 |
109
+ |------|------|
110
+ | `feat: add user login`(英文) | `feat: 添加用户登录功能` |
111
+ | `fix(eui): 修复了按钮样式。` | `fix(eui): 修复按钮样式`(无句号、不用"了") |
112
+ | `feat: 添加登录并修复登出 bug` | 拆成两个 commit |
113
+ | `update: 修改配置` | `update` 不在枚举,应为 `chore` |
114
+ | `feat(auth): ...`(项目无 auth scope) | 用项目已定义的 scope 值 |
115
+ | message 末尾加 `Co-Authored-By: Claude ...` | 不加任何 AI 署名 trailer |
116
+ | `🤖 Generated with Claude Code` | 不加任何生成声明 |
117
+
118
+ ## 正确示例
119
+
120
+ - `feat(eui): 添加 Image 组件,支持懒加载`
121
+ - `fix: 修复 token 刷新竞态条件`
122
+ - `refactor(backend): 提取分页逻辑为共享工具`
123
+ - `chore: 升级 Vite 至 8.x`
124
+ - `feat(eui)!: 重命名 EDialog open 属性为 v-model:open`
125
+ - body:`BREAKING CHANGE: EDialog 不再接受 visible 属性,请改用 v-model:open`
@@ -103,7 +103,7 @@ description: "发布版本:测试 → bump → changelog → build → publish
103
103
  # 暂存变更(version + changelog)
104
104
  git add <changed-files>
105
105
 
106
- # 提交(遵循 dwy-git-commit-convention)
106
+ # 提交(遵循 dwy-git-commit)
107
107
  git commit -m "chore(<scope>): release v<version>"
108
108
 
109
109
  # 打 tag(按 Release 配置的命名规则)
@@ -1,10 +1,11 @@
1
1
  ---
2
- description: 跨栈技术选型强制约束(FastAPI/Vue3/Flutter/UV/pnpm/Docker/S3 等,全局加载)
2
+ name: dwy-tech-stack
3
+ description: 跨栈技术选型强制约束(FastAPI / Vue 3 / Flutter / UV / pnpm / Docker / S3 / DolphinDB 等)。触发场景:用户提到「用什么 ORM / 缓存 / 状态管理 / 路由 / 包管理 / 组件库」/ 引入新依赖 / 替换现有库 / 调研选型 / 新项目初始化 / 架构评估;AI 准备执行 `pnpm add` / `uv add` / `pip install` / `flutter pub add` / `npm install` 前;讨论涉及后端 Web 框架、ORM、关系数据库、缓存、消息队列、异步任务、JWT / 密码哈希、Linter;前端 Vue 框架、构建工具、组件库、状态管理、样式方案、表单校验、测试;移动端 Flutter、状态管理、HTTP 客户端、路由、本地存储、代码生成;容器化、对象存储、时序数据库时。强制:每个领域只有唯一方案,AI 不得选替代,不得「建议改用 XX」。
3
4
  ---
4
5
 
5
6
  # 跨栈技术选型强制约束
6
7
 
7
- 每个领域只有一个方案,AI 不得选替代,不得"建议改用 XX"。
8
+ 每个领域只有一个方案,AI 不得选替代,不得「建议改用 XX」。
8
9
 
9
10
  ## 后端
10
11
 
@@ -23,7 +24,7 @@ description: 跨栈技术选型强制约束(FastAPI/Vue3/Flutter/UV/pnpm/Docker/
23
24
  | 基础设施层 | dwyeapi | 自造框架、手写基础设施 |
24
25
  | Linter/Formatter | Ruff | Black, isort, flake8, pylint |
25
26
 
26
- ## 前端(Web)
27
+ ## 前端(Web)
27
28
 
28
29
  | 领域 | 唯一方案 | 禁止替代 |
29
30
  |------|---------|---------|
@@ -0,0 +1,81 @@
1
+ # {{projectName}}
2
+
3
+ {{projectDescription}}
4
+
5
+ ## 架构
6
+
7
+ Monorepo 全栈骨架:
8
+
9
+ ```
10
+ {{projectName}}/
11
+ ├── backend/ # FastAPI 后端(uv workspace + 域分包)
12
+ ├── frontend/ # Vue 3 前端(pnpm workspace + catalog)
13
+ ├── docker-compose.dev.yml # PostgreSQL + Redis 基础设施
14
+ ├── dev.sh # 一键启动脚本
15
+ └── .env.example
16
+ ```
17
+
18
+ 详细约束见各子目录的 `CLAUDE.md`。
19
+
20
+ ## 端口约定
21
+
22
+ 本项目用 `{{portPrefix}}xxxx` 万位前缀避免与其他项目冲突:
23
+
24
+ | 服务 | 端口 |
25
+ |------|------|
26
+ | Backend | `127.0.0.1:{{portPrefix}}8001` |
27
+ | Frontend | `127.0.0.1:{{portPrefix}}5173` |
28
+ | PostgreSQL | `127.0.0.1:{{portPrefix}}5432` |
29
+ | Redis | `127.0.0.1:{{portPrefix}}6379` |
30
+
31
+ ## 启动
32
+
33
+ ```bash
34
+ # 1. 复制环境变量
35
+ cp .env.example .env
36
+
37
+ # 2. 安装依赖
38
+ cd backend && uv sync --dev && cd ..
39
+ cd frontend && pnpm install && cd ..
40
+
41
+ # 3. 一键启动(Docker + backend + frontend)
42
+ ./dev.sh
43
+ ```
44
+
45
+ ## 常用命令
46
+
47
+ ```bash
48
+ # Backend
49
+ cd backend
50
+ uv sync --dev # 安装依赖
51
+ uv run uvicorn app.main:app --reload # 单独启 backend
52
+ uv run pytest tests/ -v # 测试
53
+ uv run ruff check src/ && uv run ruff format src/
54
+
55
+ # Frontend
56
+ cd frontend
57
+ pnpm install
58
+ pnpm dev # 单独启 frontend
59
+ pnpm build
60
+ pnpm typecheck
61
+
62
+ # 数据库迁移
63
+ cd backend
64
+ uv run alembic revision --autogenerate -m "msg"
65
+ uv run alembic upgrade head
66
+ ```
67
+
68
+ ## 核心架构模式
69
+
70
+ 1. **单一版本中心**:backend `pyproject.toml` 集中管理外部依赖版本;frontend `pnpm-workspace.yaml` 的 `catalog:` 集中管理 npm 依赖版本。子包只写包名不写版本。
71
+ 2. **装配层**:`backend/src/app/main.py` 只做装配,业务逻辑在 `backend/packages/{{scopePrefix}}-<domain>/` 内。
72
+ 3. **域分包**:每个业务包按域子目录,域内分 router / service / schemas / models / protocols 五件套。
73
+ 4. **Provider 模式**:外部服务(DB / Redis / SMS / OSS / 第三方 API)抽象为 Protocol,`factories.py` 按 settings 选具体实现。
74
+ 5. **dwy- vs 业务-前缀**:`packages/dwy-*` 是跨项目可复用 kernel;`packages/{{scopePrefix}}-*` 是项目业务专属。
75
+ 6. **dwyeapi 优先**:后端基础设施先用 dwyeapi(配置/异常/分页/缓存),不重复实现。
76
+
77
+ ## 加新业务
78
+
79
+ **Backend**:复制 `backend/packages/{{scopePrefix}}-{{initialDomain}}/` 整体改名 → 改 `pyproject.toml` 的 `name` → 改 `src/<scope_domain>/__init__.py` 的 `register()` → 在 `src/app/main.py` 装载。
80
+
81
+ **Frontend**:复制 `frontend/packages/features/{{initialDomain}}/` 改名 → 在 `frontend/apps/web/src/router/index.ts` 注册路由。