create-dwy 0.5.1 → 0.6.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 (156) hide show
  1. package/bin/index.js +1 -1
  2. package/package.json +2 -2
  3. package/src/create.js +61 -37
  4. package/src/sync.js +212 -61
  5. package/templates/claude-global/CLAUDE.md +92 -0
  6. package/templates/claude-global/rules/dwy-android-core.md +610 -0
  7. package/templates/claude-global/rules/dwy-api-design.md +110 -0
  8. package/templates/claude-global/rules/dwy-db-migration.md +46 -0
  9. package/templates/claude-global/rules/dwy-flutter-core.md +564 -0
  10. package/templates/claude-global/rules/dwy-flutter-network.md +222 -0
  11. package/templates/claude-global/rules/dwy-flutter-router.md +97 -0
  12. package/templates/claude-global/rules/dwy-flutter-testing.md +94 -0
  13. package/templates/claude-global/rules/dwy-git-commit-convention.md +82 -0
  14. package/templates/claude-global/rules/dwy-git-security.md +53 -0
  15. package/templates/claude-global/rules/dwy-payload-limits.md +178 -0
  16. package/templates/claude-global/rules/{prefer-open-source.md → dwy-prefer-open-source.md} +4 -0
  17. package/templates/claude-global/rules/dwy-project-structure.md +181 -0
  18. package/templates/claude-global/rules/{python-code-style.md → dwy-python-core.md} +292 -358
  19. package/templates/claude-global/rules/dwy-python-fastapi.md +272 -0
  20. package/templates/claude-global/rules/dwy-python-orm.md +61 -0
  21. package/templates/claude-global/rules/{backend-security.md → dwy-python-security.md} +99 -72
  22. package/templates/claude-global/rules/dwy-python-testing.md +53 -0
  23. package/templates/claude-global/rules/{server-security.md → dwy-server-security.md} +1 -2
  24. package/templates/claude-global/rules/dwy-tdd-development.md +70 -0
  25. package/templates/claude-global/rules/dwy-tech-stack.md +60 -0
  26. package/templates/claude-global/rules/dwy-vue-api.md +146 -0
  27. package/templates/claude-global/rules/{vue-code-style.md → dwy-vue-core.md} +338 -152
  28. package/templates/claude-global/rules/dwy-vue-pinia.md +75 -0
  29. package/templates/claude-global/rules/dwy-vue-testing.md +102 -0
  30. package/templates/claude-global/skills/dwy-deploy-audit/SKILL.md +481 -0
  31. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-data.md +117 -0
  32. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-network.md +74 -0
  33. package/templates/claude-global/skills/dwy-deploy-audit/references/checks-runtime.md +184 -0
  34. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_base.sh +39 -0
  35. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_capacity.sh +278 -0
  36. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_db.sh +122 -0
  37. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_docker.sh +249 -0
  38. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_env.sh +64 -0
  39. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_https.sh +60 -0
  40. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_logs.sh +209 -0
  41. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_nginx.sh +92 -0
  42. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_resilience.sh +157 -0
  43. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_secrets.sh +327 -0
  44. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_services.sh +77 -0
  45. package/templates/claude-global/skills/dwy-deploy-audit/scripts/check_ssh.sh +56 -0
  46. package/templates/claude-global/skills/dwy-deploy-audit/scripts/run_all.sh +105 -0
  47. package/templates/claude-global/skills/dwy-docker/SKILL.md +187 -0
  48. package/templates/claude-global/skills/dwy-docker/references/ask-templates.md +142 -0
  49. package/templates/claude-global/skills/dwy-docker/references/templates.md +479 -0
  50. package/templates/claude-global/skills/dwy-docker/references/version-rules.md +76 -0
  51. package/templates/claude-global/skills/dwy-docker/scripts/query_dockerhub.py +204 -0
  52. package/templates/claude-global/skills/dwy-docker/scripts/scan_images.sh +185 -0
  53. package/templates/claude-global/skills/dwy-eapi/SKILL.md +433 -0
  54. package/templates/claude-global/skills/dwy-eapi/references/tasks-integration-guide.md +387 -0
  55. package/templates/claude-global/skills/dwy-ekit/SKILL.md +85 -0
  56. package/templates/claude-global/skills/dwy-ekit/references/data.md +135 -0
  57. package/templates/claude-global/skills/dwy-ekit/references/form.md +68 -0
  58. package/templates/claude-global/skills/dwy-ekit/references/request.md +183 -0
  59. package/templates/claude-global/skills/dwy-ekit/references/ui.md +109 -0
  60. package/templates/claude-global/skills/{dwy-frontend-eui → dwy-eui}/SKILL.md +129 -15
  61. package/templates/claude-global/skills/dwy-eui/references/eui-design-guide.md +257 -0
  62. package/templates/claude-global/skills/dwy-eui/references/eui-integration-guide.md +302 -0
  63. package/templates/claude-global/skills/dwy-eui/references/eui-landing-design-guide.md +437 -0
  64. package/templates/claude-global/skills/dwy-fullstack-scaffold/SKILL.md +214 -0
  65. package/templates/claude-global/skills/dwy-mirror-source/SKILL.md +275 -0
  66. package/templates/claude-global/skills/dwy-mirror-source/references/dockerfile-snippets.md +228 -0
  67. package/templates/claude-global/skills/dwy-mirror-source/references/mirror-providers.md +150 -0
  68. package/templates/claude-global/skills/dwy-mirror-source/scripts/__pycache__/check_mirrors.cpython-313.pyc +0 -0
  69. package/templates/claude-global/skills/dwy-mirror-source/scripts/apply_mirrors.py +666 -0
  70. package/templates/claude-global/skills/dwy-mirror-source/scripts/check_mirrors.py +868 -0
  71. package/templates/claude-global/skills/dwy-pentest/SKILL.md +344 -0
  72. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__init__.py +1 -0
  73. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/__init__.cpython-311.pyc +0 -0
  74. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/config.cpython-311.pyc +0 -0
  75. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/executor.cpython-311.pyc +0 -0
  76. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/severity.cpython-311.pyc +0 -0
  77. package/templates/claude-global/skills/dwy-pentest/scripts/lib/__pycache__/validator.cpython-311.pyc +0 -0
  78. package/templates/claude-global/skills/dwy-pentest/scripts/lib/config.py +109 -0
  79. package/templates/claude-global/skills/dwy-pentest/scripts/lib/executor.py +157 -0
  80. package/templates/claude-global/skills/dwy-pentest/scripts/lib/severity.py +96 -0
  81. package/templates/claude-global/skills/dwy-pentest/scripts/lib/validator.py +113 -0
  82. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_auth.py +289 -0
  83. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_recon.py +217 -0
  84. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_report.py +343 -0
  85. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_scan.py +205 -0
  86. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_ssl.py +208 -0
  87. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_vuln.py +205 -0
  88. package/templates/claude-global/skills/dwy-pentest/scripts/pentest_web.py +330 -0
  89. package/templates/claude-global/skills/dwy-pentest/scripts/pyproject.toml +14 -0
  90. package/templates/claude-global/skills/dwy-pentest/scripts/setup_tools.sh +97 -0
  91. package/templates/claude-global/skills/dwy-pentest/scripts/uv.lock +415 -0
  92. package/templates/claude-global/skills/{dwy-release → dwy-publish}/SKILL.md +42 -18
  93. package/templates/claude-global/skills/dwy-vue-core/SKILL.md +890 -0
  94. package/templates/project/backend/.dwy.hbs +5 -0
  95. package/templates/project/backend/.python-version +1 -0
  96. package/templates/project/backend/CLAUDE.md.hbs +40 -0
  97. package/templates/project/{web/backend → backend}/alembic/script.py.mako +2 -0
  98. package/templates/project/{web/backend → backend}/alembic.ini.hbs +0 -1
  99. package/templates/project/backend/deploy.sh.hbs +18 -0
  100. package/templates/project/{web → backend}/docker-compose.prod.yml.hbs +1 -1
  101. package/templates/project/{web/backend → backend}/pyproject.toml.hbs +4 -5
  102. package/templates/project/{web/backend → backend}/src/app/config.py.hbs +1 -1
  103. package/templates/project/backend/src/app/database.py +10 -0
  104. package/templates/project/backend/src/app/dependencies.py +5 -0
  105. package/templates/project/{web/backend → backend}/src/app/main.py.hbs +3 -3
  106. package/templates/project/backend/src/app/models/base.py +5 -0
  107. package/templates/project/web/CLAUDE.md.hbs +29 -36
  108. package/templates/project/web/{frontend → apps/web}/index.html.hbs +1 -0
  109. package/templates/project/web/{frontend → apps/web}/package.json.hbs +4 -3
  110. package/templates/project/web/apps/web/src/App.vue +9 -0
  111. package/templates/project/web/apps/web/src/api/client.ts +5 -0
  112. package/templates/project/web/apps/web/src/composables/.gitkeep +0 -0
  113. package/templates/project/web/apps/web/src/layouts/DefaultLayout.vue +8 -0
  114. package/templates/project/web/{frontend → apps/web}/src/router/index.ts +1 -1
  115. package/templates/project/web/{frontend → apps/web}/src/stores/auth.ts +4 -2
  116. package/templates/project/web/apps/web/src/style.css +2 -0
  117. package/templates/project/web/apps/web/src/types/router.d.ts +8 -0
  118. package/templates/project/web/apps/web/src/views/HomeView.vue +8 -0
  119. package/templates/project/web/apps/web/tsconfig.app.json +18 -0
  120. package/templates/project/web/apps/web/tsconfig.json +6 -0
  121. package/templates/project/web/{frontend → apps/web}/vite.config.ts.hbs +7 -1
  122. package/templates/project/web/package.json.hbs +16 -0
  123. package/templates/project/web/packages/.gitkeep +0 -0
  124. package/templates/project/web/pnpm-workspace.yaml +3 -0
  125. package/templates/claude-global/hooks/post-sync-claude-global.sh +0 -72
  126. package/templates/claude-global/rules/agent-team-execution.md +0 -138
  127. package/templates/claude-global/rules/agent-team-patterns.md +0 -157
  128. package/templates/claude-global/rules/git-commit-convention.md +0 -106
  129. package/templates/claude-global/rules/git-security.md +0 -144
  130. package/templates/claude-global/skills/dwy-backend-base/SKILL.md +0 -279
  131. package/templates/claude-global/skills/dwy-frontend-core/SKILL.md +0 -181
  132. package/templates/project/web/.claude/commands/deploy.md +0 -4
  133. package/templates/project/web/backend/src/app/models/base.py +0 -5
  134. package/templates/project/web/deploy.sh.hbs +0 -113
  135. package/templates/project/web/frontend/src/App.vue +0 -3
  136. package/templates/project/web/frontend/src/api/client.ts +0 -13
  137. package/templates/project/web/frontend/src/style.css +0 -1
  138. package/templates/project/web/frontend/src/views/HomeView.vue +0 -5
  139. package/templates/project/web/frontend/tsconfig.app.json +0 -14
  140. package/templates/project/web/frontend/tsconfig.json +0 -4
  141. /package/templates/{project/web/backend → claude-global/skills/dwy-pentest/scripts}/.python-version +0 -0
  142. /package/templates/project/{web/backend → backend}/Dockerfile +0 -0
  143. /package/templates/project/{web/backend → backend}/alembic/env.py.hbs +0 -0
  144. /package/templates/{claude-global/skills → project/backend/alembic/versions}/.gitkeep +0 -0
  145. /package/templates/project/{web → backend}/docker-compose.dev.yml.hbs +0 -0
  146. /package/templates/project/{web/backend → backend}/src/app/__init__.py +0 -0
  147. /package/templates/project/{web/backend → backend}/src/app/models/__init__.py +0 -0
  148. /package/templates/project/{web/backend → backend}/src/app/routers/__init__.py +0 -0
  149. /package/templates/project/{web/backend → backend}/src/app/routers/health.py +0 -0
  150. /package/templates/project/{web/backend → backend}/src/app/schemas/__init__.py +0 -0
  151. /package/templates/project/{web/backend → backend}/src/app/services/__init__.py +0 -0
  152. /package/templates/project/{web/backend → backend}/tests/__init__.py +0 -0
  153. /package/templates/project/{web/backend → backend}/tests/conftest.py.hbs +0 -0
  154. /package/templates/project/{web/backend/alembic/versions → mobile}/.gitkeep +0 -0
  155. /package/templates/project/web/{frontend → apps/web}/src/components/.gitkeep +0 -0
  156. /package/templates/project/web/{frontend → apps/web}/src/main.ts +0 -0
@@ -0,0 +1,437 @@
1
+ # EUI 落地页设计风格规范
2
+
3
+ > AI 使用 @dwydev/eui 编写落地页时必须遵循此规范。
4
+ > 本规范与 `eui-design-guide.md`(中后台规范)互补,落地页特有规则在此定义,通用规则(颜色系统、暗色模式、ESelect 约束等)仍遵循中后台规范。
5
+
6
+ ## 一、落地页 vs 中后台的核心差异
7
+
8
+ | 维度 | 中后台 | 落地页 |
9
+ |------|--------|--------|
10
+ | 目标 | 操作效率、信息密度 | 转化率、品牌传达 |
11
+ | 字号 | `text-sm` ~ `text-2xl` | `text-base` ~ `text-6xl` |
12
+ | 留白 | 紧凑 `p-6 gap-6` | 大量 `py-16 lg:py-24` |
13
+ | 宽度 | 满屏利用 | `max-w-6xl mx-auto` 居中 |
14
+ | 响应式 | 最小 `md`(768px) | 最小 `sm`(375px),手机优先 |
15
+ | 阴影 | `shadow-xs` / `shadow-sm` | 可用 `shadow-md` / `shadow-lg` |
16
+ | 动画 | 几乎不用 | 适度滚动入场动画 |
17
+
18
+ ## 二、页面结构模板
19
+
20
+ ### 通用 Section 结构
21
+
22
+ 落地页由多个全宽 Section 垂直堆叠,每个 Section 内部居中限宽:
23
+
24
+ ```vue
25
+ <section class="py-16 lg:py-24">
26
+ <div class="max-w-6xl mx-auto px-6">
27
+ <!-- Section 内容 -->
28
+ </div>
29
+ </section>
30
+ ```
31
+
32
+ ### 标准 Section 顺序
33
+
34
+ | 序号 | Section | 目的 | 必须 |
35
+ |------|---------|------|------|
36
+ | 1 | Hero | 核心价值主张 + 主 CTA | 是 |
37
+ | 2 | 社会证明 | 客户 Logo 墙 / 数字指标 | 推荐 |
38
+ | 3 | 功能/特性 | 3-4 个核心卖点 | 是 |
39
+ | 4 | 产品展示 | 截图 / 动图 / 视频 | 推荐 |
40
+ | 5 | 用户评价 | 真实用户推荐语 | 推荐 |
41
+ | 6 | 定价方案 | 2-3 档价格卡片 | 可选 |
42
+ | 7 | FAQ | 常见疑虑解答 | 推荐 |
43
+ | 8 | 底部 CTA | 再次强调行动号召 | 是 |
44
+ | 9 | Footer | 链接 / 版权 / 备案 | 是 |
45
+
46
+ 可根据产品类型增减,但 **Hero + 功能 + 底部 CTA + Footer** 是最小集。
47
+
48
+ ## 三、导航栏
49
+
50
+ ```vue
51
+ <header class="fixed top-0 inset-x-0 z-50 border-b bg-background/80 backdrop-blur-sm">
52
+ <div class="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
53
+ <!-- Logo -->
54
+ <a href="/" class="text-lg font-semibold">Brand</a>
55
+
56
+ <!-- 导航链接(桌面端) -->
57
+ <nav class="hidden md:flex items-center gap-6 text-sm text-muted-foreground">
58
+ <a href="#features" class="hover:text-foreground transition-colors">功能</a>
59
+ <a href="#pricing" class="hover:text-foreground transition-colors">定价</a>
60
+ <a href="#faq" class="hover:text-foreground transition-colors">FAQ</a>
61
+ </nav>
62
+
63
+ <!-- CTA -->
64
+ <div class="flex items-center gap-2">
65
+ <EButton variant="ghost" size="sm">登录</EButton>
66
+ <EButton size="sm">免费试用</EButton>
67
+ </div>
68
+ </div>
69
+ </header>
70
+ ```
71
+
72
+ 规则:
73
+ - `fixed` 定位 + `backdrop-blur-sm` 毛玻璃效果
74
+ - `bg-background/80` 半透明,不用纯色遮挡
75
+ - 内容区 `max-w-6xl mx-auto px-6` 与 Section 对齐
76
+ - 移动端隐藏导航链接(`hidden md:flex`),用汉堡菜单或只保留 CTA
77
+ - 页面 `scroll-behavior: smooth` 锚点平滑滚动
78
+
79
+ ## 四、Hero Section
80
+
81
+ ```vue
82
+ <section class="pt-32 pb-16 lg:pb-24">
83
+ <div class="max-w-6xl mx-auto px-6 text-center">
84
+ <!-- 标签 -->
85
+ <EBadge variant="secondary" class="mb-4">全新发布 v2.0</EBadge>
86
+
87
+ <!-- 主标题 -->
88
+ <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight">
89
+ 一句话说清<span class="text-primary">核心价值</span>
90
+ </h1>
91
+
92
+ <!-- 副标题 -->
93
+ <p class="mt-6 text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto leading-relaxed">
94
+ 用一两句话补充说明,解决什么问题,给谁用。
95
+ </p>
96
+
97
+ <!-- CTA 按钮组 -->
98
+ <div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
99
+ <EButton size="lg">免费开始</EButton>
100
+ <EButton variant="outline" size="lg">查看演示</EButton>
101
+ </div>
102
+
103
+ <!-- 产品截图 -->
104
+ <div class="mt-16 rounded-xl border shadow-lg overflow-hidden">
105
+ <img src="/hero-screenshot.png" alt="产品截图" class="w-full" />
106
+ </div>
107
+ </div>
108
+ </section>
109
+ ```
110
+
111
+ 规则:
112
+ - `pt-32` 给固定导航栏留空间
113
+ - 标题 `text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight`
114
+ - 关键词用 `text-primary` 高亮,不超过一处
115
+ - 副标题 `max-w-2xl mx-auto` 控制行宽(65-75 字符)
116
+ - CTA 按钮用 `size="lg"`,主次分明
117
+ - 移动端 CTA 纵向排列(`flex-col sm:flex-row`)
118
+
119
+ ## 五、功能/特性 Section
120
+
121
+ ### 3 列卡片网格
122
+
123
+ ```vue
124
+ <section id="features" class="py-16 lg:py-24">
125
+ <div class="max-w-6xl mx-auto px-6">
126
+ <div class="text-center mb-12">
127
+ <h2 class="text-3xl font-bold">核心功能</h2>
128
+ <p class="mt-3 text-lg text-muted-foreground">一句话描述</p>
129
+ </div>
130
+
131
+ <div class="grid md:grid-cols-3 gap-8">
132
+ <div v-for="feature in features" :key="feature.title"
133
+ class="rounded-lg border bg-card p-6 hover:shadow-md transition-shadow"
134
+ >
135
+ <div class="size-10 rounded-md bg-primary/10 flex items-center justify-center mb-4">
136
+ <component :is="feature.icon" class="size-5 text-primary" />
137
+ </div>
138
+ <h3 class="text-lg font-semibold mb-2">{{ feature.title }}</h3>
139
+ <p class="text-sm text-muted-foreground leading-relaxed">{{ feature.description }}</p>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </section>
144
+ ```
145
+
146
+ 规则:
147
+ - 桌面 3 列(`md:grid-cols-3`),移动端单列自动堆叠
148
+ - 图标用 `bg-primary/10` 浅色底 + `text-primary` 图标色
149
+ - 卡片 hover 用 `hover:shadow-md transition-shadow`,不缩放
150
+ - 功能数量 3、4、6 个,保持网格整齐
151
+
152
+ ### 左右交替布局
153
+
154
+ ```vue
155
+ <div class="grid md:grid-cols-2 gap-12 items-center">
156
+ <div :class="index % 2 === 1 && 'md:order-2'">
157
+ <img :src="feature.image" :alt="feature.title" class="rounded-lg border" />
158
+ </div>
159
+ <div>
160
+ <h3 class="text-2xl font-bold mb-4">{{ feature.title }}</h3>
161
+ <p class="text-muted-foreground leading-relaxed">{{ feature.description }}</p>
162
+ </div>
163
+ </div>
164
+ ```
165
+
166
+ 适合有产品截图的场景,左图右文 / 右图左文交替。
167
+
168
+ ## 六、社会证明
169
+
170
+ ### Logo 墙
171
+
172
+ ```vue
173
+ <section class="py-12 border-y bg-muted/30">
174
+ <div class="max-w-6xl mx-auto px-6">
175
+ <p class="text-center text-sm text-muted-foreground mb-8">
176
+ 受到以下企业信赖
177
+ </p>
178
+ <div class="flex flex-wrap items-center justify-center gap-x-12 gap-y-6 opacity-60">
179
+ <!-- SVG Logos,不用 emoji -->
180
+ </div>
181
+ </div>
182
+ </section>
183
+ ```
184
+
185
+ ### 数字指标
186
+
187
+ ```vue
188
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
189
+ <div v-for="stat in stats" :key="stat.label">
190
+ <p class="text-3xl md:text-4xl font-bold text-primary">{{ stat.value }}</p>
191
+ <p class="mt-1 text-sm text-muted-foreground">{{ stat.label }}</p>
192
+ </div>
193
+ </div>
194
+ ```
195
+
196
+ 规则:
197
+ - Logo 统一灰度 + 降低透明度(`opacity-60`),不抢主视觉
198
+ - 数字指标 2-4 个,数值用 `text-primary font-bold`
199
+
200
+ ## 七、用户评价
201
+
202
+ ```vue
203
+ <section class="py-16 lg:py-24 bg-muted/30">
204
+ <div class="max-w-6xl mx-auto px-6">
205
+ <h2 class="text-3xl font-bold text-center mb-12">用户怎么说</h2>
206
+
207
+ <div class="grid md:grid-cols-3 gap-6">
208
+ <div v-for="t in testimonials" :key="t.name"
209
+ class="rounded-lg border bg-card p-6"
210
+ >
211
+ <p class="text-sm leading-relaxed mb-4">"{{ t.content }}"</p>
212
+ <div class="flex items-center gap-3">
213
+ <EAvatar :src="t.avatar" :alt="t.name" size="sm" />
214
+ <div>
215
+ <p class="text-sm font-medium">{{ t.name }}</p>
216
+ <p class="text-xs text-muted-foreground">{{ t.title }}</p>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ </section>
223
+ ```
224
+
225
+ 规则:
226
+ - 3-5 条评价,有头像 + 姓名 + 职位
227
+ - 评价区背景用 `bg-muted/30` 区分层级
228
+ - 引号用中文引号,不用 `""`
229
+
230
+ ## 八、定价 Section
231
+
232
+ ```vue
233
+ <section id="pricing" class="py-16 lg:py-24">
234
+ <div class="max-w-5xl mx-auto px-6">
235
+ <div class="text-center mb-12">
236
+ <h2 class="text-3xl font-bold">简单透明的定价</h2>
237
+ <p class="mt-3 text-lg text-muted-foreground">选择适合你的方案</p>
238
+ </div>
239
+
240
+ <div class="grid md:grid-cols-3 gap-6">
241
+ <div v-for="plan in plans" :key="plan.name"
242
+ :class="[
243
+ 'rounded-xl border p-8 flex flex-col',
244
+ plan.popular ? 'border-primary shadow-lg relative' : '',
245
+ ]"
246
+ >
247
+ <EBadge v-if="plan.popular" class="absolute -top-3 left-1/2 -translate-x-1/2">
248
+ 最受欢迎
249
+ </EBadge>
250
+ <h3 class="text-lg font-semibold">{{ plan.name }}</h3>
251
+ <p class="text-sm text-muted-foreground mt-1">{{ plan.description }}</p>
252
+ <div class="mt-6">
253
+ <span class="text-4xl font-bold">{{ plan.price }}</span>
254
+ <span class="text-muted-foreground"> /月</span>
255
+ </div>
256
+ <ul class="mt-6 space-y-3 flex-1">
257
+ <li v-for="f in plan.features" :key="f" class="flex items-center gap-2 text-sm">
258
+ <Check class="size-4 text-primary shrink-0" />
259
+ {{ f }}
260
+ </li>
261
+ </ul>
262
+ <EButton
263
+ :variant="plan.popular ? 'default' : 'outline'"
264
+ class="mt-8 w-full"
265
+ >
266
+ {{ plan.cta }}
267
+ </EButton>
268
+ </div>
269
+ </div>
270
+ </div>
271
+ </section>
272
+ ```
273
+
274
+ 规则:
275
+ - 2-3 档,推荐档用 `border-primary shadow-lg` 高亮
276
+ - "最受欢迎"用 `EBadge` 浮在卡片顶部
277
+ - 价格 `text-4xl font-bold`,单位 `text-muted-foreground`
278
+ - 功能列表用 Check 图标 + `text-primary`
279
+ - 推荐档 CTA 用 `default` variant,其他用 `outline`
280
+
281
+ ## 九、FAQ Section
282
+
283
+ ```vue
284
+ <section id="faq" class="py-16 lg:py-24">
285
+ <div class="max-w-3xl mx-auto px-6">
286
+ <h2 class="text-3xl font-bold text-center mb-12">常见问题</h2>
287
+ <EAccordion type="single" collapsible :items="faqItems" />
288
+ </div>
289
+ </section>
290
+ ```
291
+
292
+ 规则:
293
+ - 内容区 `max-w-3xl`(比其他 Section 窄,阅读舒适)
294
+ - 用 EUI 的 `<EAccordion>` 组件
295
+ - 5-8 个问题
296
+
297
+ ## 十、底部 CTA
298
+
299
+ ```vue
300
+ <section class="py-16 lg:py-24 bg-primary text-primary-foreground">
301
+ <div class="max-w-4xl mx-auto px-6 text-center">
302
+ <h2 class="text-3xl md:text-4xl font-bold">准备好开始了吗?</h2>
303
+ <p class="mt-4 text-lg opacity-90">一句话再次强调价值</p>
304
+ <div class="mt-8 flex flex-col sm:flex-row items-center justify-center gap-4">
305
+ <EButton size="lg" variant="secondary">免费开始</EButton>
306
+ <EButton size="lg" variant="outline" class="border-primary-foreground/30 text-primary-foreground hover:bg-primary-foreground/10">
307
+ 联系销售
308
+ </EButton>
309
+ </div>
310
+ </div>
311
+ </section>
312
+ ```
313
+
314
+ 规则:
315
+ - 用 `bg-primary text-primary-foreground` 全宽色块,视觉突出
316
+ - 主 CTA 用 `variant="secondary"` 反色
317
+ - 和 Hero 的 CTA 保持一致的文案
318
+
319
+ ## 十一、Footer
320
+
321
+ ```vue
322
+ <footer class="border-t py-12">
323
+ <div class="max-w-6xl mx-auto px-6">
324
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-8">
325
+ <div>
326
+ <h4 class="font-semibold mb-4">产品</h4>
327
+ <ul class="space-y-2 text-sm text-muted-foreground">
328
+ <li><a href="#" class="hover:text-foreground transition-colors">功能</a></li>
329
+ <li><a href="#" class="hover:text-foreground transition-colors">定价</a></li>
330
+ </ul>
331
+ </div>
332
+ <!-- 更多列 -->
333
+ </div>
334
+ <div class="mt-12 pt-8 border-t text-center text-sm text-muted-foreground">
335
+ &copy; {{ new Date().getFullYear() }} Brand. All rights reserved.
336
+ </div>
337
+ </div>
338
+ </footer>
339
+ ```
340
+
341
+ ## 十二、排版规范(落地页专用)
342
+
343
+ | 元素 | class | 场景 |
344
+ |------|-------|------|
345
+ | 主标题(Hero) | `text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight` | 仅 Hero |
346
+ | Section 标题 | `text-3xl font-bold` | 各 Section h2 |
347
+ | 卡片/功能标题 | `text-lg font-semibold` | h3 |
348
+ | 副标题/描述 | `text-lg text-muted-foreground` | Section 描述 |
349
+ | 正文 | `text-sm` 或 `text-base` | 卡片内容 |
350
+ | 辅助文字 | `text-sm text-muted-foreground` | 标签、备注 |
351
+
352
+ ### 与中后台规范的差异
353
+
354
+ - 允许 `text-4xl` ~ `text-6xl`(仅 Hero 区域)
355
+ - 允许 `font-bold`(标题可用,中后台只用 `font-semibold`)
356
+ - 允许 `tracking-tight`(大标题紧凑字距)
357
+ - 正文可用 `text-base`(16px),比中后台的 `text-sm` 更大
358
+
359
+ ## 十三、动画规范
360
+
361
+ ### 允许的动画
362
+
363
+ | 类型 | 实现 | 场景 |
364
+ |------|------|------|
365
+ | 滚动入场 | `opacity-0 translate-y-4` → `opacity-100 translate-y-0` | Section 内容 |
366
+ | 数字递增 | JS 计数动画 | 统计指标 |
367
+ | 渐显 | `opacity-0` → `opacity-100` | Logo 墙 |
368
+ | 悬停阴影 | `hover:shadow-md transition-shadow` | 功能卡片 |
369
+
370
+ ### 滚动入场实现
371
+
372
+ ```vue
373
+ <script setup>
374
+ import { useIntersectionObserver } from '@vueuse/core'
375
+
376
+ const target = ref<HTMLElement | null>(null)
377
+ const isVisible = ref(false)
378
+
379
+ useIntersectionObserver(target, ([{ isIntersecting }]) => {
380
+ if (isIntersecting) isVisible.value = true
381
+ }, { threshold: 0.1 })
382
+ </script>
383
+
384
+ <template>
385
+ <div
386
+ ref="target"
387
+ :class="[
388
+ 'transition-all duration-700 ease-out',
389
+ isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4',
390
+ ]"
391
+ >
392
+ <slot />
393
+ </div>
394
+ </template>
395
+ ```
396
+
397
+ ### 禁止的动画
398
+
399
+ - **禁止** parallax 滚动视差(性能差 + 晕动症)
400
+ - **禁止** `animate-bounce` 等持续动画(除 loading)
401
+ - **禁止** 入场动画 > 700ms
402
+ - **禁止** 滚动劫持(scroll-jacking)
403
+ - **必须** 检查 `prefers-reduced-motion`,尊重用户设置
404
+
405
+ ## 十四、响应式规范
406
+
407
+ 落地页**必须**支持手机端(375px 起):
408
+
409
+ | 断点 | 布局调整 |
410
+ |------|---------|
411
+ | < 640px | 单列,CTA 纵向排列,导航隐藏 |
412
+ | 640px-768px | 单列或 2 列网格 |
413
+ | 768px-1024px | 2-3 列网格 |
414
+ | > 1024px | 完整布局 |
415
+
416
+ 关键规则:
417
+ - 图片 `w-full rounded-lg`,不固定宽度
418
+ - 文字容器 `max-w-2xl mx-auto`,防止超长行
419
+ - Grid 用 `grid md:grid-cols-3`,移动端自动单列
420
+ - CTA 按钮 `flex-col sm:flex-row`,移动端纵向
421
+
422
+ ## 十五、代码自检清单(落地页专用)
423
+
424
+ | # | 检查项 |
425
+ |---|--------|
426
+ | 1 | 颜色只用语义 token,不写死色值 |
427
+ | 2 | Hero 标题用 `tracking-tight`,不超过 `text-6xl` |
428
+ | 3 | 每个 Section 有 `py-16 lg:py-24` 上下间距 |
429
+ | 4 | 内容区 `max-w-6xl mx-auto px-6` 居中限宽 |
430
+ | 5 | 图标只用 lucide-vue-next,无 emoji |
431
+ | 6 | 导航栏 `fixed` + `backdrop-blur-sm` + `bg-background/80` |
432
+ | 7 | Hero 下方 `pt-32` 避免被导航栏遮挡 |
433
+ | 8 | CTA 按钮 `size="lg"`,主次分明 |
434
+ | 9 | 375px 手机端无水平滚动,布局正常 |
435
+ | 10 | 动画 `duration-700` 以内,检查 `prefers-reduced-motion` |
436
+ | 11 | 定价卡片推荐档 `border-primary shadow-lg` 高亮 |
437
+ | 12 | 暗色模式所有元素可见可读 |
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: dwy-fullstack-scaffold
3
+ description: "按 quant-cloud monorepo 架构生成 Web 全栈项目骨架。触发条件:用户说'创建新项目'、'搭骨架'、'新建全栈项目'、'按 quant-cloud 架构创建'、'全栈脚手架'、'scaffold'、'新项目按这个架构'、'开新项目'时。"
4
+ ---
5
+
6
+ # dwy-fullstack-scaffold
7
+
8
+ 按照 quant-cloud(/Users/chances/WebstormProjects/ai-quant/quant-cloud/) 的 monorepo 架构生成全栈项目骨架。
9
+
10
+ ## 触发后该做什么(决策树)
11
+
12
+ ```
13
+ 用户说 "创建新项目 xxx" / "搭骨架"
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 + 根级)
21
+ ↓
22
+ 2. 检查 target_dir 不存在或为空。如已存在且非空, AskUserQuestion 确认是否清理。
23
+ ↓
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>
31
+ ↓
32
+ 4. 生成完成后自动执行(脚本内做):
33
+ - cd <target_dir>/backend && uv sync --dev
34
+ - cd <target_dir>/frontend && pnpm install (如开 frontend)
35
+ ↓
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 干净
42
+ ↓
43
+ 6. 报告结果 + 下一步指引
44
+ ```
45
+
46
+ ## 生成的目录结构
47
+
48
+ ```
49
+ <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/ # 设计文档占位
56
+ ├── .env.example
57
+ ├── .gitignore
58
+ ├── backend/
59
+ │ ├── CLAUDE.md # 后端约束(分层/Provider/异常/eapi 优先使用等)
60
+ │ ├── pyproject.toml # 单一版本中心 + uv workspace + 双 index(aliyun + pypi)
61
+ │ ├── 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 嵌套分组
68
+ │ │ ├── exceptions.py
69
+ │ │ ├── factories.py # Provider 工厂(配置驱动切换实现)
70
+ │ │ ├── middleware/__init__.py
71
+ │ │ └── infra/__init__.py
72
+ │ ├── packages/
73
+ │ │ ├── dwy-shared/ # 跨项目可复用 kernel
74
+ │ │ │ ├── pyproject.toml
75
+ │ │ │ └── src/dwy_shared/__init__.py
76
+ │ │ └── <scope_prefix>-<initial_domain>/ # 业务包雏形
77
+ │ │ ├── pyproject.toml
78
+ │ │ └── src/<scope_prefix>_<initial_domain>/
79
+ │ │ ├── __init__.py # register(app) 装载入口
80
+ │ │ ├── router.py # /api/health endpoint
81
+ │ │ ├── service.py
82
+ │ │ ├── schemas.py
83
+ │ │ ├── models.py
84
+ │ │ └── protocols.py # Provider 协议定义
85
+ │ └── tests/
86
+ │ └── conftest.py
87
+ └── frontend/
88
+ ├── CLAUDE.md # 前端约束(eui 优先 / pnpm catalog / features 域分包)
89
+ ├── package.json
90
+ ├── pnpm-workspace.yaml # catalog: 第三方依赖版本统一管理
91
+ ├── 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
108
+ └── 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
119
+ ```
120
+
121
+ ## 关键模式(由模板严格保留)
122
+
123
+ 参考 references/architecture.md 的详细说明。要点:
124
+
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`(项目可去掉)。
133
+
134
+ ## 用户参数收集
135
+
136
+ 调用脚本前 **必须** 用 AskUserQuestion 收集 5 个参数。提供合理默认值:
137
+
138
+ | 参数 | 含义 | 默认 | 示例 |
139
+ |------|------|------|------|
140
+ | project_name | kebab-case 项目名 | (无默认,必问) | `my-app` / `quant-admin` |
141
+ | target_dir | 目标父目录 | `/Users/chances/WebstormProjects/<project_name>` | 同上 |
142
+ | scope_prefix | 业务包前缀 | `app` | `quant`, `foo` |
143
+ | initial_domain | 初始示例业务域 | `core` | `order`, `user`, `factor` |
144
+ | include_frontend | 是否生成 frontend | `true` | `true` / `false` |
145
+
146
+ **target_dir 检查**:已存在且非空 → 用 AskUserQuestion 让用户确认"清理后重建"或"换个目录"或"放弃"。
147
+
148
+ ## 不要做的事
149
+
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)。
155
+
156
+ ## 生成完成后的报告模板
157
+
158
+ ```markdown
159
+ ✅ 项目 <project_name> 骨架已生成
160
+
161
+ 📁 路径: <target_dir>
162
+
163
+ 📦 已安装依赖:
164
+ - backend (uv sync --dev): <duration> s
165
+ - frontend (pnpm install): <duration> s [仅当 include_frontend=true]
166
+
167
+ ✅ 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]
170
+
171
+ 🚀 下一步:
172
+ cd <target_dir>
173
+ ./dev.sh
174
+
175
+ 🛠 业务开发起点:
176
+ - 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 注册路由
180
+
181
+ 📋 待办(skill 没替你做):
182
+ - git init && git add . && git commit -m "chore: initial scaffold from dwy-fullstack-scaffold"
183
+ - 在 .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 雏形)
186
+ ```
187
+
188
+ ## 失败排错
189
+
190
+ 生成或 health check 失败时,先看脚本输出最后 50 行(脚本会打印每一步的命令 + stderr)。常见失败:
191
+
192
+ | 症状 | 原因 | 解决 |
193
+ |------|------|------|
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 |
199
+
200
+ ## 后续扩展
201
+
202
+ 加新业务 package(例如订单系统 `quant-order`):
203
+
204
+ 1. 复制 `backend/packages/<scope>-<initial_domain>/` 整体到 `<scope>-<new_domain>/`
205
+ 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)`
209
+
210
+ 加新前端 feature:
211
+
212
+ 1. 在 `frontend/packages/features/` 复制示例 feature 整体改名
213
+ 2. 在 `frontend/apps/web/src/features/` 加同名目录(页面层)
214
+ 3. `apps/web/src/router/index.ts` 注册路由