create-yss-spec 2.1.0 → 2.1.1

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 (277) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -2
  3. package/src/cli.js +1 -1
  4. package/template/.agents/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  5. package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +4 -2
  6. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  7. package/template/.agents/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  8. package/template/.agents/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  9. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  10. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  11. package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  12. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +28 -0
  13. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  14. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  15. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +2 -0
  16. package/template/.agents/skills/yss-router/SKILL.md +4 -0
  17. package/template/.agents/skills/yss-router/references/router-contract.yaml +48 -2
  18. package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +2 -0
  19. package/template/.agents/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  20. package/template/.claude/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  21. package/template/.claude/skills/implementation-repo-onboarding/SKILL.md +4 -2
  22. package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  23. package/template/.claude/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  24. package/template/.claude/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  25. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  26. package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  27. package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  28. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +28 -0
  29. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  30. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  31. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +2 -0
  32. package/template/.claude/skills/yss-router/SKILL.md +4 -0
  33. package/template/.claude/skills/yss-router/references/router-contract.yaml +48 -2
  34. package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +2 -0
  35. package/template/.claude/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  36. package/template/.codex/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  37. package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +4 -2
  38. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  39. package/template/.codex/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  40. package/template/.codex/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  41. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  42. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  43. package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  44. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +28 -0
  45. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  46. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  47. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +2 -0
  48. package/template/.codex/skills/yss-router/SKILL.md +4 -0
  49. package/template/.codex/skills/yss-router/references/router-contract.yaml +48 -2
  50. package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +2 -0
  51. package/template/.codex/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  52. package/template/.hermes/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  53. package/template/.hermes/skills/implementation-repo-onboarding/SKILL.md +4 -2
  54. package/template/.hermes/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  55. package/template/.hermes/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  56. package/template/.hermes/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  57. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  58. package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  59. package/template/.hermes/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  60. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +28 -0
  61. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  62. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  63. package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +2 -0
  64. package/template/.hermes/skills/yss-router/SKILL.md +4 -0
  65. package/template/.hermes/skills/yss-router/references/router-contract.yaml +48 -2
  66. package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +2 -0
  67. package/template/.hermes/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  68. package/template/.pi/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  69. package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +4 -2
  70. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  71. package/template/.pi/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  72. package/template/.pi/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  73. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  74. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  75. package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  76. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +28 -0
  77. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  78. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  79. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +2 -0
  80. package/template/.pi/skills/yss-router/SKILL.md +4 -0
  81. package/template/.pi/skills/yss-router/references/router-contract.yaml +48 -2
  82. package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +2 -0
  83. package/template/.pi/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  84. package/template/.qoder/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  85. package/template/.qoder/skills/implementation-repo-onboarding/SKILL.md +4 -2
  86. package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  87. package/template/.qoder/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  88. package/template/.qoder/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  89. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  90. package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  91. package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  92. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +28 -0
  93. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  94. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  95. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +2 -0
  96. package/template/.qoder/skills/yss-router/SKILL.md +4 -0
  97. package/template/.qoder/skills/yss-router/references/router-contract.yaml +48 -2
  98. package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +2 -0
  99. package/template/.qoder/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  100. package/template/.trae/skills/cross-repo-implementation-routing/SKILL.md +4 -3
  101. package/template/.trae/skills/implementation-repo-onboarding/SKILL.md +4 -2
  102. package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +25 -5
  103. package/template/.trae/skills/yss-ddd-scaffold-generator/agents/openai.yaml +1 -1
  104. package/template/.trae/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +25 -36
  105. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +474 -258
  106. package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.py +155 -0
  107. package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +2 -1
  108. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +28 -0
  109. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +70 -2
  110. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +9 -0
  111. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +2 -0
  112. package/template/.trae/skills/yss-router/SKILL.md +4 -0
  113. package/template/.trae/skills/yss-router/references/router-contract.yaml +48 -2
  114. package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +2 -0
  115. package/template/.trae/skills/yss-router/references/yss-skill-execution-result.md +1 -1
  116. package/template/AGENTS.md +12 -8
  117. package/template/docs/architecture/templates/engineering-baseline-review-template.md +14 -0
  118. package/template/docs/process/implementation-repo-integration.md +17 -0
  119. package/template/docs/process/lifecycle-artifact-map.md +3 -3
  120. package/template/docs/templates/build-architecture-checklist-template.md +7 -1
  121. package/template/docs/templates/cross-repo-slice-template.md +2 -0
  122. package/template/docs/templates/implementation-repo-registry-template.md +14 -0
  123. package/template/docs/templates/implementation-routing-template.md +35 -6
  124. package/template/docs/user-guide//344/272/247/345/223/201/347/224/237/345/221/275/345/221/250/346/234/237/345/267/245/344/275/234/346/265/201.md +4 -3
  125. package/template/docs/user-guide//347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +10 -2
  126. package/template/scripts/implementation-path-policy.rb +50 -0
  127. package/template/scripts/sync-skills +5 -0
  128. package/template/scripts/update-skill-lock +7 -1
  129. package/template/scripts/verify-implementation-path-scenarios +43 -0
  130. package/template/scripts/verify-lifecycle-scenarios +18 -0
  131. package/template/scripts/verify-matt-yss-integration-scenarios +1 -1
  132. package/template/scripts/verify-prototype-backend-scaffold-scenarios +239 -0
  133. package/template/scripts/verify-scaffold-generator-scenarios +438 -0
  134. package/template/scripts/verify-template +11 -0
  135. package/template/scripts/verify-yss-router-scenarios +76 -23
  136. package/template/skills-lock.json +6 -6
  137. package/template.snapshot.json +4 -4
  138. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  139. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  140. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  141. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  142. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  143. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  144. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  145. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  146. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  147. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  148. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  149. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  150. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  151. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  152. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  153. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  154. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  155. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  156. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  157. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  158. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  159. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  160. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  161. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  162. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  163. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  164. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  165. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  166. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  167. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  168. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  169. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  170. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  171. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  172. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  173. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  174. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  175. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  176. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  177. package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  178. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  179. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  180. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  181. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  182. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  183. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  184. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  185. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  186. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  187. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  188. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  189. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  190. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  191. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  192. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  193. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  194. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  195. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  196. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  197. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  198. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  199. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  200. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  201. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  202. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  203. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  204. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  205. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  206. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  207. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  208. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  209. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  210. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  211. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  212. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  213. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  214. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  215. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  216. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  217. package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  218. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  219. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  220. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  221. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  222. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  223. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  224. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  225. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  226. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  227. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  228. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  229. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  230. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  231. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  232. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  233. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  234. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  235. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  236. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  237. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  238. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  239. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  240. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  241. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  242. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  243. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  244. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  245. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  246. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  247. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  248. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  249. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  250. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  251. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  252. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  253. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  254. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  255. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  256. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  257. package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
  258. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/adapter/UserController.java.template +0 -84
  259. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/application/UserConvertor.java.template +0 -21
  260. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/application/UserService.java.template +0 -48
  261. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/application/UserServiceImpl.java.template +0 -87
  262. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/bootstrap/YssDatamiddleApplication.java.template +0 -28
  263. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/config/data.sql.template +0 -2
  264. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/config/schema.sql.template +0 -27
  265. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/User.java.template +0 -17
  266. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserAddCmd.java.template +0 -27
  267. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserGateway.java.template +0 -54
  268. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserPageQuery.java.template +0 -12
  269. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserUpdateCmd.java.template +0 -21
  270. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/domain/UserVO.java.template +0 -52
  271. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/AuditableEntity.java.template +0 -25
  272. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/PageUtil.java.template +0 -13
  273. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserGatewayImpl.java.template +0 -85
  274. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPO.java.template +0 -35
  275. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserPOConvertor.java.template +0 -28
  276. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/UserRepository.java.template +0 -7
  277. package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/infrastructure/YssDataMybatisConfig.java.template +0 -8
@@ -1,43 +1,69 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
- """
4
- YSS DDD 脚手架生成器
5
- 用于快速创建基于 DDD 的后端项目结构
6
- """
3
+ """YSS DDD 后端纯工程骨架生成器。"""
7
4
 
8
- import os
9
- import sys
10
5
  import argparse
11
6
  import json
12
- from pathlib import Path
13
- from typing import Dict, List
7
+ import os
14
8
  import re
15
9
  import shutil
16
- import sqlite3
10
+ import sys
17
11
  import tempfile
18
12
  from datetime import datetime
13
+ from pathlib import Path
14
+ from typing import Dict, List, Optional, Tuple
15
+
19
16
 
20
17
  class ScaffoldGenerator:
21
- """脚手架生成器主类"""
18
+ """只生成工程结构,不生成任何业务行为。"""
19
+
20
+ def __init__(
21
+ self,
22
+ project_name: str,
23
+ base_package: str,
24
+ output_dir: str,
25
+ with_example: bool = False,
26
+ database: str = "mysql",
27
+ force: bool = False,
28
+ contract_id: Optional[str] = None,
29
+ contract_version: Optional[int] = None,
30
+ approval_ref: Optional[str] = None,
31
+ router_draft_ref: Optional[str] = None,
32
+ persisted_ref: Optional[str] = None,
33
+ contract_file: Optional[str] = None,
34
+ overwrite_scope: Optional[str] = None,
35
+ rollback_ref: Optional[str] = None,
36
+ ):
37
+ if with_example:
38
+ raise ValueError(
39
+ "YSS 受控脚手架只生成纯工程骨架;--with-example 已禁用,业务代码必须按批准切片合同实现"
40
+ )
22
41
 
23
- def __init__(self, project_name: str, base_package: str, output_dir: str,
24
- with_example: bool = False, database: str = 'mysql', force: bool = False):
25
42
  self.project_name = project_name
26
43
  self.base_package = base_package
27
44
  self.output_dir = Path(output_dir)
45
+ self.repository_root = Path(__file__).resolve().parents[4]
46
+ self._validate_harness_output_layout()
28
47
  self.with_example = with_example
29
48
  self.database = database
30
49
  self.force = force
50
+ self.contract_id = contract_id
51
+ self.contract_version = contract_version
52
+ self.approval_ref = approval_ref
53
+ self.router_draft_ref = router_draft_ref
54
+ self.persisted_ref = persisted_ref
55
+ self.contract_file = Path(contract_file).resolve() if contract_file else None
56
+ self.overwrite_scope = overwrite_scope
57
+ self.rollback_ref = rollback_ref
58
+ self.scaffold_contract: Dict[str, object] = {}
59
+
31
60
  self.template_root = Path(__file__).resolve().parents[1] / "assets" / "templates"
32
61
  self.config_template_dir = self.template_root / "config"
33
62
  self.pom_template_dir = self.template_root / "pom"
34
63
  if not self.pom_template_dir.exists():
35
64
  self.pom_template_dir = self.config_template_dir
36
65
 
37
- # 转换包名为路径
38
- self.package_path = base_package.replace('.', '/')
39
-
40
- # 最终项目根目录;生成期间 project_root 会指向 staging 目录
66
+ self.package_path = base_package.replace(".", "/")
41
67
  self.final_project_root = self.output_dir / project_name
42
68
  self.project_root = self.final_project_root
43
69
 
@@ -51,14 +77,19 @@ class ScaffoldGenerator:
51
77
  self.db_dependency = self._resolve_db_dependency(self.database)
52
78
 
53
79
  def generate(self):
54
- """生成完整的脚手架项目"""
80
+ """在受控生成合同下生成不含业务行为的工程骨架。"""
55
81
  if self.final_project_root.exists() and not self.force:
56
82
  raise FileExistsError(
57
83
  f"输出目录已存在: {self.final_project_root};如确认覆盖,请显式传入 --force"
58
84
  )
85
+ self._validate_contract_metadata()
86
+ if self._target_is_non_empty() and self.force:
87
+ self._validate_force_metadata()
59
88
 
60
89
  self.output_dir.mkdir(parents=True, exist_ok=True)
61
- staging_root = Path(tempfile.mkdtemp(prefix=f".{self.project_name}.staging-", dir=self.output_dir))
90
+ staging_root = Path(
91
+ tempfile.mkdtemp(prefix=f".{self.project_name}.staging-", dir=self.output_dir)
92
+ )
62
93
  self.project_root = staging_root / self.project_name
63
94
 
64
95
  try:
@@ -67,31 +98,21 @@ class ScaffoldGenerator:
67
98
  print(f"📁 输出目录: {self.output_dir}")
68
99
  print()
69
100
 
70
- # 创建项目结构
71
101
  self._create_project_structure()
72
-
73
- # 生成 POM 文件
74
102
  self._generate_pom_files()
75
-
76
- # 生成配置文件
77
103
  self._generate_config_files()
78
-
79
- # 生成示例代码
80
- if self.with_example:
81
- self._generate_example_code()
82
-
83
- # 生成数据库脚本
84
104
  self._generate_database_scripts()
85
-
86
- # 生成文档
87
105
  self._generate_documentation()
88
-
106
+ self._write_generation_manifest()
89
107
  self._copy_wrapper_files()
90
108
  self._validate_generated_artifacts()
91
109
 
92
110
  backup_path = None
93
111
  if self.final_project_root.exists():
94
- backup_path = self.output_dir / f".{self.project_name}.backup-{datetime.now().strftime('%Y%m%d%H%M%S%f')}"
112
+ backup_path = self.output_dir / (
113
+ f".{self.project_name}.backup-"
114
+ f"{datetime.now().strftime('%Y%m%d%H%M%S%f')}"
115
+ )
95
116
  self.final_project_root.rename(backup_path)
96
117
  self.project_root.rename(self.final_project_root)
97
118
  self.project_root = self.final_project_root
@@ -107,18 +128,204 @@ class ScaffoldGenerator:
107
128
  print(" ./mvnw validate")
108
129
  print(" ./mvnw test")
109
130
  print(" ./mvnw package")
110
- print(" ./mvnw spring-boot:run -pl {}-bootstrap".format(self.project_name))
131
+ print(f" ./mvnw spring-boot:run -pl {self.project_name}-bootstrap")
111
132
  except Exception:
112
133
  shutil.rmtree(staging_root, ignore_errors=True)
113
134
  raise
114
135
 
136
+ def _target_is_non_empty(self) -> bool:
137
+ if not self.final_project_root.exists():
138
+ return False
139
+ if self.final_project_root.is_file():
140
+ return True
141
+ return any(self.final_project_root.iterdir())
142
+
143
+ def _validate_harness_output_layout(self) -> None:
144
+ """在当前 Harness 内只允许生成到 apps/backend/<project>/。"""
145
+ output_root = self.output_dir.resolve()
146
+ try:
147
+ relative = output_root.relative_to(self.repository_root)
148
+ except ValueError:
149
+ # 外部实现仓库使用其登记的 native root,不套用 Harness 目录策略。
150
+ return
151
+
152
+ parts = relative.parts
153
+ if len(parts) >= 2 and parts[0] == "app" and parts[1] in {"backend", "frontend"}:
154
+ raise ValueError(
155
+ "禁止使用单数 app/backend 或 app/frontend 作为工程生成路径;"
156
+ "Harness 内后端脚手架必须以 apps/backend 为父容器"
157
+ )
158
+ if parts == ("apps", "backend"):
159
+ return
160
+ if parts[:2] == ("apps", "frontend"):
161
+ raise ValueError("后端脚手架不能输出到 apps/frontend;请使用外部后端仓库或 apps/backend")
162
+ raise ValueError(
163
+ "当前 Harness 内生成后端工程时,输出目录必须是 apps/backend;"
164
+ "生成器会以 project_name 创建 apps/backend/<project>/"
165
+ )
166
+
167
+ def _validate_contract_metadata(self):
168
+ if self.contract_file is None or not self.contract_file.is_file():
169
+ raise ValueError("必须提供已持久化的结构化脚手架合同 JSON 文件: --contract-file")
170
+
171
+ try:
172
+ contract = json.loads(self.contract_file.read_text(encoding="utf-8"))
173
+ except (OSError, json.JSONDecodeError) as exception:
174
+ raise ValueError(f"脚手架合同文件无法读取或不是合法 JSON: {self.contract_file}") from exception
175
+ if not isinstance(contract, dict):
176
+ raise ValueError("脚手架合同必须是 JSON 对象")
177
+
178
+ required_metadata = {
179
+ "--contract-id": self.contract_id,
180
+ "--contract-version": self.contract_version,
181
+ "--approval-ref": self.approval_ref,
182
+ "--router-draft-ref": self.router_draft_ref,
183
+ "--persisted-ref": self.persisted_ref,
184
+ }
185
+ missing = [
186
+ option for option, value in required_metadata.items() if value in (None, "")
187
+ ]
188
+ if self.contract_version is not None and self.contract_version < 1:
189
+ missing.append("--contract-version(必须为正整数)")
190
+ if missing:
191
+ raise ValueError(
192
+ "生成项目必须提供当前已批准脚手架合同的完整元数据: " + ", ".join(missing)
193
+ )
194
+
195
+ required_fields = [
196
+ "schema_version",
197
+ "contract_id",
198
+ "contract_version",
199
+ "slice_id",
200
+ "status",
201
+ "router_draft_ref",
202
+ "lifecycle_approval_ref",
203
+ "persisted_ref",
204
+ "current_version",
205
+ "implementation_repository",
206
+ "backend_repository",
207
+ "scaffold_status",
208
+ "target_git_url_or_output_dir",
209
+ "allowed_write_paths",
210
+ "expected_evidence_files",
211
+ "verification_commands",
212
+ "approval",
213
+ "work_unit",
214
+ "overwrite_policy",
215
+ ]
216
+ missing_contract_fields = [
217
+ field for field in required_fields if contract.get(field) in (None, "", [])
218
+ ]
219
+ if missing_contract_fields:
220
+ raise ValueError(
221
+ "脚手架合同缺少结构化字段: " + ", ".join(missing_contract_fields)
222
+ )
223
+ if contract["schema_version"] != 1 or contract["status"] != "approved":
224
+ raise ValueError("脚手架合同必须是 schema_version=1 且已由生命周期批准")
225
+ if contract["contract_id"] != self.contract_id:
226
+ raise ValueError("--contract-id 与脚手架合同不一致")
227
+ if contract["contract_version"] != self.contract_version:
228
+ raise ValueError("--contract-version 与脚手架合同不一致")
229
+ if contract["current_version"] != contract["contract_version"]:
230
+ raise ValueError("脚手架合同版本不是当前版本")
231
+ if contract["router_draft_ref"] != self.router_draft_ref:
232
+ raise ValueError("--router-draft-ref 与脚手架合同不一致")
233
+ if contract["persisted_ref"] != self.persisted_ref:
234
+ raise ValueError("--persisted-ref 与脚手架合同不一致")
235
+ if contract["lifecycle_approval_ref"] != self.approval_ref:
236
+ raise ValueError("--approval-ref 与脚手架合同不一致")
237
+ if contract["scaffold_status"] != "required":
238
+ raise ValueError("脚手架生成器只接受 scaffold_status=required")
239
+ if not all(isinstance(contract[field], list) and contract[field] for field in (
240
+ "allowed_write_paths", "expected_evidence_files", "verification_commands"
241
+ )):
242
+ raise ValueError("脚手架合同的 allowed_write_paths、expected_evidence_files、verification_commands 必须非空")
243
+ if ".yss/scaffold-generation.json" not in " ".join(str(item) for item in contract["expected_evidence_files"]):
244
+ raise ValueError("脚手架合同 expected_evidence_files 必须包含 .yss/scaffold-generation.json")
245
+ target_ref = str(contract["target_git_url_or_output_dir"])
246
+ if "://" not in target_ref and not target_ref.startswith("git@"):
247
+ if Path(target_ref).resolve() != self.output_dir.resolve():
248
+ raise ValueError("脚手架合同目标目录与 --output-dir 不一致")
249
+ expected_commands = ["./mvnw validate", "./mvnw test", "./mvnw package"]
250
+ if contract["verification_commands"] != expected_commands:
251
+ raise ValueError("脚手架合同验证命令必须固定为三条项目根目录 ./mvnw 命令")
252
+
253
+ approval = contract["approval"]
254
+ if not isinstance(approval, dict) or any(
255
+ approval.get(field) in (None, "")
256
+ for field in ("approval_ref", "approver", "persisted_ref", "current_version")
257
+ ):
258
+ raise ValueError("脚手架合同 approval 记录不完整")
259
+ if approval["approval_ref"] != self.approval_ref or approval["persisted_ref"] != self.persisted_ref:
260
+ raise ValueError("脚手架合同 approval 引用与命令参数不一致")
261
+ if approval["current_version"] != self.contract_version:
262
+ raise ValueError("脚手架合同 approval 不是当前版本")
263
+
264
+ work_unit = contract["work_unit"]
265
+ required_work_unit_fields = [
266
+ "id",
267
+ "behavior",
268
+ "primary_skill",
269
+ "supporting_skills",
270
+ "tdd_mode",
271
+ "allowed_write_paths",
272
+ "expected_evidence",
273
+ "verification_commands",
274
+ "controlled_generation",
275
+ ]
276
+ if not isinstance(work_unit, dict) or any(
277
+ work_unit.get(field) in (None, "", []) for field in required_work_unit_fields
278
+ ):
279
+ raise ValueError("脚手架合同 work_unit 结构不完整")
280
+ if (
281
+ work_unit.get("primary_skill") != "yss-ddd-scaffold-generator"
282
+ or work_unit.get("tdd_mode") != "controlled-generation"
283
+ or work_unit.get("controlled_generation") is not True
284
+ ):
285
+ raise ValueError("脚手架合同 work_unit 必须绑定本 skill 和 controlled-generation")
286
+ if (
287
+ work_unit["verification_commands"] != contract["verification_commands"]
288
+ or work_unit["allowed_write_paths"] != contract["allowed_write_paths"]
289
+ ):
290
+ raise ValueError("脚手架合同 work_unit 与根级验证/写路径约束不一致")
291
+ overwrite_policy = contract["overwrite_policy"]
292
+ if not isinstance(overwrite_policy, dict) or any(
293
+ field not in overwrite_policy for field in ("force_allowed", "overwrite_scope", "rollback_ref")
294
+ ):
295
+ raise ValueError("脚手架合同 overwrite_policy 结构不完整")
296
+ self.scaffold_contract = contract
297
+
298
+ def _validate_force_metadata(self):
299
+ required_metadata = {
300
+ "--overwrite-scope": self.overwrite_scope,
301
+ "--rollback-ref": self.rollback_ref,
302
+ }
303
+ missing = [
304
+ option for option, value in required_metadata.items() if value in (None, "")
305
+ ]
306
+ if missing:
307
+ raise ValueError(
308
+ "覆盖非空目录必须提供当前批准合同的覆盖范围和回滚引用: "
309
+ + ", ".join(missing)
310
+ )
311
+ overwrite_policy = self.scaffold_contract.get("overwrite_policy", {})
312
+ if not isinstance(overwrite_policy, dict) or overwrite_policy.get("force_allowed") is not True:
313
+ raise ValueError("脚手架合同未批准非空目录覆盖")
314
+ if overwrite_policy.get("overwrite_scope") != self.overwrite_scope:
315
+ raise ValueError("--overwrite-scope 与脚手架合同不一致")
316
+ if overwrite_policy.get("rollback_ref") != self.rollback_ref:
317
+ raise ValueError("--rollback-ref 与脚手架合同不一致")
318
+
115
319
  def _validate_generated_artifacts(self):
116
320
  """在 staging 目录提交前校验关键产物和占位符。"""
117
321
  required_files = [
118
322
  self.project_root / "pom.xml",
119
323
  self.project_root / f"{self.project_name}-bootstrap" / "pom.xml",
120
- self.project_root / f"{self.project_name}-bootstrap" / "src/main/resources/smart-doc.json",
324
+ self.project_root
325
+ / f"{self.project_name}-bootstrap"
326
+ / "src/main/resources/smart-doc.json",
121
327
  self.project_root / "mvnw",
328
+ self.project_root / ".yss/scaffold-generation.json",
122
329
  ]
123
330
  missing = [str(path) for path in required_files if not path.is_file()]
124
331
  if missing:
@@ -126,6 +333,16 @@ class ScaffoldGenerator:
126
333
 
127
334
  smart_doc_path = required_files[2]
128
335
  json.loads(smart_doc_path.read_text(encoding="utf-8"))
336
+ manifest = json.loads(required_files[4].read_text(encoding="utf-8"))
337
+ if (
338
+ manifest.get("contract_id") != self.contract_id
339
+ or manifest.get("contract_version") != self.contract_version
340
+ or manifest.get("current_version") != self.contract_version
341
+ or manifest.get("generation_mode") != "controlled-generation"
342
+ or manifest.get("verification_commands")
343
+ != ["./mvnw validate", "./mvnw test", "./mvnw package"]
344
+ ):
345
+ raise ValueError("脚手架生成元数据清单与当前批准合同或固定验证命令不一致")
129
346
  bootstrap_pom = required_files[1].read_text(encoding="utf-8")
130
347
  plugin_versions = re.findall(
131
348
  r"<artifactId>smart-doc-maven-plugin</artifactId>\s*<version>([^<]+)</version>",
@@ -134,63 +351,81 @@ class ScaffoldGenerator:
134
351
  if plugin_versions != ["yss-4.0.0"]:
135
352
  raise ValueError("smart-doc-maven-plugin 必须且只能使用 yss-4.0.0")
136
353
 
354
+ binary_suffixes = {".class", ".db", ".jar", ".png", ".jpg", ".jpeg", ".gif"}
137
355
  for path in self.project_root.rglob("*"):
138
- if path.is_file() and path.suffix not in {".db", ".jar", ".class"}:
139
- content = path.read_text(encoding="utf-8")
140
- if "{{" in content or "root/root" in content:
141
- raise ValueError(f"生成文件包含未替换占位符或明文凭据: {path}")
356
+ if not path.is_file() or path.suffix in binary_suffixes:
357
+ continue
358
+ content = path.read_text(encoding="utf-8")
359
+ if "{{" in content or "root/root" in content:
360
+ raise ValueError(f"生成文件包含未替换占位符或明文凭据: {path}")
142
361
 
143
362
  def _create_project_structure(self):
144
- """创建项目目录结构"""
363
+ """创建不含业务文件的项目目录结构。"""
145
364
  print("📁 创建项目目录结构...")
146
-
147
365
  modules = [
148
366
  f"{self.project_name}-domain",
149
367
  f"{self.project_name}-application",
150
368
  f"{self.project_name}-infrastructure",
151
369
  f"{self.project_name}-adapter",
152
- f"{self.project_name}-bootstrap"
370
+ f"{self.project_name}-bootstrap",
153
371
  ]
154
372
 
155
373
  for module in modules:
156
374
  module_path = self.project_root / module
157
-
158
- # 创建 src/main/java 目录
159
- java_path = module_path / "src" / "main" / "java" / self.package_path
160
- java_path.mkdir(parents=True, exist_ok=True)
161
-
162
- # 创建 src/main/resources 目录
163
- resources_path = module_path / "src" / "main" / "resources"
164
- resources_path.mkdir(parents=True, exist_ok=True)
165
-
166
- # 创建 src/test/java 目录
167
- test_path = module_path / "src" / "test" / "java" / self.package_path
168
- test_path.mkdir(parents=True, exist_ok=True)
169
-
375
+ (module_path / "src/main/java" / self.package_path).mkdir(
376
+ parents=True, exist_ok=True
377
+ )
378
+ (module_path / "src/main/resources").mkdir(parents=True, exist_ok=True)
379
+ (module_path / "src/test/java" / self.package_path).mkdir(
380
+ parents=True, exist_ok=True
381
+ )
170
382
  print(f" ✓ {module}")
171
383
 
172
- # 创建 adapter 子模块
173
- web_module = self.project_root / f"{self.project_name}-adapter" / f"{self.project_name}-web"
174
- web_java_path = web_module / "src" / "main" / "java" / self.package_path / "rest"
175
- web_java_path.mkdir(parents=True, exist_ok=True)
384
+ web_module = (
385
+ self.project_root
386
+ / f"{self.project_name}-adapter"
387
+ / f"{self.project_name}-web"
388
+ )
389
+ (web_module / "src/main/java" / self.package_path / "rest").mkdir(
390
+ parents=True, exist_ok=True
391
+ )
176
392
  print(f" ✓ {self.project_name}-adapter/{self.project_name}-web")
177
393
 
178
- # 创建数据库脚本目录
179
- db_path = self.project_root / "db"
180
- db_path.mkdir(parents=True, exist_ok=True)
181
- print(f" ✓ db")
394
+ (self.project_root / "db").mkdir(parents=True, exist_ok=True)
395
+ print(" ✓ db")
182
396
 
183
397
  def _generate_pom_files(self):
184
- """生成 Maven POM 文件"""
398
+ """生成 Maven POM 文件。"""
185
399
  print("\n📝 生成 Maven POM 文件...")
186
- pom_templates = [
400
+ pom_templates: List[Tuple[Path, Path]] = [
187
401
  (self.pom_template_dir / "parent-pom.xml.template", self.project_root / "pom.xml"),
188
- (self.pom_template_dir / "domain-pom.xml.template", self.project_root / f"{self.project_name}-domain" / "pom.xml"),
189
- (self.pom_template_dir / "application-pom.xml.template", self.project_root / f"{self.project_name}-application" / "pom.xml"),
190
- (self.pom_template_dir / "infrastructure-pom.xml.template", self.project_root / f"{self.project_name}-infrastructure" / "pom.xml"),
191
- (self.pom_template_dir / "adapter-pom.xml.template", self.project_root / f"{self.project_name}-adapter" / "pom.xml"),
192
- (self.pom_template_dir / "web-pom.xml.template", self.project_root / f"{self.project_name}-adapter" / f"{self.project_name}-web" / "pom.xml"),
193
- (self.pom_template_dir / "bootstrap-pom.xml.template", self.project_root / f"{self.project_name}-bootstrap" / "pom.xml"),
402
+ (
403
+ self.pom_template_dir / "domain-pom.xml.template",
404
+ self.project_root / f"{self.project_name}-domain" / "pom.xml",
405
+ ),
406
+ (
407
+ self.pom_template_dir / "application-pom.xml.template",
408
+ self.project_root / f"{self.project_name}-application" / "pom.xml",
409
+ ),
410
+ (
411
+ self.pom_template_dir / "infrastructure-pom.xml.template",
412
+ self.project_root / f"{self.project_name}-infrastructure" / "pom.xml",
413
+ ),
414
+ (
415
+ self.pom_template_dir / "adapter-pom.xml.template",
416
+ self.project_root / f"{self.project_name}-adapter" / "pom.xml",
417
+ ),
418
+ (
419
+ self.pom_template_dir / "web-pom.xml.template",
420
+ self.project_root
421
+ / f"{self.project_name}-adapter"
422
+ / f"{self.project_name}-web"
423
+ / "pom.xml",
424
+ ),
425
+ (
426
+ self.pom_template_dir / "bootstrap-pom.xml.template",
427
+ self.project_root / f"{self.project_name}-bootstrap" / "pom.xml",
428
+ ),
194
429
  ]
195
430
  self._render_and_write_templates(pom_templates)
196
431
  print(" ✓ 父级 pom.xml")
@@ -202,142 +437,41 @@ class ScaffoldGenerator:
202
437
  print(" ✓ bootstrap pom.xml")
203
438
 
204
439
  def _generate_config_files(self):
205
- """生成配置文件"""
440
+ """生成不含业务行为的工程配置文件。"""
206
441
  print("\n⚙️ 生成配置文件...")
207
- config_templates = [
208
- (self.config_template_dir / "application.yml.template", self.project_root / f"{self.project_name}-bootstrap" / "src" / "main" / "resources" / "application.yml"),
209
- (self.config_template_dir / "logback-spring.xml.template", self.project_root / f"{self.project_name}-bootstrap" / "src" / "main" / "resources" / "logback-spring.xml"),
210
- (self.config_template_dir / "smart-doc.json.template", self.project_root / f"{self.project_name}-bootstrap" / "src" / "main" / "resources" / "smart-doc.json"),
442
+ config_templates: List[Tuple[Path, Path]] = [
443
+ (
444
+ self.config_template_dir / "application.yml.template",
445
+ self.project_root
446
+ / f"{self.project_name}-bootstrap"
447
+ / "src/main/resources/application.yml",
448
+ ),
449
+ (
450
+ self.config_template_dir / "logback-spring.xml.template",
451
+ self.project_root
452
+ / f"{self.project_name}-bootstrap"
453
+ / "src/main/resources/logback-spring.xml",
454
+ ),
455
+ (
456
+ self.config_template_dir / "smart-doc.json.template",
457
+ self.project_root
458
+ / f"{self.project_name}-bootstrap"
459
+ / "src/main/resources/smart-doc.json",
460
+ ),
211
461
  ]
212
462
  self._render_and_write_templates(config_templates)
213
463
  print(" ✓ application.yml")
214
464
  print(" ✓ logback-spring.xml")
215
465
  print(" ✓ smart-doc.json")
216
466
 
217
- def _generate_example_code(self):
218
- """生成示例代码"""
219
- print("\n💻 生成示例代码 (User CRUD)...")
220
- domain_root = self.project_root / f"{self.project_name}-domain" / "src" / "main" / "java" / self.package_path
221
- application_root = self.project_root / f"{self.project_name}-application" / "src" / "main" / "java" / self.package_path
222
- infrastructure_root = self.project_root / f"{self.project_name}-infrastructure" / "src" / "main" / "java" / self.package_path
223
- adapter_root = self.project_root / f"{self.project_name}-adapter" / f"{self.project_name}-web" / "src" / "main" / "java" / self.package_path
224
- bootstrap_root = self.project_root / f"{self.project_name}-bootstrap" / "src" / "main" / "java" / self.package_path
225
-
226
- example_templates = [
227
- (self.template_root / "domain" / "UserAddCmd.java.template", domain_root / "client" / "dto" / "cmd" / "UserAddCmd.java"),
228
- (self.template_root / "domain" / "UserUpdateCmd.java.template", domain_root / "client" / "dto" / "cmd" / "UserUpdateCmd.java"),
229
- (self.template_root / "domain" / "UserPageQuery.java.template", domain_root / "client" / "dto" / "query" / "UserPageQuery.java"),
230
- (self.template_root / "domain" / "UserVO.java.template", domain_root / "client" / "vo" / "UserVO.java"),
231
- (self.template_root / "domain" / "UserGateway.java.template", domain_root / "domain" / "user" / "gateway" / "UserGateway.java"),
232
- (self.template_root / "domain" / "User.java.template", domain_root / "domain" / "user" / "model" / "User.java"),
233
- (self.template_root / "application" / "UserService.java.template", application_root / "core" / "service" / "UserService.java"),
234
- (self.template_root / "application" / "UserServiceImpl.java.template", application_root / "core" / "service" / "impl" / "UserServiceImpl.java"),
235
- (self.template_root / "application" / "UserConvertor.java.template", application_root / "core" / "service" / "convertor" / "UserConvertor.java"),
236
- (self.template_root / "infrastructure" / "AuditableEntity.java.template", infrastructure_root / "repository" / "entity" / "AuditableEntity.java"),
237
- (self.template_root / "infrastructure" / "UserPO.java.template", infrastructure_root / "repository" / "entity" / "UserPO.java"),
238
- (self.template_root / "infrastructure" / "UserRepository.java.template", infrastructure_root / "repository" / "UserRepository.java"),
239
- (self.template_root / "infrastructure" / "UserGatewayImpl.java.template", infrastructure_root / "repository" / "gateway" / "impl" / "UserGatewayImpl.java"),
240
- (self.template_root / "infrastructure" / "UserPOConvertor.java.template", infrastructure_root / "repository" / "convertor" / "UserPOConvertor.java"),
241
- (self.template_root / "infrastructure" / "PageUtil.java.template", infrastructure_root / "repository" / "util" / "PageUtil.java"),
242
- (self.template_root / "infrastructure" / "YssDataMybatisConfig.java.template", infrastructure_root / "repository" / "config" / "YssDataMybatisConfig.java"),
243
- (self.template_root / "adapter" / "UserController.java.template", adapter_root / "rest" / "UserController.java"),
244
- (self.template_root / "bootstrap" / "YssDatamiddleApplication.java.template", bootstrap_root / "YssDatamiddleApplication.java"),
245
- ]
246
- self._render_and_write_templates(example_templates)
247
- print(" ✓ Domain 层: UserAddCmd, UserUpdateCmd, UserPageQuery, UserVO, UserGateway, User")
248
- print(" ✓ Application 层: UserService, UserServiceImpl, UserConvertor")
249
- print(" ✓ Infrastructure 层: UserPO, UserRepository, UserGatewayImpl, UserPOConvertor, PageUtil,YssDataMybatisConfig")
250
- print(" ✓ Adapter 层: UserController")
251
- print(" ✓ Bootstrap 层: YssDatamiddleApplication 启动类")
252
-
253
467
  def _generate_database_scripts(self):
254
- """生成数据库脚本"""
255
- print("\n🗃️ 生成数据库脚本...")
256
-
257
- # 针对 SQLite 的特殊处理
258
- if self.database == 'sqlite':
259
- schema_content = """-- 用户表
260
- CREATE TABLE t_user (
261
- id INTEGER PRIMARY KEY,
262
- username VARCHAR(50) NOT NULL,
263
- email VARCHAR(100),
264
- status INTEGER NOT NULL DEFAULT 1,
265
- description VARCHAR(500),
266
- deleted INTEGER NOT NULL DEFAULT 0,
267
- created_by VARCHAR(50),
268
- created_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
269
- last_modified_by VARCHAR(50),
270
- last_modified_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
271
- );
272
-
273
- CREATE UNIQUE INDEX uk_username ON t_user (username);
274
- CREATE INDEX idx_status ON t_user (status);
275
- CREATE INDEX idx_created_date ON t_user (created_date);
276
-
277
- -- Leaf Alloc 表
278
- CREATE TABLE leaf_alloc (
279
- biz_tag VARCHAR(128) NOT NULL PRIMARY KEY,
280
- max_id BIGINT NOT NULL,
281
- step INT NOT NULL,
282
- description VARCHAR(256),
283
- update_time VARCHAR(256)
284
- );
285
- """
286
- # 直接写入 schema.sql
287
- schema_path = self.project_root / "db" / "schema.sql"
288
- self._write_file(schema_path, schema_content)
289
-
290
- # data.sql 模板处理 (如果有差异也可以在这里处理,暂时复用模板但需注意语法)
291
- # SQLite 的 data.sql 可以复用 MySQL 的 INSERT 语句,只要没有特殊函数
292
- data_templates = [
293
- (self.config_template_dir / "data.sql.template", self.project_root / "db" / "data.sql"),
294
- ]
295
- self._render_and_write_templates(data_templates)
296
-
297
- # 初始化 SQLite 数据库
298
- print(" Initializing SQLite database...")
299
- try:
300
- db_file = self.project_root / f"{self.project_name}-bootstrap" / f"{self.db_name}.db"
301
- # 如果文件存在先删除,确保干净的初始化
302
- if db_file.exists():
303
- db_file.unlink()
304
-
305
- conn = sqlite3.connect(str(db_file))
306
- cursor = conn.cursor()
307
-
308
- # 执行 schema.sql
309
- if schema_path.exists():
310
- cursor.executescript(schema_path.read_text(encoding='utf-8'))
311
- print(" ✓ Executed schema.sql")
312
-
313
- # 执行 data.sql
314
- data_path = self.project_root / "db" / "data.sql"
315
- if data_path.exists():
316
- cursor.executescript(data_path.read_text(encoding='utf-8'))
317
- print(" ✓ Executed data.sql")
318
-
319
- conn.commit()
320
- conn.close()
321
- print(f" ✓ Created database: {db_file.name}")
322
- except Exception as e:
323
- print(f" ❌ Failed to initialize SQLite database: {e}")
324
-
325
- else:
326
- # 默认 (MySQL) 处理
327
- db_templates = [
328
- (self.config_template_dir / "schema.sql.template", self.project_root / "db" / "schema.sql"),
329
- (self.config_template_dir / "data.sql.template", self.project_root / "db" / "data.sql"),
330
- ]
331
- self._render_and_write_templates(db_templates)
332
-
333
- print(" ✓ schema.sql (建表脚本)")
334
- print(" ✓ data.sql (初始化数据)")
468
+ """只保留数据库目录布局,不生成业务表或初始化数据。"""
469
+ print("\n🗃️ 保留数据库目录布局...")
470
+ print(" ✓ db/(业务 schema 和初始化数据由批准切片合同生成)")
335
471
 
336
472
  def _generate_documentation(self):
337
- """生成项目文档"""
473
+ """生成不包含业务 API 的项目说明。"""
338
474
  print("\n📚 生成项目文档...")
339
- readme_path = self.project_root / "README.md"
340
- api_path = self.project_root / "API.md"
341
475
  readme_content = self._render_text(
342
476
  "# {{project_name}}\n\n"
343
477
  "## 模块说明\n\n"
@@ -346,28 +480,54 @@ CREATE TABLE leaf_alloc (
346
480
  "- {{project_name}}-infrastructure\n"
347
481
  "- {{project_name}}-adapter\n"
348
482
  "- {{project_name}}-bootstrap\n\n"
483
+ "业务 API、领域模型、数据结构和权限行为必须在冻结的 "
484
+ "Slice Implementation Contract 下,由对应 YSS skill 逐切片实现。\n\n"
349
485
  "## 快速开始\n\n"
350
486
  "```bash\n"
351
487
  "cd {{project_name}}\n"
352
488
  "./mvnw clean compile\n"
353
489
  "./mvnw spring-boot:run -pl {{project_name}}-bootstrap\n"
354
490
  "```\n",
355
- self._template_vars()
356
- )
357
- api_content = self._render_text(
358
- "# {{project_name}} API\n\n"
359
- "## 用户接口\n\n"
360
- "- POST /api/users/page\n"
361
- "- GET /api/users/{id}\n"
362
- "- POST /api/users\n"
363
- "- PUT /api/users\n"
364
- "- DELETE /api/users/{id}\n",
365
- self._template_vars()
491
+ self._template_vars(),
366
492
  )
367
- self._write_file(readme_path, readme_content)
368
- self._write_file(api_path, api_content)
493
+ self._write_file(self.project_root / "README.md", readme_content)
369
494
  print(" ✓ README.md")
370
- print(" ✓ API.md")
495
+
496
+ def _write_generation_manifest(self):
497
+ """把脚手架合同引用和生成输入写入非业务元数据清单。"""
498
+ manifest = {
499
+ "schema_version": 1,
500
+ "contract_id": self.contract_id,
501
+ "contract_version": self.contract_version,
502
+ "approval_ref": self.approval_ref,
503
+ "router_draft_ref": self.router_draft_ref,
504
+ "persisted_ref": self.persisted_ref,
505
+ "contract_file_ref": str(self.contract_file),
506
+ "slice_id": self.scaffold_contract["slice_id"],
507
+ "lifecycle_approval_ref": self.scaffold_contract["lifecycle_approval_ref"],
508
+ "current_version": self.scaffold_contract["current_version"],
509
+ "approver": self.scaffold_contract["approval"]["approver"],
510
+ "allowed_write_paths": self.scaffold_contract["allowed_write_paths"],
511
+ "expected_evidence_files": self.scaffold_contract["expected_evidence_files"],
512
+ "project_name": self.project_name,
513
+ "base_package": self.base_package,
514
+ "database": self.database,
515
+ "generation_mode": "controlled-generation",
516
+ "force": self.force,
517
+ "overwrite_scope": self.overwrite_scope,
518
+ "rollback_ref": self.rollback_ref,
519
+ "verification_commands": [
520
+ "./mvnw validate",
521
+ "./mvnw test",
522
+ "./mvnw package",
523
+ ],
524
+ "generated_at": datetime.now().astimezone().isoformat(),
525
+ }
526
+ self._write_file(
527
+ self.project_root / ".yss/scaffold-generation.json",
528
+ json.dumps(manifest, ensure_ascii=False, indent=2) + "\n",
529
+ )
530
+ print(" ✓ .yss/scaffold-generation.json")
371
531
 
372
532
  def _copy_wrapper_files(self):
373
533
  wrapper_dir = self.template_root.parent / "wrapper"
@@ -384,7 +544,7 @@ CREATE TABLE leaf_alloc (
384
544
  shutil.rmtree(mvn_dir_target)
385
545
  shutil.copytree(mvn_dir_source, mvn_dir_target)
386
546
 
387
- def _render_and_write_templates(self, items: List[tuple]):
547
+ def _render_and_write_templates(self, items: List[Tuple[Path, Path]]):
388
548
  variables = self._template_vars()
389
549
  for template_path, output_path in items:
390
550
  content = self._load_template(template_path)
@@ -418,7 +578,7 @@ CREATE TABLE leaf_alloc (
418
578
  "driver_class": self.driver_class,
419
579
  "db_name": self.db_name,
420
580
  "jdbc_url": self.jdbc_url,
421
- "db_dependency": self.db_dependency
581
+ "db_dependency": self.db_dependency,
422
582
  }
423
583
 
424
584
  def _resolve_group_id(self, base_package: str) -> str:
@@ -432,16 +592,19 @@ CREATE TABLE leaf_alloc (
432
592
  "mysql": "com.mysql.cj.jdbc.Driver",
433
593
  "postgres": "org.postgresql.Driver",
434
594
  "oracle": "oracle.jdbc.OracleDriver",
435
- "sqlite": "org.sqlite.JDBC"
595
+ "sqlite": "org.sqlite.JDBC",
436
596
  }
437
597
  return drivers.get(database, "com.mysql.cj.jdbc.Driver")
438
598
 
439
599
  def _resolve_jdbc_url(self, database: str, db_name: str) -> str:
440
600
  if database == "sqlite":
441
601
  return f"jdbc:sqlite:{db_name}.db"
442
- elif database == "mysql":
443
- return f"jdbc:mysql://localhost:3306/{db_name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai"
444
- elif database == "postgres":
602
+ if database == "mysql":
603
+ return (
604
+ f"jdbc:mysql://localhost:3306/{db_name}?useUnicode=true&"
605
+ "characterEncoding=utf8&serverTimezone=Asia/Shanghai"
606
+ )
607
+ if database == "postgres":
445
608
  return f"jdbc:postgresql://localhost:5432/{db_name}"
446
609
  return ""
447
610
 
@@ -452,81 +615,134 @@ CREATE TABLE leaf_alloc (
452
615
  <artifactId>sqlite-jdbc</artifactId>
453
616
  <version>3.51.1.0</version>
454
617
  </dependency>"""
455
- elif database == "mysql":
618
+ if database == "mysql":
456
619
  return """<dependency>
457
620
  <groupId>com.mysql</groupId>
458
621
  <artifactId>mysql-connector-j</artifactId>
459
622
  <version>8.4.0</version>
460
623
  <scope>compile</scope>
461
624
  </dependency>"""
462
- elif database == "postgres":
625
+ if database == "postgres":
463
626
  return """<dependency>
464
627
  <groupId>org.postgresql</groupId>
465
628
  <artifactId>postgresql</artifactId>
466
629
  <version>42.7.3</version>
467
630
  </dependency>"""
468
-
469
631
  return ""
470
632
 
471
633
 
472
634
  def main():
473
- """主函数"""
635
+ """命令行入口。"""
474
636
  parser = argparse.ArgumentParser(
475
- description='YSS DDD 脚手架生成器',
637
+ description="YSS DDD 脚手架生成器",
476
638
  formatter_class=argparse.RawDescriptionHelpFormatter,
477
- epilog='''
639
+ epilog="""
478
640
  示例:
479
641
  python generate_scaffold.py --project-name my-service --base-package com.yss.myservice --output-dir /path/to/repo
480
- python generate_scaffold.py --project-name user-service --base-package com.yss.user --output-dir /path/to/repo --database mysql
481
- '''
642
+ python generate_scaffold.py --project-name order-service --base-package com.yss.order --output-dir /path/to/repo --database mysql
643
+ """,
482
644
  )
483
-
484
- parser.add_argument('--project-name', required=True,
485
- help='项目名称 (kebab-case, 例如: user-service)')
486
- parser.add_argument('--base-package', required=True,
487
- help='基础包名 (例如: com.yss.user)')
488
- parser.add_argument('--output-dir', required=True,
489
- help='输出目录;必须显式指定')
645
+ parser.add_argument(
646
+ "--project-name",
647
+ required=True,
648
+ help="项目名称 (kebab-case, 例如: user-service)",
649
+ )
650
+ parser.add_argument(
651
+ "--base-package",
652
+ required=True,
653
+ help="基础包名 (例如: com.yss.user)",
654
+ )
655
+ parser.add_argument("--output-dir", required=True, help="输出目录;必须显式指定")
490
656
  example_group = parser.add_mutually_exclusive_group()
491
- example_group.add_argument('--with-example', dest='with_example', action='store_true',
492
- help='显式生成 User CRUD 示例代码')
493
- example_group.add_argument('--without-example', dest='with_example', action='store_false',
494
- help='不生成示例代码(默认)')
657
+ example_group.add_argument(
658
+ "--with-example",
659
+ dest="with_example",
660
+ action="store_true",
661
+ help="已禁用:业务示例必须按批准切片合同生成",
662
+ )
663
+ example_group.add_argument(
664
+ "--without-example",
665
+ dest="with_example",
666
+ action="store_false",
667
+ help="不生成示例代码(默认)",
668
+ )
495
669
  parser.set_defaults(with_example=False)
496
- parser.add_argument('--database', default='mysql',
497
- choices=['mysql'],
498
- help='数据库类型;当前仅支持经过验证的 mysql(默认)')
499
- parser.add_argument('--force', action='store_true',
500
- help='显式允许写入非空输出目录;默认拒绝覆盖')
670
+ parser.add_argument(
671
+ "--database",
672
+ default="mysql",
673
+ choices=["mysql"],
674
+ help="数据库类型;当前仅支持经过验证的 mysql(默认)",
675
+ )
676
+ parser.add_argument(
677
+ "--force",
678
+ action="store_true",
679
+ help="显式允许写入非空输出目录;必须同时提供批准合同元数据",
680
+ )
681
+ parser.add_argument("--contract-id", help="脚手架合同 ID;生成时必填")
682
+ parser.add_argument(
683
+ "--contract-version",
684
+ type=int,
685
+ help="脚手架合同版本;生成时必填",
686
+ )
687
+ parser.add_argument(
688
+ "--approval-ref",
689
+ help="生命周期批准引用;生成时必填",
690
+ )
691
+ parser.add_argument(
692
+ "--router-draft-ref",
693
+ help="Router 脚手架合同 draft 引用;生成时必填",
694
+ )
695
+ parser.add_argument(
696
+ "--persisted-ref",
697
+ help="已持久化脚手架合同引用;生成时必填",
698
+ )
699
+ parser.add_argument(
700
+ "--contract-file",
701
+ required=True,
702
+ help="已批准且已持久化的结构化脚手架合同 JSON 文件;生成时必填",
703
+ )
704
+ parser.add_argument(
705
+ "--overwrite-scope",
706
+ help="合同批准的覆盖范围;非空目录使用 --force 时必填",
707
+ )
708
+ parser.add_argument(
709
+ "--rollback-ref",
710
+ help="可回滚 checkpoint 引用;非空目录使用 --force 时必填",
711
+ )
501
712
 
502
713
  args = parser.parse_args()
503
714
 
504
- # 验证项目名称格式
505
- if not re.match(r'^[a-z][a-z0-9-]*$', args.project_name):
715
+ if not re.match(r"^[a-z][a-z0-9-]*$", args.project_name):
506
716
  print("❌ 错误: 项目名称必须是 kebab-case 格式 (例如: user-service)")
507
717
  sys.exit(1)
508
-
509
- # 验证包名格式
510
- if not re.match(r'^[a-z](?:[a-z0-9]*)(?:\.[a-z](?:[a-z0-9]*)?)*$', args.base_package):
718
+ if not re.match(r"^[a-z](?:[a-z0-9]*)(?:\.[a-z](?:[a-z0-9]*)?)*$", args.base_package):
511
719
  print("❌ 错误: 包名格式不正确 (例如: com.yss.user)")
512
720
  sys.exit(1)
513
-
514
- # 创建生成器并执行
515
- generator = ScaffoldGenerator(
516
- project_name=args.project_name,
517
- base_package=args.base_package,
518
- output_dir=args.output_dir,
519
- with_example=args.with_example,
520
- database=args.database,
521
- force=args.force
522
- )
721
+ if args.with_example:
722
+ parser.error("--with-example 已禁用;业务代码必须由批准的 YSS Slice skill 逐切片生成")
523
723
 
524
724
  try:
725
+ generator = ScaffoldGenerator(
726
+ project_name=args.project_name,
727
+ base_package=args.base_package,
728
+ output_dir=args.output_dir,
729
+ with_example=args.with_example,
730
+ database=args.database,
731
+ force=args.force,
732
+ contract_id=args.contract_id,
733
+ contract_version=args.contract_version,
734
+ approval_ref=args.approval_ref,
735
+ router_draft_ref=args.router_draft_ref,
736
+ persisted_ref=args.persisted_ref,
737
+ contract_file=args.contract_file,
738
+ overwrite_scope=args.overwrite_scope,
739
+ rollback_ref=args.rollback_ref,
740
+ )
525
741
  generator.generate()
526
- except Exception as e:
527
- print(f"\n❌ 生成失败: {str(e)}")
742
+ except Exception as exception:
743
+ print(f"\n❌ 生成失败: {str(exception)}")
528
744
  sys.exit(1)
529
745
 
530
746
 
531
- if __name__ == '__main__':
747
+ if __name__ == "__main__":
532
748
  main()