ai-engineering-init 1.3.4 → 1.4.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 (227) hide show
  1. package/.claude/hooks/skill-forced-eval.js +2 -0
  2. package/.claude/settings.json +3 -3
  3. package/.claude/skills/add-skill/SKILL.md +79 -32
  4. package/.claude/skills/api-development/SKILL.md +83 -377
  5. package/.claude/skills/architecture-design/SKILL.md +138 -632
  6. package/.claude/skills/backend-annotations/SKILL.md +134 -506
  7. package/.claude/skills/banana-image/SKILL.md +10 -3
  8. package/.claude/skills/brainstorm/SKILL.md +103 -535
  9. package/.claude/skills/bug-detective/SKILL.md +147 -1097
  10. package/.claude/skills/bug-detective/references/error-patterns.md +242 -0
  11. package/.claude/skills/code-patterns/SKILL.md +116 -426
  12. package/.claude/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  13. package/.claude/skills/crud-development/SKILL.md +64 -304
  14. package/.claude/skills/data-permission/SKILL.md +105 -412
  15. package/.claude/skills/data-permission/references/custom-data-scope.md +90 -0
  16. package/.claude/skills/file-oss-management/SKILL.md +106 -714
  17. package/.claude/skills/file-oss-management/references/entities.md +105 -0
  18. package/.claude/skills/file-oss-management/references/service-impl.md +104 -0
  19. package/.claude/skills/leniu-api-development/SKILL.md +142 -626
  20. package/.claude/skills/leniu-api-development/references/real-examples.md +273 -0
  21. package/.claude/skills/leniu-architecture-design/SKILL.md +176 -391
  22. package/.claude/skills/leniu-backend-annotations/SKILL.md +132 -519
  23. package/.claude/skills/leniu-brainstorm/SKILL.md +132 -541
  24. package/.claude/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  25. package/.claude/skills/leniu-crud-development/SKILL.md +232 -938
  26. package/.claude/skills/leniu-crud-development/references/templates.md +597 -0
  27. package/.claude/skills/leniu-customization-location/SKILL.md +410 -0
  28. package/.claude/skills/leniu-data-permission/SKILL.md +70 -0
  29. package/.claude/skills/leniu-java-entity/SKILL.md +76 -590
  30. package/.claude/skills/leniu-java-entity/references/templates.md +237 -0
  31. package/.claude/skills/leniu-java-export/SKILL.md +94 -379
  32. package/.claude/skills/leniu-java-logging/SKILL.md +106 -709
  33. package/.claude/skills/leniu-java-logging/references/data-mask.md +46 -0
  34. package/.claude/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  35. package/.claude/skills/leniu-java-mybatis/SKILL.md +73 -446
  36. package/.claude/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  37. package/.claude/skills/leniu-report-customization/SKILL.md +111 -365
  38. package/.claude/skills/leniu-report-customization/references/table-fields.md +93 -0
  39. package/.claude/skills/leniu-report-standard-customization/SKILL.md +111 -334
  40. package/.claude/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  41. package/.claude/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  42. package/.claude/skills/leniu-security-guard/SKILL.md +133 -347
  43. package/.claude/skills/mysql-debug/SKILL.md +364 -0
  44. package/.claude/skills/openspec-apply-change/SKILL.md +10 -1
  45. package/.claude/skills/openspec-archive-change/SKILL.md +9 -1
  46. package/.claude/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  47. package/.claude/skills/openspec-continue-change/SKILL.md +9 -1
  48. package/.claude/skills/openspec-explore/SKILL.md +10 -1
  49. package/.claude/skills/openspec-ff-change/SKILL.md +9 -1
  50. package/.claude/skills/openspec-new-change/SKILL.md +9 -1
  51. package/.claude/skills/openspec-onboard/SKILL.md +15 -130
  52. package/.claude/skills/openspec-sync-specs/SKILL.md +9 -1
  53. package/.claude/skills/openspec-verify-change/SKILL.md +9 -1
  54. package/.claude/skills/performance-doctor/SKILL.md +110 -434
  55. package/.claude/skills/redis-cache/SKILL.md +89 -595
  56. package/.claude/skills/redis-cache/references/listeners.md +23 -0
  57. package/.claude/skills/scheduled-jobs/SKILL.md +88 -407
  58. package/.claude/skills/security-guard/SKILL.md +137 -532
  59. package/.claude/skills/security-guard/references/encrypt-config.md +103 -0
  60. package/.claude/skills/security-guard/references/sensitive-strategies.md +42 -0
  61. package/.claude/skills/sms-mail/SKILL.md +116 -574
  62. package/.claude/skills/sms-mail/references/mail-config.md +88 -0
  63. package/.claude/skills/sms-mail/references/sms-config.md +74 -0
  64. package/.claude/skills/social-login/SKILL.md +112 -514
  65. package/.claude/skills/social-login/references/provider-configs.md +118 -0
  66. package/.claude/skills/tenant-management/SKILL.md +129 -444
  67. package/.claude/skills/tenant-management/references/tenant-scenarios.md +91 -0
  68. package/.claude/skills/test-development/SKILL.md +86 -540
  69. package/.claude/skills/test-development/references/parameterized-examples.md +119 -0
  70. package/.claude/skills/utils-toolkit/SKILL.md +52 -305
  71. package/.claude/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  72. package/.claude/skills/websocket-sse/SKILL.md +105 -550
  73. package/.claude/skills/workflow-engine/SKILL.md +147 -502
  74. package/.codex/skills/add-skill/SKILL.md +79 -32
  75. package/.codex/skills/api-development/SKILL.md +172 -599
  76. package/.codex/skills/architecture-design/SKILL.md +138 -504
  77. package/.codex/skills/backend-annotations/SKILL.md +134 -496
  78. package/.codex/skills/banana-image/SKILL.md +10 -3
  79. package/.codex/skills/brainstorm/SKILL.md +103 -535
  80. package/.codex/skills/bug-detective/SKILL.md +147 -1097
  81. package/.codex/skills/bug-detective/references/error-patterns.md +242 -0
  82. package/.codex/skills/code-patterns/SKILL.md +120 -282
  83. package/.codex/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  84. package/.codex/skills/crud-development/SKILL.md +64 -292
  85. package/.codex/skills/data-permission/SKILL.md +108 -407
  86. package/.codex/skills/data-permission/references/custom-data-scope.md +90 -0
  87. package/.codex/skills/database-ops/SKILL.md +8 -154
  88. package/.codex/skills/error-handler/SKILL.md +10 -0
  89. package/.codex/skills/file-oss-management/SKILL.md +106 -714
  90. package/.codex/skills/file-oss-management/references/entities.md +105 -0
  91. package/.codex/skills/file-oss-management/references/service-impl.md +104 -0
  92. package/.codex/skills/git-workflow/SKILL.md +27 -5
  93. package/.codex/skills/leniu-api-development/SKILL.md +142 -626
  94. package/.codex/skills/leniu-api-development/references/real-examples.md +273 -0
  95. package/.codex/skills/leniu-architecture-design/SKILL.md +176 -391
  96. package/.codex/skills/leniu-backend-annotations/SKILL.md +132 -519
  97. package/.codex/skills/leniu-brainstorm/SKILL.md +132 -541
  98. package/.codex/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  99. package/.codex/skills/leniu-crud-development/SKILL.md +232 -938
  100. package/.codex/skills/leniu-crud-development/references/templates.md +597 -0
  101. package/.codex/skills/leniu-customization-location/SKILL.md +410 -0
  102. package/.codex/skills/leniu-data-permission/SKILL.md +70 -0
  103. package/.codex/skills/leniu-java-code-style/SKILL.md +510 -0
  104. package/.codex/skills/leniu-java-entity/SKILL.md +76 -590
  105. package/.codex/skills/leniu-java-entity/references/templates.md +237 -0
  106. package/.codex/skills/leniu-java-export/SKILL.md +94 -379
  107. package/.codex/skills/leniu-java-logging/SKILL.md +106 -709
  108. package/.codex/skills/leniu-java-logging/references/data-mask.md +46 -0
  109. package/.codex/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  110. package/.codex/skills/leniu-java-mybatis/SKILL.md +73 -446
  111. package/.codex/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  112. package/.codex/skills/leniu-report-customization/SKILL.md +111 -365
  113. package/.codex/skills/leniu-report-customization/references/table-fields.md +93 -0
  114. package/.codex/skills/leniu-report-standard-customization/SKILL.md +111 -334
  115. package/.codex/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  116. package/.codex/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  117. package/.codex/skills/leniu-security-guard/SKILL.md +133 -347
  118. package/.codex/skills/mysql-debug/SKILL.md +364 -0
  119. package/.codex/skills/openspec-apply-change/SKILL.md +10 -1
  120. package/.codex/skills/openspec-archive-change/SKILL.md +9 -1
  121. package/.codex/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  122. package/.codex/skills/openspec-continue-change/SKILL.md +9 -1
  123. package/.codex/skills/openspec-explore/SKILL.md +10 -1
  124. package/.codex/skills/openspec-ff-change/SKILL.md +9 -1
  125. package/.codex/skills/openspec-new-change/SKILL.md +9 -1
  126. package/.codex/skills/openspec-onboard/SKILL.md +15 -130
  127. package/.codex/skills/openspec-sync-specs/SKILL.md +9 -1
  128. package/.codex/skills/openspec-verify-change/SKILL.md +9 -1
  129. package/.codex/skills/performance-doctor/SKILL.md +110 -434
  130. package/.codex/skills/project-navigator/SKILL.md +20 -1
  131. package/.codex/skills/redis-cache/SKILL.md +93 -589
  132. package/.codex/skills/redis-cache/references/listeners.md +23 -0
  133. package/.codex/skills/scheduled-jobs/SKILL.md +88 -407
  134. package/.codex/skills/security-guard/SKILL.md +141 -527
  135. package/.codex/skills/security-guard/references/encrypt-config.md +103 -0
  136. package/.codex/skills/security-guard/references/sensitive-strategies.md +42 -0
  137. package/.codex/skills/sms-mail/SKILL.md +116 -574
  138. package/.codex/skills/sms-mail/references/mail-config.md +88 -0
  139. package/.codex/skills/sms-mail/references/sms-config.md +74 -0
  140. package/.codex/skills/social-login/SKILL.md +112 -514
  141. package/.codex/skills/social-login/references/provider-configs.md +118 -0
  142. package/.codex/skills/store-pc/SKILL.md +258 -383
  143. package/.codex/skills/tenant-management/SKILL.md +129 -444
  144. package/.codex/skills/tenant-management/references/tenant-scenarios.md +91 -0
  145. package/.codex/skills/test-development/SKILL.md +86 -540
  146. package/.codex/skills/test-development/references/parameterized-examples.md +119 -0
  147. package/.codex/skills/ui-pc/SKILL.md +350 -387
  148. package/.codex/skills/utils-toolkit/SKILL.md +52 -283
  149. package/.codex/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  150. package/.codex/skills/websocket-sse/SKILL.md +105 -550
  151. package/.codex/skills/workflow-engine/SKILL.md +147 -502
  152. package/.cursor/hooks/cursor-skill-eval.js +53 -1
  153. package/.cursor/hooks.json +3 -3
  154. package/.cursor/skills/add-skill/SKILL.md +79 -32
  155. package/.cursor/skills/api-development/SKILL.md +83 -377
  156. package/.cursor/skills/architecture-design/SKILL.md +138 -632
  157. package/.cursor/skills/backend-annotations/SKILL.md +134 -506
  158. package/.cursor/skills/banana-image/SKILL.md +10 -3
  159. package/.cursor/skills/brainstorm/SKILL.md +103 -535
  160. package/.cursor/skills/bug-detective/SKILL.md +147 -1097
  161. package/.cursor/skills/bug-detective/references/error-patterns.md +242 -0
  162. package/.cursor/skills/code-patterns/SKILL.md +116 -426
  163. package/.cursor/skills/code-patterns/references/leniu-code-patterns.md +87 -0
  164. package/.cursor/skills/crud-development/SKILL.md +64 -304
  165. package/.cursor/skills/data-permission/SKILL.md +105 -412
  166. package/.cursor/skills/data-permission/references/custom-data-scope.md +90 -0
  167. package/.cursor/skills/file-oss-management/SKILL.md +106 -714
  168. package/.cursor/skills/file-oss-management/references/entities.md +105 -0
  169. package/.cursor/skills/file-oss-management/references/service-impl.md +104 -0
  170. package/.cursor/skills/git-workflow/SKILL.md +27 -5
  171. package/.cursor/skills/leniu-api-development/SKILL.md +142 -626
  172. package/.cursor/skills/leniu-api-development/references/real-examples.md +273 -0
  173. package/.cursor/skills/leniu-architecture-design/SKILL.md +176 -391
  174. package/.cursor/skills/leniu-backend-annotations/SKILL.md +132 -519
  175. package/.cursor/skills/leniu-brainstorm/SKILL.md +132 -541
  176. package/.cursor/skills/leniu-brainstorm/references/business-scenarios.md +162 -0
  177. package/.cursor/skills/leniu-crud-development/SKILL.md +232 -938
  178. package/.cursor/skills/leniu-crud-development/references/templates.md +597 -0
  179. package/.cursor/skills/leniu-customization-location/SKILL.md +410 -0
  180. package/.cursor/skills/leniu-data-permission/SKILL.md +70 -0
  181. package/.cursor/skills/leniu-java-code-style/SKILL.md +510 -0
  182. package/.cursor/skills/leniu-java-entity/SKILL.md +76 -590
  183. package/.cursor/skills/leniu-java-entity/references/templates.md +237 -0
  184. package/.cursor/skills/leniu-java-export/SKILL.md +94 -379
  185. package/.cursor/skills/leniu-java-logging/SKILL.md +106 -709
  186. package/.cursor/skills/leniu-java-logging/references/data-mask.md +46 -0
  187. package/.cursor/skills/leniu-java-logging/references/logging-scenarios.md +113 -0
  188. package/.cursor/skills/leniu-java-mybatis/SKILL.md +73 -446
  189. package/.cursor/skills/leniu-java-mybatis/references/report-mapper.md +88 -0
  190. package/.cursor/skills/leniu-report-customization/SKILL.md +111 -365
  191. package/.cursor/skills/leniu-report-customization/references/table-fields.md +93 -0
  192. package/.cursor/skills/leniu-report-standard-customization/SKILL.md +111 -334
  193. package/.cursor/skills/leniu-report-standard-customization/references/analysis-module.md +64 -0
  194. package/.cursor/skills/leniu-report-standard-customization/references/table-fields.md +113 -0
  195. package/.cursor/skills/leniu-security-guard/SKILL.md +133 -347
  196. package/.cursor/skills/mysql-debug/SKILL.md +364 -0
  197. package/.cursor/skills/openspec-apply-change/SKILL.md +10 -1
  198. package/.cursor/skills/openspec-archive-change/SKILL.md +9 -1
  199. package/.cursor/skills/openspec-bulk-archive-change/SKILL.md +9 -1
  200. package/.cursor/skills/openspec-continue-change/SKILL.md +9 -1
  201. package/.cursor/skills/openspec-explore/SKILL.md +10 -1
  202. package/.cursor/skills/openspec-ff-change/SKILL.md +9 -1
  203. package/.cursor/skills/openspec-new-change/SKILL.md +9 -1
  204. package/.cursor/skills/openspec-onboard/SKILL.md +15 -130
  205. package/.cursor/skills/openspec-sync-specs/SKILL.md +9 -1
  206. package/.cursor/skills/openspec-verify-change/SKILL.md +9 -1
  207. package/.cursor/skills/performance-doctor/SKILL.md +110 -434
  208. package/.cursor/skills/redis-cache/SKILL.md +89 -595
  209. package/.cursor/skills/redis-cache/references/listeners.md +23 -0
  210. package/.cursor/skills/scheduled-jobs/SKILL.md +88 -407
  211. package/.cursor/skills/security-guard/SKILL.md +137 -532
  212. package/.cursor/skills/security-guard/references/encrypt-config.md +103 -0
  213. package/.cursor/skills/security-guard/references/sensitive-strategies.md +42 -0
  214. package/.cursor/skills/sms-mail/SKILL.md +116 -574
  215. package/.cursor/skills/sms-mail/references/mail-config.md +88 -0
  216. package/.cursor/skills/sms-mail/references/sms-config.md +74 -0
  217. package/.cursor/skills/social-login/SKILL.md +112 -514
  218. package/.cursor/skills/social-login/references/provider-configs.md +118 -0
  219. package/.cursor/skills/tenant-management/SKILL.md +129 -444
  220. package/.cursor/skills/tenant-management/references/tenant-scenarios.md +91 -0
  221. package/.cursor/skills/test-development/SKILL.md +86 -540
  222. package/.cursor/skills/test-development/references/parameterized-examples.md +119 -0
  223. package/.cursor/skills/utils-toolkit/SKILL.md +52 -305
  224. package/.cursor/skills/utils-toolkit/references/redis-utils-api.md +56 -0
  225. package/.cursor/skills/websocket-sse/SKILL.md +105 -550
  226. package/.cursor/skills/workflow-engine/SKILL.md +147 -502
  227. package/package.json +1 -1
@@ -1,180 +1,144 @@
1
1
  ---
2
2
  name: leniu-architecture-design
3
3
  description: |
4
- leniu-yunshitang-core 项目架构设计指南。基于 pigx-framework 框架的云食堂双库架构,包含三层架构规范、双库多租户实现、业务模块划分、Entity 设计规范。
4
+ leniu-tengyun-core 项目架构设计指南。基于 pigx-framework 的云食堂双库架构,包含四层架构规范、双库多租户实现、模块划分、Entity 设计。
5
5
 
6
6
  触发场景:
7
- - 云食堂项目系统整体架构设计
8
- - 双库架构(系统库+商户库)的业务模块规划
9
- - 三层架构代码分层与重构策略
10
- - 多租户数据隔离设计
11
- - Entity 审计字段与逻辑删除设计
7
+ - 新模块/新功能的架构设计与代码分层
8
+ - 双库架构(系统库+商户库)数据路由决策
9
+ - 四层架构(Controller→Business→Service→Mapper)编排
10
+ - 多租户数据隔离与跨租户操作
11
+ - Entity/DTO/VO 结构设计
12
+ - Mapper XML 文件放置与配置
12
13
 
13
14
  适用项目:
14
15
  - leniu-tengyun-core:/Users/xujiajun/Developer/gongsi_proj/leniu-api/leniu-tengyun-core
15
16
  - leniu-yunshitang:/Users/xujiajun/Developer/gongsi_proj/leniu-api/leniu-tengyun/leniu-yunshitang
16
17
 
17
- 触发词:架构设计、双库架构、商户库、系统库、pigx框架、四层架构、模块划分、Business
18
+ 触发词:架构设计、双库架构、商户库、系统库、pigx框架、四层架构、模块划分、Business层、分层设计、代码结构
18
19
  ---
19
20
 
20
- # leniu-yunshitang-core 架构设计指南
21
+ # leniu-tengyun-core 架构设计指南
21
22
 
22
- ## 项目概述
23
+ ## 双库架构
23
24
 
24
- leniu-yunshitang-core 是基于 **pigx-framework** 的智慧食堂云服务平台,采用**双库架构**(系统库 + 商户库)实现多租户隔离。
25
+ 物理分离双库,**Entity tenant_id 字段**:
25
26
 
26
- **核心特点:**
27
- - JDK 21 + Spring Boot 3.x
28
- - 双库架构:系统库(全局数据)+ 商户库(租户数据)
29
- - 包名:`net.xnzn.*`
30
- - 租户识别:请求头 `MERCHANT-ID`
31
- - 审计字段:`crby/crtime/upby/uptime`
32
- - 逻辑删除:`del_flag`(1=删除,2=正常,注意与 RuoYi 相反)
27
+ | 库类型 | 数据范围 | 访问方式 |
28
+ |--------|---------|---------|
29
+ | **系统库** | 租户信息、商户配置、系统字典 | `Executors.doInSystem()` |
30
+ | **商户库** | 订单、菜品、用户、设备等 | 默认(请求头 `MERCHANT-ID`) |
33
31
 
34
- ---
35
-
36
- ## 双库架构设计
37
-
38
- ### 架构说明
39
-
40
- 本项目采用**物理分离的双库架构**,而非单库多租户:
41
-
42
- | 库类型 | 说明 | 数据范围 | 访问方式 |
43
- |--------|------|---------|---------|
44
- | **系统库** | 全局系统数据 | 租户信息、商户配置、系统字典等 | 默认访问(无 MERCHANT-ID) |
45
- | **商户库** | 租户业务数据 | 订单、菜品、用户、设备等商户数据 | 请求头携带 MERCHANT-ID 时访问 |
32
+ ### 多租户上下文切换
46
33
 
47
- **关键区别:**
48
- - Entity 不需要 `tenant_id` 字段(物理库隔离)
49
- - 通过 `TenantContextHolder.getTenantId()` 获取当前租户
50
- - 使用 `Executors.doInTenant()` / `doInSystem()` 切换库
34
+ ```java
35
+ // 获取当前租户
36
+ Long tenantId = TenantContextHolder.getTenantId();
51
37
 
52
- ### 双库配置示例
38
+ // 在指定商户库执行
39
+ Executors.doInTenant(tenantId, () -> { /* 商户库 */ });
53
40
 
54
- ```yaml
55
- # bootstrap.yml
56
- dataset:
57
- system:
58
- master:
59
- jdbcUrl: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/system
60
- username: ${MYSQL_USERNAME:root}
61
- password: ${MYSQL_PASSWORD:do@u.can}
41
+ // 在系统库执行
42
+ Executors.doInSystem(() -> { /* 系统库 */ });
62
43
 
63
- tenant:
64
- carrier-name: MERCHANT-ID
44
+ // 遍历所有租户执行(定时任务场景)
45
+ Executors.doInAllTenant(tenantId -> { /* 每个租户 */ });
65
46
  ```
66
47
 
67
- ### 多租户上下文
48
+ ### 双库路由场景
68
49
 
69
50
  ```java
70
- // 获取当前租户ID
71
- Long tenantId = TenantContextHolder.getTenantId();
51
+ // 场景1:商户业务(默认,前端请求头携带 MERCHANT-ID
52
+ @PostMapping("/order/add")
53
+ public void addOrder(@RequestBody LeRequest<OrderDTO> request) {
54
+ orderService.add(request.getContent()); // 自动路由商户库
55
+ }
72
56
 
73
- // 在指定租户库执行操作
74
- Executors.doInTenant(tenantId, () -> {
75
- // 业务代码 - 访问商户库
76
- });
57
+ // 场景2:系统配置操作
58
+ @PostMapping("/merchant/config")
59
+ public void updateConfig(@RequestBody LeRequest<ConfigDTO> request) {
60
+ Executors.doInSystem(() -> configService.update(request.getContent()));
61
+ }
77
62
 
78
- // 在系统库执行操作
79
- Executors.doInSystem(() -> {
80
- // 业务代码 - 访问系统库
81
- });
63
+ // 场景3:定时任务遍历所有租户
64
+ public void execute() {
65
+ Executors.doInAllTenant(tenantId -> reportService.generate(tenantId));
66
+ }
82
67
 
83
- // 遍历所有租户执行
84
- Executors.doInAllTenant(tenantId -> {
85
- // 业务代码
86
- });
68
+ // 场景4:MQ 消费指定租户
69
+ @RabbitListener(queues = "order.queue")
70
+ public void consumeOrder(Message message) {
71
+ Long tenantId = getTenantFromMessage(message);
72
+ Executors.doInTenant(tenantId, () -> orderService.process(message));
73
+ }
87
74
  ```
88
75
 
89
76
  ---
90
77
 
91
- ## 本项目技术栈
92
-
93
- ### 核心技术栈
94
-
95
- | 层级 | 技术栈 | 版本 | 说明 |
96
- |------|--------|------|------|
97
- | **后端框架** | Spring Boot | 3.x | 核心框架 |
98
- | **开发语言** | Java | 21 | LTS 版本 |
99
- | **ORM** | MyBatis-Plus | 3.x | 持久层框架 |
100
- | **基础框架** | pigx-framework | 3.4.7 | 企业级开发框架 |
101
- | **数据库** | MySQL | 8.0+ | 双库架构 |
102
- | **缓存** | Redis + Redisson | - | 分布式缓存 |
103
- | **容器** | Undertow | - | Web 容器(替换 Tomcat) |
104
-
105
- ### 项目模块结构
78
+ ## 四层架构
106
79
 
107
80
  ```
108
- leniu-tengyun-core/
109
- ├── core-base/ # 公共基础模块
110
- ├── core-aggregator/ # 聚合器
111
- ├── sys-common/ # 公共业务模块(支付、通知、对接等)
112
- ├── sys-canteen/ # 食堂业务模块
113
- ├── sys-kitchen/ # 后场厨房模块
114
- ├── sys-drp/ # 供应链模块
115
- ├── sys-logistics/ # 物流模块
116
- └── sys-open/ # 开放接口模块
81
+ Controller → Business → Service → Mapper
117
82
  ```
118
83
 
119
- ---
120
-
121
- ## 三层架构规范
84
+ | 层 | 职责 | 命名 |
85
+ |----|------|------|
86
+ | **Controller** | 接收请求、参数校验、路由分端 | `XxxWebController` |
87
+ | **Business** | 业务编排、跨 Service 协调 | `XxxWebBusiness` |
88
+ | **Service** | 单表 CRUD、事务 | `XxxServiceImpl` |
89
+ | **Mapper** | ORM 映射(XML 同目录) | `XxxMapper` |
122
90
 
123
- 本项目采用 **三层架构**:Controller Service Mapper
124
-
125
- **没有独立的 DAO 层!**
126
-
127
- ```
128
- ┌──────────────────────────────────────────────────────────────┐
129
- │ Controller 层 │
130
- │ • 接收 HTTP 请求、参数校验、返回 Page<T> │
131
- │ • 使用 LeRequest<T> 封装请求体 │
132
- │ • 使用 @RequiresAuthentication 权限控制 │
133
- └──────────────────────────────┬───────────────────────────────┘
134
-
135
-
136
- ┌──────────────────────────────────────────────────────────────┐
137
- │ Service 层 │
138
- │ • 业务逻辑处理、事务管理、编排协调 │
139
- │ • 直接注入 Mapper(无 DAO 层) │
140
- │ • 使用 MyBatis-Plus LambdaQueryWrapper │
141
- └──────────────────────────────┬───────────────────────────────┘
142
-
143
-
144
- ┌──────────────────────────────────────────────────────────────┐
145
- │ Mapper 层 │
146
- │ • extends BaseMapper<Entity> │
147
- │ • MyBatis-Plus ORM 映射、SQL 执行 │
148
- └──────────────────────────────────────────────────────────────┘
149
- ```
91
+ > **Business 层**是本项目核心特色,复杂逻辑在此编排,简单 CRUD 可跳过直接 ControllerService。
150
92
 
151
93
  ### Controller 示例
152
94
 
153
95
  ```java
154
96
  package net.xnzn.core.xxx.controller;
155
97
 
156
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
157
98
  import com.pig4cloud.pigx.common.core.util.LeRequest;
158
- import com.pig4cloud.pigx.common.core.exception.LeException;
159
99
  import net.xnzn.framework.secure.filter.annotation.RequiresAuthentication;
160
- import org.springframework.web.bind.annotation.*;
161
100
 
162
101
  @RestController
163
102
  @RequiresAuthentication
164
- @RequestMapping("/xxx/resource")
165
- public class XxxResourceController {
103
+ @RequestMapping("/api/v2/web/xxx")
104
+ public class XxxWebController {
166
105
 
167
106
  @Autowired
168
- private XxxServiceImpl xxxService;
107
+ private XxxWebBusiness xxxBusiness;
169
108
 
170
109
  @PostMapping("/add")
171
110
  public void add(@Validated @RequestBody LeRequest<XxxDTO> request) {
172
- xxxService.add(request.getContent());
111
+ xxxBusiness.add(request.getContent());
173
112
  }
174
113
 
175
114
  @PostMapping("/query")
176
115
  public Page<XxxVO> query(@Validated @RequestBody LeRequest<PageDTO> request) {
177
- return xxxService.query(request.getContent());
116
+ return xxxBusiness.query(request.getContent());
117
+ }
118
+ }
119
+ ```
120
+
121
+ ### Business 示例
122
+
123
+ ```java
124
+ package net.xnzn.core.xxx.business.impl;
125
+
126
+ @Component
127
+ public class XxxWebBusiness {
128
+
129
+ @Autowired
130
+ private XxxServiceImpl xxxService;
131
+ @Autowired
132
+ private YyyServiceImpl yyyService;
133
+
134
+ public void add(XxxDTO dto) {
135
+ // 编排多个 Service
136
+ xxxService.add(dto);
137
+ yyyService.bindRelation(dto.getId());
138
+ }
139
+
140
+ public Page<XxxVO> query(PageDTO dto) {
141
+ return xxxService.query(dto);
178
142
  }
179
143
  }
180
144
  ```
@@ -184,12 +148,6 @@ public class XxxResourceController {
184
148
  ```java
185
149
  package net.xnzn.core.xxx.service.impl;
186
150
 
187
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
188
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
189
- import net.xnzn.core.common.enums.DelFlagEnum;
190
- import net.xnzn.framework.id.Id;
191
- import org.springframework.stereotype.Service;
192
-
193
151
  @Service
194
152
  public class XxxServiceImpl {
195
153
  @Autowired
@@ -197,7 +155,9 @@ public class XxxServiceImpl {
197
155
 
198
156
  public void add(XxxDTO dto) {
199
157
  long id = Id.next();
200
- XxxEntity entity = dto.toEntity(id);
158
+ XxxEntity entity = new XxxEntity();
159
+ BeanUtil.copyProperties(dto, entity);
160
+ entity.setId(id);
201
161
  xxxMapper.insert(entity);
202
162
  }
203
163
 
@@ -212,36 +172,21 @@ public class XxxServiceImpl {
212
172
  ```java
213
173
  package net.xnzn.core.xxx.mapper;
214
174
 
215
- import com.baomidou.mybatisplus.core.mapper.BaseMapper;
216
- import net.xnzn.core.xxx.model.XxxEntity;
217
- import org.apache.ibatis.annotations.Mapper;
218
-
219
175
  @Mapper
220
176
  public interface XxxMapper extends BaseMapper<XxxEntity> {
221
- // 自定义查询方法
177
+ Page<XxxVO> page(Page<Object> page, @Param("keyword") String keyword);
222
178
  }
223
179
  ```
224
180
 
225
- ### ⚠️ Mapper XML 文件位置(重要差异)
226
-
227
- **leniu-yunshitang-core 的 XML 文件与 Java Mapper 放在同一目录**,而非传统的 `resources/mapper/` 目录!
181
+ ### Mapper XML(与 Java 同目录)
228
182
 
229
183
  ```
230
184
  src/main/java/net/xnzn/core/xxx/mapper/
231
- ├── XxxMapper.java # Java 接口
232
- └── XxxMapper.xml # XML 映射文件(同目录!)
233
- ```
234
-
235
- **对比 RuoYi-Vue-Plus:**
185
+ ├── XxxMapper.java
186
+ └── XxxMapper.xml 同目录,非 resources/mapper/
236
187
  ```
237
- # RuoYi-Vue-Plus 传统方式
238
- src/main/java/.../mapper/XxxMapper.java
239
- src/main/resources/mapper/XxxMapper.xml # XML 在 resources 目录
240
- ```
241
-
242
- **配置要求:**
243
- 需要在 `pom.xml` 中配置资源过滤,让 Maven 将 Java 目录下的 XML 文件也打包:
244
188
 
189
+ **pom.xml 必须配置资源过滤:**
245
190
  ```xml
246
191
  <build>
247
192
  <resources>
@@ -260,81 +205,65 @@ src/main/resources/mapper/XxxMapper.xml # XML 在 resources 目录
260
205
 
261
206
  **XML 文件示例:**
262
207
  ```xml
263
- <!-- XxxMapper.xml -->
264
208
  <?xml version="1.0" encoding="UTF-8"?>
265
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
209
+ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
210
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
266
211
  <mapper namespace="net.xnzn.core.xxx.mapper.XxxMapper">
267
-
268
212
  <select id="page" resultType="net.xnzn.core.xxx.vo.XxxVO">
269
- SELECT * FROM xxx_table
213
+ SELECT id, name, status, crtime, uptime
214
+ FROM xxx_table
270
215
  WHERE del_flag = 2
271
216
  <if test="keyword != null and keyword != ''">
272
217
  AND name LIKE CONCAT('%', #{keyword}, '%')
273
218
  </if>
274
219
  </select>
275
-
276
220
  </mapper>
277
221
  ```
278
222
 
279
223
  ---
280
224
 
281
- ## Entity 设计规范
225
+ ## 多端 Controller 路由
282
226
 
283
- ### Entity 审计字段
227
+ | | 路由前缀 | Controller 命名 |
228
+ |----|---------|----------------|
229
+ | Web 管理端 | `/api/v2/web/{module}` | `XxxWebController` |
230
+ | 移动端 | `/api/v2/mobile/{module}` | `XxxMobileController` |
231
+ | 设备端 | `/api/v2/android/{module}` | `XxxAndroidController` |
232
+ | 开放接口 | `/api/v2/open/{module}` | `XxxOpenController` |
233
+
234
+ ---
235
+
236
+ ## Entity 设计
284
237
 
285
238
  ```java
286
239
  package net.xnzn.core.xxx.model;
287
240
 
288
- import com.baomidou.mybatisplus.annotation.*;
289
- import lombok.Data;
290
- import java.time.LocalDateTime;
291
-
292
241
  @Data
293
242
  @TableName("xxx_table")
294
243
  public class XxxEntity {
295
244
 
296
- // 主键(雪花ID或自增)
297
- @TableId(value = "id", type = IdType.AUTO)
298
- private Long id;
245
+ @TableId(value = "id", type = IdType.ASSIGN_ID)
246
+ private Long id; // 雪花ID:Id.next()
299
247
 
300
- // 业务字段
301
248
  private String name;
302
249
  private Integer status;
303
250
 
304
251
  // 审计字段
305
252
  @TableField(fill = FieldFill.INSERT)
306
- private String crby; // 创建人
307
-
253
+ private String crby;
308
254
  @TableField(fill = FieldFill.INSERT)
309
- private LocalDateTime crtime; // 创建时间
310
-
255
+ private LocalDateTime crtime;
311
256
  @TableField(fill = FieldFill.INSERT_UPDATE)
312
- private String upby; // 更新人
313
-
257
+ private String upby;
314
258
  @TableField(fill = FieldFill.INSERT_UPDATE)
315
- private LocalDateTime uptime; // 更新时间
259
+ private LocalDateTime uptime;
316
260
 
317
- // 逻辑删除(注意:1=删除,2=正常,与 RuoYi 相反)
261
+ // 逻辑删除:1=删除,2=正常
318
262
  private Integer delFlag;
319
263
  }
320
264
  ```
321
265
 
322
- ### 审计字段说明
323
-
324
- | 字段 | 含义 | 自动填充 |
325
- |------|------|---------|
326
- | `crby` | 创建人 | INSERT |
327
- | `crtime` | 创建时间 | INSERT |
328
- | `upby` | 更新人 | INSERT_UPDATE |
329
- | `uptime` | 更新时间 | INSERT_UPDATE |
330
- | `delFlag` | 逻辑删除(1=删除,2=正常) | 手动设置 |
331
-
332
- **注意:**
333
- - `del_flag` 值与 RuoYi-Vue-Plus 相反!
334
- - leniu:1=删除,2=正常
335
- - RuoYi:0=正常,1=删除
336
-
337
- ### DelFlagEnum 示例
266
+ ### DelFlagEnum
338
267
 
339
268
  ```java
340
269
  public enum DelFlagEnum {
@@ -346,244 +275,100 @@ public enum DelFlagEnum {
346
275
  }
347
276
  ```
348
277
 
278
+ ### 对应建表 SQL
279
+
280
+ ```sql
281
+ CREATE TABLE xxx_table (
282
+ id BIGINT NOT NULL COMMENT '主键(雪花ID)',
283
+ name VARCHAR(100) COMMENT '名称',
284
+ status INT COMMENT '状态',
285
+ crby VARCHAR(64) COMMENT '创建人',
286
+ crtime DATETIME COMMENT '创建时间',
287
+ upby VARCHAR(64) COMMENT '更新人',
288
+ uptime DATETIME COMMENT '更新时间',
289
+ del_flag INT DEFAULT 2 COMMENT '删除标识(1-删除,2-正常)',
290
+ PRIMARY KEY (id)
291
+ );
292
+ -- 无需 tenant_id(双库物理隔离)
293
+ ```
294
+
349
295
  ---
350
296
 
351
297
  ## 请求响应封装
352
298
 
353
- ### LeRequest 请求封装
354
-
355
299
  ```java
356
- @Data
357
- public class LeRequest<T> {
358
- @NotNull(message = "请求内容不能为空")
359
- private T content; // 实际请求数据
300
+ // 请求体:LeRequest<T> 包装
301
+ @PostMapping("/add")
302
+ public void add(@Validated @RequestBody LeRequest<XxxDTO> request) {
303
+ XxxDTO dto = request.getContent();
360
304
  }
361
305
 
362
- // 使用方式
363
- @PostMapping("/add")
364
- public void add(@RequestBody LeRequest<XxxDTO> request) {
365
- XxxDTO dto = request.getContent(); // 获取实际数据
306
+ // 分页请求
307
+ @PostMapping("/query")
308
+ public Page<XxxVO> query(@Validated @RequestBody LeRequest<PageDTO> request) {
309
+ return xxxService.query(request.getContent());
366
310
  }
367
311
  ```
368
312
 
369
- ### PageDTO 分页参数
313
+ ### PageDTO
370
314
 
371
315
  ```java
372
316
  @Data
373
317
  public class PageDTO {
374
- @NotNull
375
- @Min(1)
376
- private Integer pageNum; // 当前页
318
+ @NotNull @Min(1)
319
+ private Integer pageNum;
320
+ @NotNull @Min(1)
321
+ private Integer pageSize;
322
+ private String keyword;
377
323
 
378
- @NotNull
379
- @Min(1)
380
- private Integer pageSize; // 每页条数
381
-
382
- private String keyword; // 搜索关键词
383
-
384
- // 转换为 MyBatis-Plus Page
385
324
  public Page<Object> getMpPage() {
386
325
  return new Page<>(pageNum, pageSize);
387
326
  }
388
327
  }
389
328
  ```
390
329
 
391
- ### 分页响应
392
-
393
- ```java
394
- // 直接返回 MyBatis-Plus Page
395
- public Page<XxxVO> query(PageDTO dto) {
396
- return xxxMapper.page(dto.getMpPage(), dto.getKeyword());
397
- }
398
- ```
399
-
400
330
  ---
401
331
 
402
- ## 异常处理
403
-
404
- ### LeException 业务异常
332
+ ## 异常与国际化
405
333
 
406
334
  ```java
407
- import com.pig4cloud.pigx.common.core.exception.LeException;
408
-
409
- // 抛出业务异常
335
+ // 业务异常
410
336
  throw new LeException("业务错误信息");
411
337
 
412
- // 带国际化消息
413
- import net.xnzn.framework.config.i18n.I18n;
338
+ // 带国际化
414
339
  throw new LeException(I18n.getMessage("error.key"));
415
340
  ```
416
341
 
417
342
  ---
418
343
 
419
- ## 国际化
420
-
421
- ### 消息文件配置
422
-
423
- ```yaml
424
- # bootstrap.yml
425
- spring:
426
- messages:
427
- basename: "message_canteen_ext,message_common_ext,..."
428
- ```
429
-
430
- ### 使用方式
431
-
432
- ```java
433
- import net.xnzn.framework.config.i18n.I18n;
434
-
435
- // 获取国际化消息
436
- String message = I18n.getMessage("key");
437
- throw new LeException(I18n.getMessage("error.key"));
438
- ```
439
-
440
- ---
441
-
442
- ## 权限控制
443
-
444
- ### @RequiresAuthentication 注解
445
-
446
- ```java
447
- import net.xnzn.framework.secure.filter.annotation.RequiresAuthentication;
448
-
449
- @RestController
450
- @RequiresAuthentication // 需要认证
451
- @RequestMapping("/xxx")
452
- public class XxxController {
453
- }
454
- ```
455
-
456
- ---
457
-
458
- ## 双库路由最佳实践
459
-
460
- ### 场景1:商户业务(默认)
344
+ ## 项目模块结构
461
345
 
462
- ```java
463
- @PostMapping("/order/add")
464
- public void addOrder(@RequestBody LeRequest<OrderDTO> request) {
465
- // 前端请求头携带 MERCHANT-ID
466
- // 自动路由到商户库,无需额外处理
467
- orderService.add(request.getContent());
468
- }
469
346
  ```
470
-
471
- ### 场景2:系统配置操作
472
-
473
- ```java
474
- @PostMapping("/merchant/config")
475
- public void updateMerchantConfig(@RequestBody LeRequest<ConfigDTO> request) {
476
- // 强制在系统库执行
477
- Executors.doInSystem(() -> {
478
- configService.update(request.getContent());
479
- });
480
- }
347
+ leniu-tengyun-core/
348
+ ├── core-base/ # 公共基础模块
349
+ ├── sys-common/ # 公共业务(支付、通知、对接)
350
+ ├── sys-canteen/ # 食堂业务
351
+ ├── sys-kitchen/ # 后场厨房
352
+ ├── sys-drp/ # 供应链
353
+ ├── sys-logistics/ # 物流
354
+ └── sys-open/ # 开放接口
481
355
  ```
482
356
 
483
- ### 场景3:跨租户操作(定时任务)
357
+ ### 标准包结构
484
358
 
485
- ```java
486
- @Component
487
- public class DailyDataTask {
488
-
489
- public void execute() {
490
- // 遍历所有租户执行
491
- Executors.doInAllTenant(tenantId -> {
492
- dailyReportService.generateReport(tenantId);
493
- });
494
- }
495
- }
496
359
  ```
497
-
498
- ### 场景4:消息消费指定租户
499
-
500
- ```java
501
- @RabbitListener(queues = "order.queue")
502
- public void consumeOrder(Message message) {
503
- Long tenantId = getTenantFromMessage(message);
504
- // 在指定租户库执行
505
- Executors.doInTenant(tenantId, () -> {
506
- orderService.process(message);
507
- });
508
- }
509
- ```
510
-
511
- ---
512
-
513
- ## 常见设计规范
514
-
515
- ### 模块包结构
516
-
360
+ net.xnzn.core.[module]/
361
+ ├── controller/ # 按端分:web/mobile/android
362
+ ├── business/impl/ # 业务编排
363
+ ├── service/impl/ # 服务层
364
+ ├── mapper/ # Mapper + XML(同目录)
365
+ ├── model/ # Entity
366
+ ├── vo/ # 响应对象
367
+ ├── dto/ # 请求参数
368
+ ├── constants/ # 枚举和常量
369
+ ├── mq/ # 消息队列
370
+ └── task/ # 定时任务
517
371
  ```
518
- net.xnzn.core.xxx/
519
- ├── controller/ # 控制器
520
- ├── service/
521
- │ └── impl/ # 服务实现(不要求接口)
522
- ├── mapper/ # MyBatis Mapper
523
- ├── model/ # 实体类
524
- ├── dto/ # 数据传输对象
525
- ├── vo/ # 视图对象
526
- └── util/ # 工具类
527
- ```
528
-
529
- ### 命名规范
530
-
531
- | 类型 | 命名规则 | 示例 |
532
- |------|---------|------|
533
- | Controller | `XxxResourceController` | `OrderResourceController` |
534
- | Service | `XxxService` / `XxxServiceImpl` | `OrderService` |
535
- | Mapper | `XxxMapper` | `OrderMapper` |
536
- | Entity | `XxxEntity` | `OrderEntity` |
537
- | DTO | `XxxDTO` | `OrderDTO` |
538
- | VO | `XxxVO` | `OrderVO` |
539
-
540
- ### ID 生成
541
-
542
- ```java
543
- import net.xnzn.framework.id.Id;
544
-
545
- // 生成雪花ID
546
- long id = Id.next();
547
- ```
548
-
549
- ---
550
-
551
- ## 与 RuoYi-Vue-Plus 对比
552
-
553
- | 特征 | RuoYi-Vue-Plus | leniu-tengyun-core |
554
- |------|----------------|-------------------|
555
- | **包名** | `org.dromara.*` | `net.xnzn.*` |
556
- | **JDK** | 17 | 21 |
557
- | **租户模式** | 单库多租户(tenant_id 字段) | 双库架构(物理库隔离) |
558
- | **请求封装** | `Bo` | `LeRequest<T>` |
559
- | **响应封装** | `R<T>`, `TableDataInfo<T>` | `Page<T>`, `void` |
560
- | **异常类** | `ServiceException` | `LeException` |
561
- | **国际化** | `MessageUtils.message()` | `I18n.getMessage()` |
562
- | **权限注解** | `@SaCheckPermission` | `@RequiresAuthentication` |
563
- | **审计字段** | `create_by/create_time/update_by/update_time` | `crby/crtime/upby/uptime` |
564
- | **逻辑删除** | `del_flag` (0=正常, 1=删除) | `del_flag` (2=正常, 1=删除) |
565
-
566
- ---
567
-
568
- ## 快速检查清单
569
-
570
- ### 新模块设计检查
571
-
572
- - [ ] **包路径正确**:`net.xnzn.xxx.*`
573
- - [ ] **Entity 审计字段**:`crby/crtime/upby/uptime`
574
- - [ ] **逻辑删除**:`delFlag`(1=删除,2=正常)
575
- - [ ] **三层架构**:Controller → Service → Mapper
576
- - [ ] **异常处理**:使用 `LeException`
577
- - [ ] **权限控制**:`@RequiresAuthentication`
578
- - [ ] **国际化**:使用 `I18n.getMessage()`
579
- - [ ] **双库路由**:根据需要使用 `Executors.doInTenant/doInSystem`
580
-
581
- ### Entity 检查
582
-
583
- - [ ] 主键配置:`@TableId(value = "id", type = IdType.AUTO)`
584
- - [ ] 表名注解:`@TableName("table_name")`
585
- - [ ] 审计字段自动填充:`@TableField(fill = FieldFill.INSERT/INSERT_UPDATE)`
586
- - [ ] Lombok 注解:`@Data @Accessors(chain = true)`
587
372
 
588
373
  ---
589
374
 
@@ -591,8 +376,8 @@ long id = Id.next();
591
376
 
592
377
  | 类型 | 路径 |
593
378
  |------|------|
594
- | Controller 示例 | `sys-kitchen/.../backfield/attendance/scheduling/controller/BackAttendanceWorkShiftController.java` |
595
- | Service 示例 | `sys-kitchen/.../backfield/attendance/scheduling/service/impl/BackAttendanceWorkShiftServiceImpl.java` |
596
- | Mapper 示例 | `sys-kitchen/.../backfield/attendance/scheduling/mapper/BackAttendanceWorkShiftMapper.java` |
597
- | Entity 示例 | `sys-kitchen/.../backfield/attendance/scheduling/model/BackAttendanceWorkShift.java` |
598
- | 配置文件 | `core-base/src/main/resources/bootstrap.yml` |
379
+ | 订单 Controller | `sys-canteen/.../order/web/controller/OrderInfoWebController.java` |
380
+ | 订单 Business | `sys-canteen/.../order/web/business/impl/OrderWebBusiness.java` |
381
+ | 订单 Service | `sys-canteen/.../order/common/service/impl/OrderInfoService.java` |
382
+ | 排班 Controller | `sys-kitchen/.../attendance/scheduling/controller/BackAttendanceWorkShiftController.java` |
383
+ | Bootstrap 配置 | `core-base/src/main/resources/bootstrap.yml` |