create-dwy 0.19.1 → 0.20.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 (98) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/package.json +1 -1
  3. package/src/cli-help.js +28 -2
  4. package/src/sync-all.js +95 -583
  5. package/src/sync-codex.js +14 -7
  6. package/src/sync-opencode.js +8 -22
  7. package/src/sync.js +60 -149
  8. package/src/tab-multiselect.js +15 -53
  9. package/templates/ai-tools/CHANGELOG.md +195 -0
  10. package/templates/ai-tools/CLAUDE.md +39 -58
  11. package/templates/ai-tools/VERSION +1 -1
  12. package/templates/ai-tools/hooks/Git/pre-git-commit-ai-signature-check.sh +5 -4
  13. package/templates/ai-tools/rules/Android/dwy-android-core.md +147 -13
  14. package/templates/ai-tools/rules/Android/dwy-android-layering.md +142 -0
  15. package/templates/ai-tools/rules/Android/dwy-android-mvp.md +55 -0
  16. package/templates/ai-tools/rules/Android/dwy-android-support-only.md +2 -0
  17. package/templates/ai-tools/rules/Docker/dwy-docker.md +23 -1
  18. package/templates/ai-tools/rules/Flutter/dwy-flutter-core.md +2 -0
  19. package/templates/ai-tools/rules/Flutter/dwy-flutter-testing.md +1 -1
  20. package/templates/ai-tools/rules/HarmonyOS/dwy-arkts-ui-build.md +12 -8
  21. package/templates/ai-tools/rules/Python/dwy-python-backend.md +4 -43
  22. package/templates/ai-tools/rules/Python/dwy-python-layering.md +169 -0
  23. package/templates/ai-tools/rules/Vue/dwy-vue-core.md +11 -49
  24. package/templates/ai-tools/rules/Vue/dwy-vue-layering.md +153 -0
  25. package/templates/ai-tools/rules/iOS/dwy-apple-layering.md +133 -0
  26. package/templates/ai-tools/rules/iOS/dwy-swift-core.md +2 -0
  27. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-craft.md +83 -0
  28. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-dependency-freshness.md +27 -66
  29. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-git-commit.md +8 -219
  30. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-oss-commercial-license.md +27 -123
  31. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prod-branch.md +31 -0
  32. package/templates/ai-tools/rules//346/225/260/346/215/256/345/272/223/dwy-postgres.md +17 -10
  33. package/templates/ai-tools/rules//346/225/260/346/215/256/345/272/223/dwy-redis.md +6 -3
  34. package/templates/ai-tools/skills/Docker/dwy-deploy-first/SKILL.md +14 -14
  35. package/templates/ai-tools/skills/Docker/dwy-deploy-first/references/chapter-01-mirrors.md +2 -2
  36. package/templates/ai-tools/skills/Docker/dwy-docker/SKILL.md +21 -13
  37. package/templates/ai-tools/skills/Docker/dwy-docker/references/ask-templates.md +13 -12
  38. package/templates/ai-tools/skills/Docker/dwy-docker/references/templates.md +3 -1
  39. package/templates/ai-tools/skills/Docker/dwy-docker/references/version-rules.md +10 -6
  40. package/templates/ai-tools/skills/Docker/dwy-docker/scripts/query_dockerhub.py +21 -6
  41. package/templates/ai-tools/skills/Docker/dwy-docker/scripts/scan_images.sh +2 -2
  42. package/templates/ai-tools/skills/Docker/dwy-mirror-source/SKILL.md +44 -30
  43. package/templates/ai-tools/skills/Docker/dwy-mirror-source/references/dockerfile-snippets.md +2 -0
  44. package/templates/ai-tools/skills/Docker/dwy-mirror-source/references/mirror-providers.md +8 -8
  45. package/templates/ai-tools/skills/Docker/dwy-mirror-source/scripts/apply_mirrors.py +14 -1
  46. package/templates/ai-tools/skills/Docker/dwy-mirror-source/scripts/check_mirrors.py +4 -0
  47. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/SKILL.md +8 -6
  48. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/digest/python-sdk.md +3 -3
  49. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/digest/stream-engine.md +2 -2
  50. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/anti-patterns.md +3 -1
  51. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/change-checklist.md +4 -4
  52. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/lethal-violations.md +5 -5
  53. package/templates/ai-tools/skills/DolphinDB/dwy-dolphindb/references/review-rules/perf-baselines.md +5 -5
  54. package/templates/ai-tools/skills/Python/dwy-eapi/SKILL.md +2 -2
  55. package/templates/ai-tools/skills/Python/dwy-eapi/v0/breaking.md +3 -0
  56. package/templates/ai-tools/skills/Python/dwy-eapi/v0/email-canonical.md +28 -3
  57. package/templates/ai-tools/skills/Python/dwy-eapi/v0/index.md +2 -2
  58. package/templates/ai-tools/skills/Python/dwy-eapi/v0/providers-email.md +12 -2
  59. package/templates/ai-tools/skills/Vue/dwy-eui/references/eui-design-guide.md +1 -1
  60. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-architecture/SKILL.md +11 -14
  61. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-product-launcher/references/state-and-contract.md +1 -1
  62. package/templates/ai-tools/skills//344/272/247/345/223/2010/345/210/2601/dwy-prototype/SKILL.md +1 -1
  63. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/SKILL.md +32 -15
  64. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/references/electron-release-workflow-template.yml +3 -1
  65. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/references/release-workflow-template.yml +8 -5
  66. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/SKILL.md +1 -1
  67. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/assets/appstore-submission.yaml +1 -1
  68. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/references/aso.md +2 -0
  69. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-ios-app-store-release/references/in-app-purchase-review.md +1 -1
  70. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/SKILL.md +4 -3
  71. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/android.md +1 -1
  72. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/backend-deploy.md +1 -1
  73. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/changelog.md +45 -27
  74. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/frontend-deploy.md +1 -1
  75. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/generic-release.md +1 -1
  76. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/git-tag.md +1 -1
  77. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/harmony.md +1 -1
  78. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/ios.md +1 -1
  79. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/SKILL.md +8 -0
  80. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/SKILL.md +7 -7
  81. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/references/checks-runtime.md +63 -59
  82. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_base.sh +10 -1
  83. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_capacity.sh +21 -23
  84. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_db.sh +9 -1
  85. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_docker.sh +20 -24
  86. package/templates/ai-tools/skills//345/256/211/345/205/250/dwy-deploy-audit/scripts/check_logs.sh +3 -3
  87. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/SKILL.md +4 -2
  88. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/references/api.md +1 -1
  89. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/dwy-doubao-tts/scripts/synthesize.py +1 -0
  90. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/media-platform-packaging/SKILL.md +7 -5
  91. package/templates/ai-tools/skills//350/207/252/345/252/222/344/275/223/media-platform-packaging/references/platform-copy-examples.md +5 -3
  92. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-dependency-choice/SKILL.md +140 -0
  93. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-git-commit/SKILL.md +113 -0
  94. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-shared/SKILL.md +16 -13
  95. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-whiteboard-prototype/SKILL.md +1 -1
  96. package/src/sync-packs.js +0 -223
  97. package/src/sync-scene.js +0 -178
  98. package/templates/ai-tools/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-tdd-development.md +0 -115
@@ -0,0 +1,142 @@
1
+ ---
2
+ description: Android 四层模块与依赖方向(app / features / biz-foundation / foundation);Gradle Version Catalog 根锁定第三方版本
3
+ paths:
4
+ - "**/*.kt"
5
+ - "**/*.java"
6
+ - "**/*.gradle"
7
+ - "**/*.kts"
8
+ - "**/libs.versions.toml"
9
+ - "**/settings.gradle"
10
+ ---
11
+
12
+ # Android 四层架构与依赖
13
+
14
+ 适用于多模块 Android 应用。注释 / 命名 / AppCompat 见 `dwy-android-core`。页面 MVP 与业务 Base 见 `dwy-android-mvp`。本文件只管**Gradle 模块层、引用边、版本写在哪**。模块**内部** Java 包仍按功能聚合(见 `dwy-android-core`「包组织」)。
15
+
16
+ 新项目强制本结构。未拆模块的存量**不回溯拆包**;新增模块必须按本文件落层。Support 老项目另走 `dwy-android-support-only`。
17
+
18
+ 单壳项目**不建** PlatformFoundation。
19
+
20
+ ---
21
+
22
+ ## 一、层名(冻结)
23
+
24
+ 正式层名只有下表四个。模块可以叫 `:app`、`:biz-foundation`,文档可写「本仓 `:layer-infra` = Foundation」。**禁止**把 `Domain` / `infra` / `core` 当层名。
25
+
26
+ | 层 | 判定(只用这一条) | 禁止 |
27
+ |---|---|---|
28
+ | **Foundation** | 换一个完全不同的产品仍原样拿走 | 出现本业务名词 |
29
+ | **BizFoundation** | 本产品才有,但跨多个 Feature 都要用 | 页面、导航、某一端壳状态 |
30
+ | **Features** | 可整包删/裁剪的业务域 | 被其他 Feature 直接引用 |
31
+ | **Assembly** | 生命周期、DI、路由挂载、把实现插进 Protocol | 业务规则、业务计算 |
32
+
33
+ 升层:第二个 Feature 或第二个产品**真在用**,才升到 BizFoundation / Foundation。禁止「可能复用」提前抽。
34
+
35
+ 业务内聚:一个业务域 = `:features:<name>`。域内 Activity / Presenter(或本仓对等角色)/ Repository 聚在该模块。禁止全局 `activities/` / `presenters/` 模块(本仓已经那样切的,跟本仓)。
36
+
37
+ `BaseActivity` / `BaseFragment` / `BaseDialog` 落在 `:biz-foundation`(本产品壳)。Foundation 不放页面基类。细则见 `dwy-android-mvp`。
38
+
39
+ ---
40
+
41
+ ## 二、依赖边(强制)
42
+
43
+ ```
44
+ :app → :features:* → :biz-foundation → :foundation
45
+ ✕ 互引
46
+ ```
47
+
48
+ | 谁 | 允许 project 依赖 | 禁止 |
49
+ |---|---|---|
50
+ | `:app` | `:features:*`、`:biz-foundation` | 业务规则写在 Application / HomePresenter |
51
+ | `:features:orders` | **仅** `implementation project(':biz-foundation')` | 其它 Feature、`:foundation`、`:app` |
52
+ | `:biz-foundation` | `:foundation`(可用 `api` 给编译用,见下) | Feature / app |
53
+ | `:foundation` | 无 project 下层 | 业务模型、Feature |
54
+
55
+ **Feature 互引为零。** 跳转只走 `:app`。跨域只许:升到 `:biz-foundation`;Feature 依赖 `biz-foundation` 里的接口,由 app 注入;壳编排。
56
+
57
+ **透传不等于可直连。** `:biz-foundation` 即使 `api project(':foundation')`,Feature **源码仍禁止** `import` foundation 包名。要用 Http/Log,走 biz-foundation 门面。
58
+
59
+ ```gradle
60
+ // features/orders/build.gradle
61
+ dependencies {
62
+ implementation project(':biz-foundation')
63
+ implementation libs.okhttp
64
+ }
65
+ ```
66
+
67
+ ```gradle
68
+ // 禁止
69
+ implementation project(':features:inventory')
70
+ implementation project(':foundation')
71
+ implementation project(':app')
72
+ ```
73
+
74
+ ---
75
+
76
+ ## 三、分包树
77
+
78
+ 打开工程必须能数出四层。业务词只出现在 `features/` 下。
79
+
80
+ ```
81
+ :app # Assembly
82
+ :features:orders # Features
83
+ :features:inventory
84
+ :biz-foundation # BizFoundation(鉴权、跨域协议放这个模块里面)
85
+ :foundation # Foundation(Http / Log / 进程工具)
86
+ ```
87
+
88
+ ```
89
+ app/
90
+ features/
91
+ orders/
92
+ inventory/
93
+ biz-foundation/
94
+ src/main/java/.../bizfoundation/auth/
95
+ foundation/
96
+ src/main/java/.../foundation/http/
97
+ gradle/libs.versions.toml
98
+ settings.gradle
99
+ ```
100
+
101
+ `settings.gradle` include 上述模块。鉴权不是独立层,是 `:biz-foundation` 内的包。
102
+
103
+ ---
104
+
105
+ ## 四、Monorepo 版本(强制)
106
+
107
+ 第三方版本号**只**出现在 `gradle/libs.versions.toml`。模块用 `libs.xxx`。内部模块 `project(':x')`。选哪个版本走 skill `dwy-dependency-choice`。
108
+
109
+ 存量若仍用根 `config.gradle` 的 `ext`,视为同一 catalog,禁止再在子模块写版本。
110
+
111
+ ```toml
112
+ # gradle/libs.versions.toml
113
+ [versions]
114
+ okhttp = "4.12.0"
115
+
116
+ [libraries]
117
+ okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
118
+ ```
119
+
120
+ ```gradle
121
+ // features/orders/build.gradle
122
+ dependencies {
123
+ implementation project(':biz-foundation')
124
+ implementation libs.okhttp
125
+ }
126
+ ```
127
+
128
+ 禁止 feature 模块 `implementation 'com.squareup.okhttp3:okhttp:4.12.0'`。
129
+
130
+ ---
131
+
132
+ ## 五、检查清单
133
+
134
+ | 检查项 | 严重 |
135
+ |---|---|
136
+ | 无 `:features` / `:biz-foundation` / `:foundation` 三层模块(新项目) | 高 |
137
+ | Feature `implementation` 另一 Feature 或 `:foundation` 或 `:app` | 高 |
138
+ | Feature 源码 `import` foundation 包名(即使经 `api` 透传) | 高 |
139
+ | 开机链 / 业务编排写在 `:app` 的 Presenter | 高 |
140
+ | 业务 BaseActivity 放在 `:foundation` 或 Feature 里 | 高 |
141
+ | 子模块写死第三方坐标版本 | 高 |
142
+ | `Domain` / `infra` / `core` 当层名 | 中 |
@@ -0,0 +1,55 @@
1
+ ---
2
+ description: Android 用 MVP 做页面分工;实际架构读当前项目上下文;业务 Base 落在 BizFoundation;简单静态页和确认框允许无 Presenter
3
+ paths:
4
+ - "**/*.java"
5
+ - "**/*.kt"
6
+ - "**/AndroidManifest.xml"
7
+ - "**/res/**/*.xml"
8
+ ---
9
+
10
+ # Android MVP 与业务 Base
11
+
12
+ **实际 MVP 架构以当前项目上下文为准。** 本文件只定大行为,不定骨架、类名、目录、库。
13
+
14
+ 写任何页面前必须先读本仓,再动手。读到的继承链、Contract 切法、基类名字、生命周期挂法、包怎么放,全部跟项目。禁止用记忆里的「标准 MVP」覆盖本仓。
15
+
16
+ 模块四层见 `dwy-android-layering`;注释 / 命名 / AppCompat 见 `dwy-android-core`。Support 与 AndroidX 也跟当前项目推断。
17
+
18
+ ---
19
+
20
+ ## 一、写页面前读什么
21
+
22
+ 打开工程后搜并读(命中即按它写):
23
+
24
+ - 已有 `*Presenter` / `*View` / `*Contract` / Presenter 基类
25
+ - 业务 `BaseActivity` / `BaseFragment` / `BaseDialog` 的位置与继承链
26
+ - 一页的类怎么摆:同功能包,还是本仓已经横切
27
+ - View 与 Presenter 怎么绑生命周期(attach / 构造传入 / 其它)
28
+
29
+ 新页对齐读到的那套。禁止另起一套。存量不回溯。
30
+
31
+ 新仓还没有任何页面:用下面行为准则写第一页;之后新页对齐第一页,仍不从外部套模板。
32
+
33
+ ---
34
+
35
+ ## 二、行为准则(骨架仍跟项目)
36
+
37
+ 1. **View 管 UI,Presenter(或本仓对等角色)管业务与请求,数据层管读写。** 有业务的页:请求、校验、状态编排不进 Activity。
38
+ 2. **Presenter 不碰控件。** 不 `findViewById`,不把 Activity / 控件当字段;需要 Context 走 View 回调。页面销毁后不再调 View。怎么 detach 跟项目。
39
+ 3. **简单静态页、确认框、单按钮提示:允许不写 Presenter。** 不造空文件。复杂 Dialog 仍走本仓 MVP。
40
+ 4. **业务 Base 给业务扩展。** `BaseActivity` / `BaseFragment` / `BaseDialog` 落在 BizFoundation(未拆四层则本仓已有的 base 包):本产品壳。Feature 有 Base 之后禁止直接继承框架页。Foundation 不放本产品页面基类。Base 禁止上帝类。
41
+
42
+ ---
43
+
44
+ ## 三、检查清单
45
+
46
+ | 检查项 | 严重 |
47
+ |---|---|
48
+ | 没读本仓已有 MVP / Base 就按外部模板开写 | 高 |
49
+ | 新页没对齐本仓已有切法 / 命名 / 库 | 高 |
50
+ | 有请求的页在 Activity 里写接口 / 拼业务 | 高 |
51
+ | Presenter(或对等角色)持有控件 / Activity,销毁后仍回调 View | 高 |
52
+ | 已有业务 Base,新页仍直接继承框架页 | 高 |
53
+ | 业务 Base 里出现某 Feature 方法(上帝类) | 高 |
54
+ | Foundation 里放本产品 BaseActivity | 高 |
55
+ | 静态页 / 确认框硬造空 Presenter | 中 |
@@ -84,6 +84,8 @@ android.enableJetifier=false
84
84
  3. 传递依赖混入 androidx 时,用 `exclude` 排除,并替换为 support 等价物;**无法排除或无 support 等价物 → 换库**,不要将就
85
85
  4. **禁止**为使用某个只支持 androidx 的库而引入 androidx —— 一个 androidx 进来就破坏整套隔离,得不偿失
86
86
 
87
+ 屏幕适配用 AndroidAutoSize(JitPack,Support 兼容线 `1.2.0+`,起点先验 `v1.2.1`,不锁死这个 tag),只按宽度。移动端设计宽 `390`,TV 设计宽 `1280`。禁止改用 `androidx.window` / WindowSizeClass / Compose Adaptive。细则见 `dwy-android-core`「屏幕适配」。
88
+
87
89
  ```groovy
88
90
  // 库 foo 的 3.x 已迁 androidx,锁在最后支持 support 的 2.8.0(升级需先整体迁 androidx,见 issue #1234)
89
91
  implementation 'com.foo:bar:2.8.0'
@@ -1,5 +1,14 @@
1
1
  ---
2
- description: Docker 通用规则(镜像固定版本、容器内存上限、日志大小限制、配置变更重启姿势)
2
+ description: Docker 通用规则(镜像固定版本、容器内存上限、日志大小限制、配置变更重启姿势)。只在容器和 CI 清单上注入。
3
+ paths:
4
+ - "**/Dockerfile"
5
+ - "**/Dockerfile.*"
6
+ - "**/docker-compose*.yml"
7
+ - "**/docker-compose*.yaml"
8
+ - "**/compose.yml"
9
+ - "**/compose.yaml"
10
+ - "**/.github/workflows/**"
11
+ - "**/k8s/**"
3
12
  ---
4
13
 
5
14
  # Docker 通用规则
@@ -32,6 +41,8 @@ image: postgres:16.4
32
41
  image: postgres:16.4@sha256:xxxxx
33
42
  ```
34
43
 
44
+ 正例里的版本号只示范具体 tag 的写法。该装哪一个,以当次查到的 tag 列表为准,不从本规则抄数字。
45
+
35
46
  ## 二、Docker 容器配置要求
36
47
 
37
48
  ### 1. 内存设置
@@ -46,6 +57,8 @@ image: postgres:16.4@sha256:xxxxx
46
57
  - **必须**限制单个日志文件大小与轮转文件数量
47
58
  - **禁止**不设上限长期写入,避免占满磁盘
48
59
 
60
+ 具体数字以当次测到的内存占用和日志增速为准。没有实测的新环境才用经验起点,服务跑起来后重测。下面示例只示范字段怎么写。
61
+
49
62
  ### compose 示例
50
63
 
51
64
  ```yaml
@@ -120,3 +133,12 @@ docker compose exec backend printenv | grep DOLPHINDB_FACTOR__
120
133
  ### 一句话
121
134
 
122
135
  > 配置改了别 restart,`up -d --force-recreate`。验证别只看连通,`printenv` 看容器内真值。
136
+
137
+ ## 四、镜像源
138
+
139
+ 文档和脚本里的镜像站 URL 是当前候选,不是指定赢家。
140
+
141
+ - 先探测即将真正使用的路径(包索引、发行版 `Release`、镜像 manifest)。超时、证书错误、状态不对、没有目标包或 tag 的源丢掉
142
+ - 在剩下的源里用本次延迟最低的。连通不等于可用
143
+ - 私服、用户指定的源不参与公网竞速
144
+ - 候选全部不成立时另找可用源,再测一次。测速结果不写回本规则
@@ -125,6 +125,7 @@ class App extends ConsumerWidget {
125
125
 
126
126
  ```yaml
127
127
  # pubspec.yaml
128
+ # 下面的 caret 只示范当时能编过的下限,不是该装的版本。装之前按 dwy-dependency-choice 现查。
128
129
  dependencies:
129
130
  flutter_riverpod: ^2.6.0
130
131
  riverpod_annotation: ^2.6.0
@@ -337,6 +338,7 @@ shared/widgets/ # snake_case
337
338
 
338
339
  ```yaml
339
340
  # pubspec.yaml
341
+ # 版本号是写法示例。装之前按 dwy-dependency-choice 现查,不要抄这里的数字。
340
342
  dependencies:
341
343
  freezed_annotation: ^2.4.0
342
344
  json_annotation: ^4.9.0
@@ -72,7 +72,7 @@ testWidgets('登录页面渲染正确', (tester) async {
72
72
 
73
73
  ## 四、Mock 工具
74
74
 
75
- 统一使用 `mocktail`(不是 mockito):
75
+ 统一使用 `mocktail`(不是 mockito)。`^1.0.0` 只示范写法,实际版本按 `dwy-dependency-choice` 现查。
76
76
 
77
77
  ```yaml
78
78
  dev_dependencies:
@@ -172,10 +172,13 @@ private async safe(name, step) {
172
172
 
173
173
  ## 9. DevEco 命令行构建(绕开 IDE,拿带 File:行:列 的错误)
174
174
 
175
+ 路径用本机 DevEco 根,不要抄某台 Mac 的默认安装位置。先找到本机安装目录,再拼 `tools/node/bin/node`、`tools/hvigor/bin/hvigorw.js` 和该布局里的 sdk。找不到就问用户。
176
+
175
177
  ```bash
176
- NODE=/Applications/DevEco-Studio.app/Contents/tools/node/bin/node
177
- HVIGOR=/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw.js
178
- export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk # 停 daemon 后必设
178
+ # <DEVECO> = 本机 DevEco 根。macOS 默认安装常见 /Applications/DevEco-Studio.app,不是唯一位置。
179
+ NODE=<DEVECO>/Contents/tools/node/bin/node
180
+ HVIGOR=<DEVECO>/Contents/tools/hvigor/bin/hvigorw.js
181
+ export DEVECO_SDK_HOME=<DEVECO>/Contents/sdk # 停 daemon 后必设
179
182
 
180
183
  # 配置校验
181
184
  $NODE $HVIGOR --sync -p product=default --daemon
@@ -205,14 +208,15 @@ $NODE $HVIGOR --mode module -p module=entry@default -p product=default -p pageTy
205
208
  - **正确做法**:DevEco → Project Structure → Signing Configs 自动签名写回工程;**模拟器**可装 unsigned;**真机**必须签名。
206
209
  - **适用**:CLI / CI 打包。
207
210
 
208
- ## 12. 本地模拟器(HVD)命令行:`-hvd` + hdc `127.0.0.1:5555`
211
+ ## 12. 本地模拟器(HVD)命令行:`-hvd` + 本次 `hdc list targets`
209
212
 
210
213
  - **现象**:不知如何脱离 IDE 起模拟器、装 HAP。
211
214
  - **正确做法**:
212
- - 启动:`/Applications/DevEco-Studio.app/Contents/tools/emulator/Emulator -hvd "Pura 90"`(名见 `~/.Huawei/Emulator/deployed/*.ini`)。
213
- - 设备:`hdc list targets` → 常见 `127.0.0.1:5555`。
214
- - 安装:`hdc -t 127.0.0.1:5555 install entry/.../entry-default-unsigned.hap`。
215
- - 启动:`hdc -t 127.0.0.1:5555 shell aa start -a EntryAbility -b <bundleName>`。
215
+ - 模拟器名读 `~/.Huawei/Emulator/deployed/*.ini`,不要写死某一台机型。
216
+ - 启动:`<DEVECO>/Contents/tools/emulator/Emulator -hvd "<ini 里的名字>"`。`<DEVECO>` 与第 9 节同一台机器的安装根。
217
+ - 设备:`hdc list targets` 的输出就是 `-t`。`127.0.0.1:5555` 只是本机常见先验,列表里没有就用列表里的那个。
218
+ - 安装:`hdc -t <本次 target> install entry/.../entry-default-unsigned.hap`。
219
+ - 启动:`hdc -t <本次 target> shell aa start -a EntryAbility -b <bundleName>`。
216
220
  - **适用**:无 GUI / 脚本化调试。
217
221
 
218
222
  ## 13. 模拟器验不了局域网 TCP / mDNS / 设备发现
@@ -12,52 +12,11 @@ paths:
12
12
 
13
13
  ## 一、项目结构与业务聚合(强制)
14
14
 
15
- ### 核心原则
15
+ **仓库四层(`app` / `features` / `biz_foundation` / `foundation`)、Feature 互不依赖、uv 根锁定版本 → 见 `dwy-python-layering`。** 本节只约定 Feature **域内**文件名。
16
16
 
17
- **按功能模块(feature / domain)聚合,禁止按技术层散落。** 同一业务功能的 router / schema / service / model / dependency 必须集中在同一个功能目录下;**禁止**全局存在 `routers/` / `services/` / `models/` / `schemas/` 等"技术层"顶级目录,把不相关功能的同类型文件强行揉到一起。
18
-
19
- ### 为什么
20
-
21
- - **跨项目迁移**:复制单个功能目录即可携带该功能全部代码;技术层散落需在 4+ 目录里翻找
22
- - **可读性**:阅读功能时所有相关代码在同一目录,无需跨目录跳转
23
- - **变更影响域清晰**:一次改动 diff 集中,code review 更高效
24
- - **删除友好**:删功能时整个目录删掉即可,不会留下孤儿文件
25
-
26
- ### 标准结构(参考)
27
-
28
- ```
29
- app/
30
- ├── users/ # 用户功能(一个业务模块自成一个目录)
31
- │ ├── __init__.py
32
- │ ├── router.py # FastAPI 路由
33
- │ ├── schemas.py # Pydantic 请求 / 响应模型
34
- │ ├── service.py # 业务逻辑
35
- │ ├── models.py # ORM 模型
36
- │ ├── dependencies.py # 该功能专用 Depends(可选)
37
- │ └── exceptions.py # 该功能专用异常(可选)
38
- ├── orders/
39
- │ ├── router.py
40
- │ ├── schemas.py
41
- │ ├── service.py
42
- │ └── models.py
43
- ├── core/ # 跨功能共享:配置 / 全局中间件 / 启动逻辑
44
- │ ├── config.py
45
- │ ├── middleware.py
46
- │ └── lifespan.py
47
- └── main.py # 注册各功能 router
48
- ```
49
-
50
- ### 强制规则
51
-
52
- - **禁止**顶级 `routers/` / `services/` / `models/` / `schemas/` 把不同功能的同类文件混放
53
17
  - 一个功能目录内文件名固定:`router.py` / `schemas.py` / `service.py` / `models.py`(单数,不带功能前缀)
54
- - 跨功能真正共享的代码放 `core/` 或 `shared/`,**禁止**为"可能复用"把单一功能逻辑提前抽离
55
18
  - 单文件超过约 400 行时再考虑拆分(如 `service.py` → `services/create.py` + `services/query.py`),**禁止**未到规模就预拆分
56
- - 功能间引用通过明确 import,**禁止**循环依赖
57
- - 测试镜像功能聚合结构:`tests/users/test_router.py` / `tests/users/test_service.py`(详见第九节)
58
-
59
- ### 例外
60
- - 通用基础设施代码(如基础框架库内部)可保持技术层结构
19
+ - 测试镜像功能聚合:`tests/features/orders/test_router.py`(详见第九节)
61
20
 
62
21
  ---
63
22
 
@@ -179,6 +138,7 @@ class UserResponse(UserBase):
179
138
  | 分页 page_size | 必须有上限(≤ 100) |
180
139
  | 字符串 | 必须显式 `max_length` |
181
140
  | 文件上传 | 后端二次校验大小 + magic bytes,**禁止**只信任前端或 Nginx |
141
+ | 图片上传 | 同时校验文件大小和像素宽高上限,防止 decompression bomb |
182
142
 
183
143
  ---
184
144
 
@@ -466,6 +426,7 @@ AI 编写或审查后端代码时,**必须**检查以下违规模式,按严
466
426
  |--------|---------|---------|
467
427
  | 重复造轮子 | 自造异常基类 / 自封装统一响应 / 散落手写 bcrypt 或 JWT 调用 / 自建 Redis 连接池 等本应走项目级统一模块的能力 | 高 |
468
428
  | 技术层散落 | 顶级出现 `routers/` / `services/` / `models/` / `schemas/` 等技术层目录把不同功能文件混放,未按功能聚合 | 高 |
429
+ | 分层依赖 | Feature `from app.` / import 另一 Feature / 源码 `from foundation.`;成员包写死第三方版本。细则见 `dwy-python-layering` | 高 |
469
430
  | 测试与源码混放 | 测试文件放在源码目录中(如 `app/users/test_router.py`),未独立到测试目录 | 高 |
470
431
  | 密码明文 | `password` 字段出现在 Response Schema | **致命 → STOP** |
471
432
  | 密码弱存储 | 使用 MD5 / SHA 而非 bcrypt | **致命 → STOP** |
@@ -0,0 +1,169 @@
1
+ ---
2
+ description: Python 后端四层分包与依赖方向(Assembly / Features / BizFoundation / Foundation);uv workspace 根锁定第三方版本
3
+ paths:
4
+ - "**/*.py"
5
+ - "**/pyproject.toml"
6
+ ---
7
+
8
+ # Python 四层架构与依赖
9
+
10
+ 适用于 uv workspace 的 Python 后端。路由 / Schema / ORM / 安全编码见 `dwy-python-backend`。本文件只管**层、引用边、版本写在哪**。
11
+
12
+ 单壳项目**不建** PlatformFoundation。
13
+
14
+ ---
15
+
16
+ ## 一、层名(冻结)
17
+
18
+ 正式层名只有下表四个。目录 / 包可以叫 `app`、`biz_foundation`,文档可写「本仓包名 X = Foundation」。**禁止**把 `Domain` / `infra` / `core` 当层名。
19
+
20
+ | 层 | 判定(只用这一条) | 禁止 |
21
+ |---|---|---|
22
+ | **Foundation** | 换一个完全不同的产品仍原样拿走 | 出现本业务名词 |
23
+ | **BizFoundation** | 本产品才有,但跨多个 Feature 都要用 | 页面、导航、某一端壳状态 |
24
+ | **Features** | 可整包删/裁剪的业务域 | 被其他 Feature 直接引用 |
25
+ | **Assembly** | 生命周期、DI、路由挂载、把实现插进 Protocol | 业务规则、业务计算 |
26
+
27
+ 升层:第二个 Feature 或第二个产品**真在用**,才升到 BizFoundation / Foundation。禁止「可能复用」提前抽。
28
+
29
+ 业务内聚:一个业务域 = `features/` 下的一个包。域内 `router.py` / `service.py` / `schemas.py` / `models.py` 聚在一起。禁止全局 `routers/` `services/` `models/`。
30
+
31
+ ---
32
+
33
+ ## 二、依赖边(强制)
34
+
35
+ ```
36
+ app → features/* → biz_foundation → foundation
37
+ ✕ 互引
38
+ ```
39
+
40
+ | 谁 | 允许依赖 | 禁止 |
41
+ |---|---|---|
42
+ | `app/` | `features/*`、`biz_foundation`、`foundation`(仅 factories) | 业务计算 |
43
+ | `features/orders` | 仅 `biz_foundation` | `app`、`features/inventory`、`foundation` |
44
+ | `biz_foundation` | 仅 `foundation` | `app`、任何 Feature |
45
+ | `foundation` | 第三方库 | 任何本仓业务包 |
46
+
47
+ **Feature 互引为零。** 跨域只许三种:升到 `biz_foundation`;Feature 只依赖 Protocol,由 `app/factories.py` / `app/hooks.py` 注入实现;`app` 编排两次调用。
48
+
49
+ 依赖倒置原则:Feature 依赖 Protocol,不依赖 Doris/Http 具体类。具体实现只出现在 `app/`。
50
+
51
+ 声明与源码两道都查:
52
+
53
+ - `features/orders/pyproject.toml` 的 `dependencies` 只许出现 `biz_foundation` 与无版本第三方名
54
+ - 源码禁止 `from app.`、`from features.inventory`、`from foundation.`
55
+
56
+ ```python
57
+ # 合法:只认抽象,实现由装配层注入
58
+ class StockPort(Protocol):
59
+ """扣库存端口。orders 不 import inventory 包。"""
60
+
61
+ async def deduct(self, sku: str, qty: int) -> None: ...
62
+
63
+
64
+ class OrderService:
65
+ """下单。stock 由 app/factories.py 注入。"""
66
+
67
+ def __init__(self, stock: StockPort) -> None:
68
+ self._stock = stock
69
+ ```
70
+
71
+ ```python
72
+ # 禁止
73
+ from app.main import settings # Feature → Assembly
74
+ from features.inventory.service import deduct # Feature → Feature
75
+ from foundation.db import get_session # Feature 越层
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 三、分包树
81
+
82
+ 打开 `backend/` 必须能数出四层。业务词只出现在 `features/` 下。
83
+
84
+ ```
85
+ backend/
86
+ app/ # Assembly
87
+ main.py # 注册 router、lifespan
88
+ factories.py # 唯一实例化具体实现的地方
89
+ hooks.py # 跨 Feature 桥
90
+ features/ # Features
91
+ orders/
92
+ pyproject.toml
93
+ src/orders/
94
+ router.py
95
+ service.py
96
+ schemas.py
97
+ models.py
98
+ inventory/
99
+ pyproject.toml
100
+ src/inventory/
101
+ router.py
102
+ service.py
103
+ schemas.py
104
+ models.py
105
+ biz_foundation/ # BizFoundation
106
+ pyproject.toml
107
+ src/biz_foundation/
108
+ auth/ # 内容:跨 Feature 鉴权,不是一层
109
+ protocols.py
110
+ foundation/ # Foundation
111
+ pyproject.toml
112
+ src/foundation/
113
+ db.py
114
+ redis.py
115
+ signing.py
116
+ pyproject.toml # workspace + 第三方版本只在这
117
+ uv.lock
118
+ ```
119
+
120
+ ```toml
121
+ # 根 pyproject.toml
122
+ [tool.uv.workspace]
123
+ members = ["features/*", "biz_foundation", "foundation"]
124
+ ```
125
+
126
+ `app/` 是根应用,不是 workspace member。测试镜像层:`tests/features/orders/`、`tests/biz_foundation/`。
127
+
128
+ ---
129
+
130
+ ## 四、Monorepo 版本(强制)
131
+
132
+ 第三方版本号**只**出现在仓库根 `pyproject.toml` 的 `constraint-dependencies`。成员包只写包名。内部包用 uv workspace,不写版本。一把锁:根 `uv.lock`。选哪个版本走 skill `dwy-dependency-choice`。
133
+
134
+ ```toml
135
+ # 根 pyproject.toml
136
+ [tool.uv.sources]
137
+ biz_foundation = { workspace = true }
138
+ foundation = { workspace = true }
139
+
140
+ [tool.uv]
141
+ constraint-dependencies = [
142
+ "fastapi==0.115.6",
143
+ "sqlalchemy==2.0.36",
144
+ ]
145
+ ```
146
+
147
+ ```toml
148
+ # features/orders/pyproject.toml
149
+ [project]
150
+ dependencies = [
151
+ "fastapi", # 无版本
152
+ "biz_foundation",
153
+ ]
154
+ ```
155
+
156
+ 禁止成员 `pyproject.toml` 写 `fastapi==0.115.6`。禁止每个包自己 `uv lock`。
157
+
158
+ ---
159
+
160
+ ## 五、检查清单
161
+
162
+ | 检查项 | 严重 |
163
+ |---|---|
164
+ | 顶层不是 `app` / `features` / `biz_foundation` / `foundation` 四层 | 高 |
165
+ | Feature `from app.` 或 pyproject 依赖 `app` | 高 |
166
+ | Feature import 另一 Feature | 高 |
167
+ | Feature 源码 `from foundation.` | 高 |
168
+ | 成员包写死第三方版本 | 高 |
169
+ | `Domain` / `infra` / `core` 当层名 | 中 |
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Vue 3 + TS + Vite + Tailwind 应用层通用规范(业务聚合结构、组件 / TS / 路由 / API / 模板 / 样式 / 错误处理 / 注释)
2
+ description: Vue 3 + TS + Vite + Tailwind 应用层通用规范(组件 / TS / 路由 / API / 模板 / 样式 / 错误处理 / 注释;仓库分层见 dwy-vue-layering)
3
3
  paths:
4
4
  - "**/*.vue"
5
5
  - "**/*.ts"
@@ -14,57 +14,11 @@ paths:
14
14
 
15
15
  ## 一、项目结构与业务聚合(强制)
16
16
 
17
- ### 核心原则
17
+ **仓库四层(`apps/web` / `packages/features` / `packages/biz-foundation` / `packages/foundation`)、Feature 互不依赖、pnpm catalog → 见 `dwy-vue-layering`。** 本节只约定 Feature **域内**文件名。
18
18
 
19
- **按功能模块(feature / domain)聚合,禁止按技术层散落。** 同一业务功能的 view / components / store / api / types 必须集中在同一个功能目录下;**禁止**全局存在 `views/` / `components/` / `stores/` / `api/` 等顶级"技术层"目录把不同功能的同类文件混放。
20
-
21
- ### 为什么
22
-
23
- - **跨项目迁移**:复制单个功能目录即可携带该功能全部代码;技术层散落需在 5+ 目录里翻找
24
- - **可读性**:阅读功能时所有相关代码在同一目录,无需跨目录跳转
25
- - **变更影响域清晰**:一次改动 diff 集中,code review 更高效
26
- - **删除友好**:删功能时整个目录删掉即可,不会留下孤儿文件
27
-
28
- ### 标准结构(参考)
29
-
30
- ```
31
- src/
32
- ├── features/ # 业务功能根目录
33
- │ ├── users/ # 用户功能
34
- │ │ ├── api.ts # 该业务的 API(用全局 HTTP 客户端)
35
- │ │ ├── store.ts # 该业务的 Pinia store
36
- │ │ ├── types.ts # 该业务的类型
37
- │ │ ├── views/ # 该业务的页面组件
38
- │ │ │ ├── UserListView.vue
39
- │ │ │ └── UserDetailView.vue
40
- │ │ ├── components/ # 该业务的内部组件
41
- │ │ │ └── UserCard.vue
42
- │ │ └── route.ts # 该业务的路由片段
43
- │ └── orders/
44
- │ ├── api.ts
45
- │ ├── store.ts
46
- │ └── views/
47
- ├── shared/ # 跨业务真正复用:UI 子组件 / composables / 常量
48
- │ ├── components/
49
- │ ├── composables/
50
- │ └── constants/
51
- ├── core/ # 全局基础设施:HTTP client / 路由根 / 主题 / 启动
52
- │ ├── http.ts # 全局唯一 HTTP 客户端实例
53
- │ ├── router.ts
54
- │ └── main.ts
55
- ├── App.vue
56
- └── style.css
57
- ```
58
-
59
- > 测试目录与 `src/` 并列、镜像业务聚合结构(详见 `dwy-vue-testing` rule)。
60
-
61
- ### 强制规则
62
-
63
- - **禁止**顶级 `views/` / `components/` / `stores/` / `api/` / `types/` 把不同功能的同类文件混放
64
19
  - 一个功能目录内文件名固定:`api.ts` / `store.ts` / `types.ts` / `route.ts`(单数、不带功能前缀)
65
- - 跨业务真正共享的代码放 `shared/` 或 `core/`,**禁止**为"可能复用"把单一功能逻辑提前抽离
66
20
  - 单文件超过约 400 行时再考虑拆分,**禁止**未到规模就预拆分
67
- - 模块间引用通过明确 import,**禁止**循环依赖
21
+ - 测试目录与源码并列、镜像业务聚合(详见 `dwy-vue-testing`)
68
22
 
69
23
  ## 二、组件规范
70
24
 
@@ -313,6 +267,14 @@ export function createUser(data: UserCreate) {
313
267
  - 模板中复杂表达式 / 内联多语句
314
268
  - `kebab-case` 组件名 / 模板中写 `.value`
315
269
 
270
+ ### 用户输入限长
271
+
272
+ 业务页里接收用户输入的控件(`input` / `textarea` / 富文本 / 文件 / 批量项)要有长度或大小上限,并用该页的 schema 再校验一次,防止粘贴绕过 `maxlength`。
273
+
274
+ 上限按字段语义定:用户名几十字符、描述几百、正文几千、图片几 MB。组件库的 Input 只提供 `maxlength` 这类 prop,不在组件内部写死业务上限。
275
+
276
+ 后端校验见 `dwy-python-backend`。只改组件库、没有业务表单时,不要给每个控件塞一套 schema。
277
+
316
278
  ---
317
279
 
318
280
  ## 八、样式规范