create-dp-koa 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +50 -0
  2. package/index.mjs +97 -0
  3. package/package.json +33 -0
  4. package/template/.env.development +9 -0
  5. package/template/.env.production +12 -0
  6. package/template/.github/workflows/ci-cd.yml +182 -0
  7. package/template/.trae/documents/controller_development_plan.md +386 -0
  8. package/template/.trae/skills/00-backend-core.skill.md +50 -0
  9. package/template/.trae/skills/01-backend-skill-router.skill.md +55 -0
  10. package/template/.trae/skills/10-backend-api.skill.md +54 -0
  11. package/template/.trae/skills/11-backend-controller-recipes.skill.md +107 -0
  12. package/template/.trae/skills/20-backend-repository.skill.md +25 -0
  13. package/template/.trae/skills/21-backend-service.skill.md +135 -0
  14. package/template/.trae/skills/25-backend-comments-and-doc.skill.md +97 -0
  15. package/template/.trae/skills/30-backend-validation.skill.md +320 -0
  16. package/template/.trae/skills/40-backend-error-logging.skill.md +21 -0
  17. package/template/.trae/skills/50-backend-bootstrap-lifecycle.skill.md +90 -0
  18. package/template/.trae/skills/60-backend-router-registration.skill.md +71 -0
  19. package/template/.trae/skills/70-backend-middleware.skill.md +98 -0
  20. package/template/.trae/skills/80-backend-utils-and-libs.skill.md +90 -0
  21. package/template/.trae/skills/85-backend-plugins.rule.md +64 -0
  22. package/template/.trae/skills/90-backend-testing.skill.md +29 -0
  23. package/template/.trae/skills/README.md +49 -0
  24. package/template/.vscode/launch.json +38 -0
  25. package/template/.vscode/settings.json +1 -0
  26. package/template/Dockerfile +36 -0
  27. package/template/README.md +229 -0
  28. package/template/docker-compose.yml +135 -0
  29. package/template/docs/API_DOCUMENTATION.md +837 -0
  30. package/template/docs/ARCHITECTURE_REFACTOR.md +109 -0
  31. package/template/docs/CACHE_MIGRATION_GUIDE.md +142 -0
  32. package/template/docs/DEPLOYMENT_GUIDE.md +1062 -0
  33. package/template/docs/DEVELOPMENT_GUIDE.md +1097 -0
  34. package/template/docs/DOCUMENTATION_CLEANUP_REPORT.md +166 -0
  35. package/template/docs/DOCUMENTATION_COMPLETION_REPORT.md +223 -0
  36. package/template/docs/DOCUMENTATION_INDEX.md +294 -0
  37. package/template/docs/DOCUMENTATION_STRUCTURE.md +221 -0
  38. package/template/docs/ENTERPRISE_ANNOTATION_SYSTEM_GUIDE.md +2069 -0
  39. package/template/docs/ENTERPRISE_DATABASE_ARCHITECTURE.md +318 -0
  40. package/template/docs/ENTERPRISE_DEPLOYMENT_GUIDE.md +547 -0
  41. package/template/docs/ENTERPRISE_ERROR_HANDLING_GUIDE.md +357 -0
  42. package/template/docs/ENTERPRISE_LOGGING_SYSTEM_GUIDE.md +494 -0
  43. package/template/docs/ENVIRONMENT_CONFIG_EXAMPLE.md +69 -0
  44. package/template/docs/FINAL_IMPLEMENTATION_SUMMARY.md +206 -0
  45. package/template/docs/HEALTH_CHECK_ROUTE_FIX.md +134 -0
  46. package/template/docs/IMPLEMENTATION_CHECKLIST.md +204 -0
  47. package/template/docs/INSTALLATION_GUIDE.md +611 -0
  48. package/template/docs/INTERCEPTOR_TESTING_REPORT.md +226 -0
  49. package/template/docs/INTERCEPTOR_TESTING_SCRIPTS.md +143 -0
  50. package/template/docs/LOGGING_OPTIMIZATION_GUIDE.md +126 -0
  51. package/template/docs/MEMORY_DATABASE_GUIDE.md +212 -0
  52. package/template/docs/NEW_ROUTER_INTEGRATION_GUIDE.md +345 -0
  53. package/template/docs/NEW_ROUTER_INTEGRATION_SUMMARY.md +259 -0
  54. package/template/docs/NEW_ROUTER_USAGE_GUIDE.md +364 -0
  55. package/template/docs/QUICK_START.md +268 -0
  56. package/template/docs/ROUTE_SLASH_COMPATIBILITY_FIX.md +191 -0
  57. package/template/docs/SERVICE_INTERCEPTOR_GUIDE.md +243 -0
  58. package/template/docs/SERVICE_LAYER_INDEX.md +205 -0
  59. package/template/docs/SERVICE_PATTERN_GUIDE.md +270 -0
  60. package/template/docs/SERVICE_RETURN_VALUE_SPECIFICATION.md +466 -0
  61. package/template/docs/SWAGGER_DEBUG_MODE_GUIDE.md +80 -0
  62. package/template/docs/SWAGGER_INTEGRATION_GUIDE.md +416 -0
  63. package/template/docs/TRANSACTION_MANAGER_USAGE.md +360 -0
  64. package/template/docs/TROUBLESHOOTING.md +869 -0
  65. package/template/env.production.example +62 -0
  66. package/template/jest.config.js +34 -0
  67. package/template/package-lock.json +13240 -0
  68. package/template/package.json +119 -0
  69. package/template/patches/typeorm+0.3.25.patch +22 -0
  70. package/template/scripts/sync-template.mjs +84 -0
  71. package/template/scripts/test-annotation-system.sh +48 -0
  72. package/template/scripts/test-core-functionality.sh +28 -0
  73. package/template/src/annotations/decorators/ConfigManagement.ts +9 -0
  74. package/template/src/annotations/decorators/DistributedTracing.ts +9 -0
  75. package/template/src/annotations/decorators/EnterprisePerformance.ts +9 -0
  76. package/template/src/annotations/decorators/PerformanceMonitor.ts +32 -0
  77. package/template/src/annotations/decorators/SecurityAudit.ts +9 -0
  78. package/template/src/annotations/index.ts +50 -0
  79. package/template/src/annotations/processors/ConfigManagementProcessor.ts +369 -0
  80. package/template/src/annotations/processors/DistributedTracingProcessor.ts +288 -0
  81. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +189 -0
  82. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +101 -0
  83. package/template/src/annotations/processors/SecurityAuditProcessor.ts +345 -0
  84. package/template/src/annotations/processors/SwaggerProcessor.ts +612 -0
  85. package/template/src/annotations/processors/index.ts +10 -0
  86. package/template/src/app.ts +123 -0
  87. package/template/src/controllers/base.controller.ts +41 -0
  88. package/template/src/controllers/cacheManagement.controller.ts +131 -0
  89. package/template/src/controllers/captcha.controller.ts +57 -0
  90. package/template/src/controllers/demo/AnnotationDemoController.ts +118 -0
  91. package/template/src/controllers/example/EnterpriseExampleController.ts +297 -0
  92. package/template/src/controllers/example/ExampleController.ts +110 -0
  93. package/template/src/controllers/example/NewAnnotationExampleController.ts +159 -0
  94. package/template/src/controllers/example/SwaggerExampleController.ts +205 -0
  95. package/template/src/controllers/example/TransactionExample.controller.ts +336 -0
  96. package/template/src/controllers/health.controller.ts +235 -0
  97. package/template/src/controllers/home/register.controller.ts +58 -0
  98. package/template/src/controllers/home/ytGoods.controller.ts +92 -0
  99. package/template/src/controllers/home/ytShop.controller.ts +135 -0
  100. package/template/src/controllers/home/ytUser.controller.ts +89 -0
  101. package/template/src/controllers/logManagement.controller.ts +396 -0
  102. package/template/src/controllers/public/emailSend.controller.ts +65 -0
  103. package/template/src/controllers/public/ytUserAuth.controller.ts +174 -0
  104. package/template/src/controllers/testData.controller.ts +253 -0
  105. package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +73 -0
  106. package/template/src/dto/controller/home/emailSend.controller.dto.ts +40 -0
  107. package/template/src/dto/controller/home/register.controller.dto.ts +45 -0
  108. package/template/src/dto/controller/home/ytGoods.controller.dto.ts +55 -0
  109. package/template/src/dto/controller/home/ytShop.controller.dto.ts +69 -0
  110. package/template/src/dto/controller/home/ytUser.controller.dto.ts +44 -0
  111. package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +63 -0
  112. package/template/src/dto/goods.dto.ts +212 -0
  113. package/template/src/dto/service/ytService.dto.ts +13 -0
  114. package/template/src/dto/user.dto.ts +177 -0
  115. package/template/src/entity/base.entity.ts +13 -0
  116. package/template/src/entity/columnTypes.ts +13 -0
  117. package/template/src/entity/goodsImagesUnlockKey.entity.ts +33 -0
  118. package/template/src/entity/goodsUnlocker.entity.ts +34 -0
  119. package/template/src/entity/index.ts +15 -0
  120. package/template/src/entity/shop.entity.ts +52 -0
  121. package/template/src/entity/shopUser.entity.ts +41 -0
  122. package/template/src/entity/ytGoods.entity.ts +94 -0
  123. package/template/src/entity/ytUser.entity.ts +96 -0
  124. package/template/src/examples/InterceptorExampleRunner.ts +284 -0
  125. package/template/src/examples/ServiceInterceptorExample.ts +214 -0
  126. package/template/src/examples/SwaggerProcessorExample.ts +169 -0
  127. package/template/src/examples/TransactionManagerDemo.ts +377 -0
  128. package/template/src/examples/cacheExamples.ts +155 -0
  129. package/template/src/framework/decorator/controller.ts +311 -0
  130. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +100 -0
  131. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +156 -0
  132. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +45 -0
  133. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +117 -0
  134. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +95 -0
  135. package/template/src/framework/decorator/processor/ProcessorManager.ts +76 -0
  136. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +126 -0
  137. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +207 -0
  138. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +99 -0
  139. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +125 -0
  140. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +128 -0
  141. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +139 -0
  142. package/template/src/framework/decorator/refactored/index.ts +98 -0
  143. package/template/src/framework/decorator/swagger.ts +150 -0
  144. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +375 -0
  145. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +348 -0
  146. package/template/src/framework/interceptors/index.ts +19 -0
  147. package/template/src/framework/plugins/registry.ts +63 -0
  148. package/template/src/framework/plugins/types.ts +15 -0
  149. package/template/src/framework/types/ServiceResult.ts +151 -0
  150. package/template/src/framework/types/index.ts +16 -0
  151. package/template/src/framework/utils/CacheManager.ts +430 -0
  152. package/template/src/framework/utils/CacheService.ts +248 -0
  153. package/template/src/framework/utils/DtoValidator.ts +164 -0
  154. package/template/src/framework/utils/MigrationHelper.ts +179 -0
  155. package/template/src/framework/utils/MigrationManager.ts +256 -0
  156. package/template/src/framework/utils/NewRouter.ts +207 -0
  157. package/template/src/framework/utils/TransactionManager.ts +172 -0
  158. package/template/src/framework/utils/bootstrap.ts +445 -0
  159. package/template/src/framework/utils/cache.ts +269 -0
  160. package/template/src/framework/utils/databaseConfig.ts +148 -0
  161. package/template/src/framework/utils/db.ts +39 -0
  162. package/template/src/framework/utils/dbMonitor.ts +106 -0
  163. package/template/src/framework/utils/dynamicSwagger.ts +410 -0
  164. package/template/src/framework/utils/function.ts +61 -0
  165. package/template/src/framework/utils/gracefulShutdown.ts +131 -0
  166. package/template/src/framework/utils/logger.ts +388 -0
  167. package/template/src/framework/utils/metrics.ts +182 -0
  168. package/template/src/framework/utils/router.ts +417 -0
  169. package/template/src/framework/utils/swagger.ts +184 -0
  170. package/template/src/framework/utils/testDb.ts +19 -0
  171. package/template/src/framework/utils/token.ts +23 -0
  172. package/template/src/framework/utils/transform.ts +17 -0
  173. package/template/src/libs/aokEmailSender.ts +42 -0
  174. package/template/src/libs/captcha.ts +37 -0
  175. package/template/src/libs/cos.ts +45 -0
  176. package/template/src/libs/mCache.ts +7 -0
  177. package/template/src/libs/serviceValidate.ts +3 -0
  178. package/template/src/libs/tecentSms.ts +51 -0
  179. package/template/src/middlewares/a.middleware.ts +6 -0
  180. package/template/src/middlewares/error.middleware.ts +14 -0
  181. package/template/src/middlewares/logging.middleware.ts +187 -0
  182. package/template/src/middlewares/static.middleware.ts +79 -0
  183. package/template/src/middlewares/swagger.middleware.ts +70 -0
  184. package/template/src/middlewares/token.middleware.ts +32 -0
  185. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +172 -0
  186. package/template/src/migrations/index.ts +6 -0
  187. package/template/src/plugins/weboffice/core/context.ts +47 -0
  188. package/template/src/plugins/weboffice/core/errors.ts +51 -0
  189. package/template/src/plugins/weboffice/core/types.ts +63 -0
  190. package/template/src/plugins/weboffice/core/utils.ts +7 -0
  191. package/template/src/plugins/weboffice/entities/index.ts +3 -0
  192. package/template/src/plugins/weboffice/entities/webofficeFile.entity.ts +28 -0
  193. package/template/src/plugins/weboffice/entities/webofficeFileVersion.entity.ts +29 -0
  194. package/template/src/plugins/weboffice/http/routes.ts +179 -0
  195. package/template/src/plugins/weboffice/index.ts +23 -0
  196. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +274 -0
  197. package/template/src/repository/UserRepository.ts +122 -0
  198. package/template/src/repository/base/BaseRepository.ts +124 -0
  199. package/template/src/repository/interfaces/IBaseRepository.ts +67 -0
  200. package/template/src/routers/index.ts +49 -0
  201. package/template/src/service/base.service.ts +116 -0
  202. package/template/src/service/paramValidateTest.service.ts +139 -0
  203. package/template/src/service/ytGoods.service.ts +42 -0
  204. package/template/src/service/ytShop.service.ts +90 -0
  205. package/template/src/service/ytUser.service.ts +451 -0
  206. package/template/src/test/swaggerParameterTest.ts +90 -0
  207. package/template/src/utils/testDataInitializer.ts +296 -0
  208. package/template/static/output.json +15203 -0
  209. package/template/test/controllers/controllers.test.ts +173 -0
  210. package/template/test/controllers/example/ExampleController.test.ts +222 -0
  211. package/template/test/controllers/example/NewAnnotationExampleController.test.ts +200 -0
  212. package/template/test/framework/TransactionManagerDemo.test.ts +363 -0
  213. package/template/test/framework/annotation/AnnotationDecorators.test.ts +222 -0
  214. package/template/test/framework/annotation/AnnotationExecutor.test.ts +246 -0
  215. package/template/test/framework/annotation/AnnotationProcessor.test.ts +179 -0
  216. package/template/test/framework/annotation/CustomProcessors.test.ts +313 -0
  217. package/template/test/framework/annotation/DefaultProcessors.test.ts +371 -0
  218. package/template/test/framework/annotation/NewRouter.test.ts +272 -0
  219. package/template/test/framework/annotation/ProcessorManager.test.ts +248 -0
  220. package/template/test/framework/annotation/setup.ts +26 -0
  221. package/template/test/framework/cache.test.ts +101 -0
  222. package/template/test/framework/databaseConfig.test.ts +142 -0
  223. package/template/test/integration/integration.test.ts +153 -0
  224. package/template/test/plugins/weboffice/http.routes.int.test.ts +61 -0
  225. package/template/test/service/business.test.ts +87 -0
  226. package/template/test/service/paramValidateTest.service.test.ts +184 -0
  227. package/template/test/service/ytUser.service.test.ts +566 -0
  228. package/template/test/setup.ts +20 -0
  229. package/template/test/setupAfterEnv.ts +14 -0
  230. package/template/test/utils/testHelpers.ts +220 -0
  231. package/template/test_output.txt +0 -0
  232. package/template/tsconfig.build.json +17 -0
  233. package/template/tsconfig.json +31 -0
  234. package/template/webpack.config.js +71 -0
  235. package/template/yarn.lock +7354 -0
@@ -0,0 +1,135 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Trae 技能:Service 层开发规范
5
+
6
+ ## 适用与触发(重要)
7
+ - 当需要新增/修改 Service 类(`src/service/**.service.ts` 或等价命名)时启用本 Skill。
8
+ - 典型场景:
9
+ - 新增业务用例(用户、店铺、商品等)的 Service 方法
10
+ - 重构/增强现有 Service(增加校验、事务、日志等)
11
+
12
+ ---
13
+
14
+ ## 一、Service 职责定位(必须)
15
+ - Service 负责:
16
+ - 业务规则/用例编排(多 Repository、多实体、多步骤)
17
+ - 参数校验(通过 `@ParamValidate` 装饰器,由 dp-ioc2 自动处理)
18
+ - 事务边界控制(通过 `transactionManager.executeInTransaction`)
19
+ - 组合/组装领域数据,返回适合 Controller 消费的结果结构
20
+ - Service 不负责:
21
+ - HTTP/路由层细节(status code、header、ctx 等)
22
+ - 直接与 Koa `Context` 交互
23
+ - 直接返回 Controller 统一响应结构(`ControllerResponse`)
24
+
25
+ ---
26
+
27
+ ## 二、类定义与依赖(必须)
28
+ - Service 类必须:
29
+ - 使用 `@Injectable()` 装饰器
30
+ - 继承 `BaseService`
31
+ - Repository 访问:
32
+ - 优先使用 `BaseService` 提供的:
33
+ - `getDataRepository(EntityClass)`(简单 CRUD)
34
+ - `createLazyRepository(EntityClass, RepositoryClass, cache)`(自定义 Repository,参考 `YtUserService`)
35
+ - 禁止在 Service 中直接获取 DataSource:
36
+ - ❌ `getDataSource()` 直接操作
37
+ - ✅ 通过 Repository 完成数据访问(见 `20-backend-repository.skill.md`)
38
+
39
+ ---
40
+
41
+ ## 三、返回值规范(必须)
42
+ - 对外公开的 Service 方法,应优先返回:
43
+ - `Promise<CommonServiceResult<T>>`
44
+ - 使用统一工厂方法:
45
+ - 成功:`CommonServiceResult.success(data, message?)`
46
+ - 各种错误:`validationError / notFound / conflict / unauthorized / forbidden / error` 等
47
+ - 仅在兼容旧接口或内部辅助方法时,可返回原始实体/值(需有明确注释说明原因)
48
+
49
+ ---
50
+
51
+ ## 四、参数校验规范(必须)
52
+
53
+ ### 4.1 使用 `@ParamValidate` 装饰器
54
+ - **必须**在方法参数上使用 `@ParamValidate` 装饰器进行自动校验
55
+ - 导入:`import { ParamValidate } from "dp-ioc2"`
56
+ - 对象参数(DTO)校验:
57
+ ```typescript
58
+ async createUser(@ParamValidate(CreateUserDto) dto: CreateUserDto): Promise<CommonServiceResult<T>> {
59
+ // dp-ioc2 会自动使用 class-validator 校验 DTO
60
+ // 校验失败会抛出 IOCValidationError
61
+ }
62
+ ```
63
+ - 非对象参数(基本类型)校验:
64
+ ```typescript
65
+ import Joi from "joi";
66
+ async getUserById(@ParamValidate(undefined, Joi.string().min(3).required()) id: string): Promise<CommonServiceResult<T>> {
67
+ // dp-ioc2 会自动使用 joi 校验基本类型参数
68
+ }
69
+ ```
70
+ - 混合使用:
71
+ ```typescript
72
+ async updateUser(
73
+ @ParamValidate(undefined, Joi.number().positive().required()) userId: number,
74
+ @ParamValidate(UpdateUserDto) dto: UpdateUserDto
75
+ ): Promise<CommonServiceResult<T>> {
76
+ // 可以同时校验基本类型和对象参数
77
+ }
78
+ ```
79
+
80
+ ### 4.2 错误处理
81
+ - `@ParamValidate` 校验失败会抛出 `IOCValidationError` 异常
82
+ - **必须**在方法内部捕获并转换为 `CommonServiceResult`:
83
+ ```typescript
84
+ import { IOCValidationError } from "dp-ioc2";
85
+
86
+ async createUser(@ParamValidate(CreateUserDto) dto: CreateUserDto): Promise<CommonServiceResult<T>> {
87
+ try {
88
+ // 业务逻辑...
89
+ } catch (error) {
90
+ if (error instanceof IOCValidationError) {
91
+ // 将 IOCValidationError 转换为统一的错误响应
92
+ return CommonServiceResult.validationError(
93
+ error.message || "参数校验失败",
94
+ error.errors // 可选:传递详细错误信息
95
+ );
96
+ }
97
+ // 其他错误处理...
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### 4.3 DTO 定义要求
103
+ - DTO 类必须使用 `class-validator` 装饰器(`@IsString`、`@IsEmail`、`@MinLength` 等)
104
+ - DTO 定义与目录规范遵循:`30-backend-validation.skill.md`
105
+ - 禁止在 Service 方法内部手动调用 `DtoValidator`(已由 `@ParamValidate` 自动处理)
106
+
107
+ ### 4.4 注意事项
108
+ - `@ParamValidate` 在方法调用前自动执行,无需手动调用校验方法
109
+ - 对象参数会自动转换为 DTO 类实例(支持传入普通对象)
110
+ - 参数校验在 `@Before` hook 之前执行
111
+ - 如果方法有多个参数需要校验,每个参数都需要单独添加 `@ParamValidate` 装饰器
112
+
113
+ ---
114
+
115
+ ## 五、事务与错误处理(必须)
116
+
117
+ ### 5.1 事务使用
118
+ - 涉及多表、多步写操作时,必须使用:
119
+ - `transactionManager.executeInTransaction(async (manager) => { ... })`
120
+ - 不允许自行手动开启/提交/回滚事务(由 `TransactionManager` 统一处理)
121
+ - 事务内如果需要 Repository,优先通过自定义 Repository/manager 适配(见现有示例)
122
+
123
+ ### 5.2 错误处理与日志
124
+ - Service 方法内部应使用 `try/catch`:
125
+ - `catch` 中使用 `logger.error(...)` 记录上下文信息
126
+ - 返回 `CommonServiceResult.error(...)` 或更具体的错误码
127
+ - 生产环境避免将详细错误信息/堆栈返回给调用方(参考 `YtUserService` 的错误处理模式)
128
+ - 详细错误处理规范参见:`40-backend-error-logging.skill.md`
129
+
130
+ ---
131
+
132
+ ## 六、调用关系约束(必须)
133
+ - Controller 只能调用 Service 的公开方法,不应调用 Repository
134
+ - Service 不应调用 Controller,也不应依赖 Koa `Context`
135
+ - Service 之间如需调用,应通过依赖注入(`@Inject(OtherService)`),避免静态调用/循环依赖
@@ -0,0 +1,97 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Trae 技能:后端注释与文档规范(Comments & Docs)
5
+
6
+ ## 适用与触发
7
+ - 当你**新增或重构业务代码**时,尤其是以下文件:
8
+ - `src/controllers/**/*.ts`
9
+ - `src/service/**/*.ts`
10
+ - `src/entity/**/*.ts`
11
+ - `src/dto/**/*.ts`
12
+ - 本 Skill 只约束**代码注释/文档风格**,不改变分层职责(仍遵循 `00/10/11/20/21` 等规则)。
13
+
14
+ ---
15
+
16
+ ## 一、总体原则(必须)
17
+ - **中文为主,面向“后来的业务开发同学”解释意图**,而不是翻译代码本身。
18
+ - 注释重点回答三件事:
19
+ 1. **这段代码在业务上要解决什么问题?**
20
+ 2. **为什么要这么做 / 有什么约束和边界?**
21
+ 3. **有哪些容易踩坑的地方?(例如依赖环境变量、数据库特性、幂等性、并发等)**
22
+ - 禁止:
23
+ - ❌ 逐行翻译式注释(如 `// 定义一个变量 a`、`// 调用 userService`)。
24
+ - ❌ 与代码含义完全重复、没有信息增量的注释。
25
+
26
+ ---
27
+
28
+ ## 二、不同层级的注释要求
29
+
30
+ ### 2.1 Controller(必须)
31
+ - 每个 `Controller` 类必须有**类级别注释**:
32
+ - 说明该 Controller 覆盖的业务域(例如“项目管理相关接口”)。
33
+ - 对外暴露的大类接口(如“项目列表/创建/更新”等)。
34
+ - 每个对外路由方法(带 `@Get/@Post/...` 的方法)必须有**方法注释**:
35
+ - 粗略说明:**请求来源场景**(前端页面/模块)+ **业务动作**。
36
+ - 标出关键入参(DTO 字段)和关键返回值(例如分页结构、是否依赖登录态)。
37
+ - 如有**权限要求 / 限制条件 / 重要副作用**,必须写清楚。
38
+
39
+ ### 2.2 Service(必须)
40
+ - Service 是业务逻辑核心,注释要尽量详细:
41
+ - 类注释:说明该 Service 管理的领域/聚合根(例如“项目聚合的用例层服务,负责项目生命周期管理”)。
42
+ - 方法注释:
43
+ - 业务用例名称(如“创建项目并绑定负责人”、“按标签过滤项目动态”等)。
44
+ - 输入输出约定:关键参数的语义(例如 `currentUserId` 是否可空、`tags` 的筛选逻辑是“任一命中”还是“全部命中”)。
45
+ - 事务性/幂等性/一致性说明(如果涉及多表、多步写操作)。
46
+ - 对外可见的**错误分支**(对应哪些 `CommonServiceResultCode`)。
47
+
48
+ ### 2.3 Entity(推荐)
49
+ - 实体类上推荐有简短注释:
50
+ - 该表在业务中的角色(例如“项目主表,承载看板列表数据”)。
51
+ - 与前端/其他系统的强耦合字段(如 status 枚举、对外展示字段)。
52
+ - 对于**容易产生歧义的字段**必须补充注释,例如:
53
+ - 标记是否是**展示用字段**(如 `iconColor`),而不是业务逻辑字段。
54
+ - 说明枚举取值与 PRD 或其他文档的对应关系。
55
+
56
+ ### 2.4 DTO(推荐)
57
+ - 对暴露给前端/第三方的 DTO,建议:
58
+ - DTO 类注释:说明在哪些接口中被使用。
59
+ - 对约束较强的字段(必填/长度/格式)补充解释用途(例如“前端用于搜索项目标题和描述的关键字”)。
60
+
61
+ ---
62
+
63
+ ## 三、注释风格与格式
64
+
65
+ ### 3.1 统一使用 TypeScript 风格块注释
66
+ - 类和方法使用 `/** ... */` 块注释,方便 IDE 悬浮提示:
67
+ ```ts
68
+ /**
69
+ * 【业务含义】创建项目并自动绑定负责人
70
+ * - 从当前登录用户中推导 ownerUser
71
+ * - 如果请求体未显式传 owner,则默认使用用户昵称或邮箱
72
+ * - 只负责写入项目主表,不负责创建任何子资源
73
+ */
74
+ async createProject(...) { ... }
75
+ ```
76
+
77
+ ### 3.2 注释粒度
78
+ - **优先注释“函数/逻辑块”,其次才是字段**:
79
+ - 对复杂 if/循环/过滤条件,使用行上方的简短注释解释“业务规则”。
80
+ - 不建议每一行都写注释,保持“高信息密度”。
81
+
82
+ ---
83
+
84
+ ## 四、与测试 & 文档的关系
85
+
86
+ - 当 Service 方法被测试覆盖时,注释可以引用测试用例说明典型场景:
87
+ - 例如:“见 `project.service.test.ts` 中关于关键字搜索和分页的用例”。
88
+ - PRD 中有明确约束的字段/行为,注释应当**引用 PRD 段落或小节标题**,方便对照。
89
+
90
+ ---
91
+
92
+ ## 五、应用建议
93
+
94
+ - 新增业务时:
95
+ - 先写 Controller / Service 框架,再补完整注释,最后写测试。
96
+ - 重构旧代码时:
97
+ - 优先为“复杂/关键路径”补注释,如鉴权、事务、资金/安全相关逻辑。
@@ -0,0 +1,320 @@
1
+ # Trae 技能:后端数据验证规范
2
+
3
+ ## 适用与触发
4
+ - **仅在**你要生成/修改 **数据验证相关代码** 时应用本 Skill
5
+ - 触发口令:
6
+ - "按验证技能规范实现数据验证"
7
+ - "根据验证技能生成符合规范的 DTO"
8
+
9
+ ## 一、DTO 分层架构(必须)
10
+
11
+ ### 1.1 分层原则
12
+ - **Controller DTO**:处理 HTTP 层的数据结构(请求参数、响应数据)
13
+ - **Service DTO**:处理业务领域的数据结构(业务操作输入、查询条件)
14
+ - **必须进行转换**:Controller 接收的 DTO 需要转换为 Service DTO 后再调用 Service
15
+
16
+ ### 1.2 目录结构(必须遵守)
17
+
18
+ ```
19
+ src/dto/
20
+ ├── controller/ # Controller 层 DTO(HTTP 层)
21
+ │ ├── home/ # 需要认证的接口
22
+ │ │ ├── ytUser.controller.dto.ts
23
+ │ │ ├── ytGoods.controller.dto.ts
24
+ │ │ └── ytShop.controller.dto.ts
25
+ │ ├── public/ # 公开接口
26
+ │ │ └── ytUserAuth.controller.dto.ts
27
+ │ └── example/ # 示例
28
+ │ └── NewAnnotationExampleController.dto.ts
29
+ └── service/ # Service 层 DTO(业务领域)
30
+ ├── user.service.dto.ts
31
+ ├── goods.service.dto.ts
32
+ └── shop.service.dto.ts
33
+ ```
34
+
35
+ ## 二、命名规范(必须)
36
+
37
+ ### 2.1 Controller DTO 命名
38
+
39
+ #### 请求 DTO(接收 HTTP 参数)
40
+ - **格式**:`{操作}{实体}ControllerDto` 或 `{操作}{实体}RequestDto`
41
+ - **示例**:
42
+ - `CreateUserControllerDto` - 创建用户请求
43
+ - `UpdateUserControllerDto` - 更新用户请求
44
+ - `LoginUserControllerDto` - 登录请求
45
+ - `GetUserInfoControllerDto` - 获取用户信息请求(Query 参数)
46
+ - `UnlockGoodsImageControllerDto` - 解锁商品图片请求
47
+
48
+ #### 响应 DTO(API 返回数据)
49
+ - **格式**:`{操作}{实体}ResponseDto`
50
+ - **示例**:
51
+ - `GetUserInfoResponseDto` - 获取用户信息响应
52
+ - `CreateUserResponseDto` - 创建用户响应
53
+ - `GetYtUserBasicInfoResponseDto` - 获取用户基本信息响应
54
+
55
+ #### 命名规则总结
56
+ - 请求 DTO:以 `ControllerDto` 或 `RequestDto` 结尾
57
+ - 响应 DTO:以 `ResponseDto` 结尾
58
+ - 文件命名:`{模块}.controller.dto.ts`
59
+
60
+ ### 2.2 Service DTO 命名
61
+
62
+ #### 业务操作 DTO
63
+ - **格式**:`{操作}{实体}ServiceDto` 或 `{操作}{实体}Dto`(简洁形式)
64
+ - **示例**:
65
+ - `CreateUserServiceDto` 或 `CreateUserDto` - 创建用户业务输入
66
+ - `UpdateUserServiceDto` 或 `UpdateUserDto` - 更新用户业务输入
67
+ - `LoginUserServiceDto` 或 `LoginUserDto` - 登录业务输入
68
+ - `ChangePasswordServiceDto` 或 `ChangePasswordDto` - 修改密码业务输入
69
+
70
+ #### 查询 DTO
71
+ - **格式**:`Query{实体}ServiceDto` 或 `Query{实体}Dto`
72
+ - **示例**:
73
+ - `QueryUserServiceDto` 或 `QueryUserDto` - 用户查询条件
74
+ - `QueryGoodsServiceDto` 或 `QueryGoodsDto` - 商品查询条件
75
+
76
+ #### 命名规则总结
77
+ - 业务操作 DTO:以 `ServiceDto` 或 `Dto` 结尾(推荐使用 `ServiceDto` 以明确区分)
78
+ - 查询 DTO:以 `Query{实体}ServiceDto` 或 `Query{实体}Dto` 命名
79
+ - 文件命名:`{模块}.service.dto.ts`
80
+
81
+ ## 三、使用规范(必须)
82
+
83
+ ### 3.1 Controller 层使用
84
+
85
+ #### 请求 DTO 使用
86
+ ```typescript
87
+ import { CreateUserControllerDto, CreateUserResponseDto } from '@src/dto/controller/home/ytUser.controller.dto';
88
+ import { CreateUserServiceDto } from '@src/dto/service/user.service.dto';
89
+
90
+ @Post()
91
+ async createUser(@Body(CreateUserControllerDto) body: CreateUserControllerDto): Promise<ControllerResponse<CreateUserResponseDto>> {
92
+ // 必须:将 Controller DTO 转换为 Service DTO
93
+ const serviceDto: CreateUserServiceDto = {
94
+ nickName: body.name, // 字段名可能不同
95
+ email: body.email,
96
+ password: body.password,
97
+ // ... 其他字段映射
98
+ };
99
+
100
+ // 调用 Service(使用 Service DTO)
101
+ const result = await this.userService.createUser(serviceDto);
102
+
103
+ // 将 Service 结果转换为 Response DTO
104
+ return this.success(mapToResponseDto(result.data));
105
+ }
106
+ ```
107
+
108
+ **重要**:
109
+ - `@Body(CreateUserControllerDto)` - 将 DTO 类传给装饰器,框架会自动校验
110
+ - `@Query(QueryDto)` - Query 参数同样将 DTO 类传给装饰器
111
+ - `@Params(ParamsDto)` - 路径参数同样将 DTO 类传给装饰器
112
+ - 框架会在方法执行前自动校验,校验失败会直接返回错误响应
113
+
114
+ #### 响应 DTO 使用
115
+ ```typescript
116
+ import { GetUserInfoResponseDto } from '@src/dto/controller/home/ytUser.controller.dto';
117
+ import { ResponseValidateIf } from '@src/framework/decorator/controller';
118
+
119
+ // 使用 @ResponseValidateIf 装饰器校验响应数据
120
+ @ResponseValidateIf(GetUserInfoResponseDto, (data) => data && data.data)
121
+ @Get()
122
+ async getUserInfo(@State() state: any): Promise<ControllerResponse<GetUserInfoResponseDto>> {
123
+ // 返回数据必须符合 ResponseDto 结构
124
+ return this.success({
125
+ id: user.id,
126
+ nickName: user.nickName,
127
+ // ... 其他字段
128
+ });
129
+ }
130
+ ```
131
+
132
+ **响应校验说明**:
133
+ - `@ResponseValidateIf(ResponseDto, condition)` - **推荐使用**,条件校验响应数据
134
+ - 第一个参数:Response DTO 类
135
+ - 第二个参数:条件函数,返回 `true` 时才进行校验
136
+ - **必须传 condition 函数**,不传 condition 默认不校验
137
+ - 示例:`@ResponseValidateIf(GetUserInfoResponseDto, (data) => data && data.data)`
138
+ - `@ResponseValidator(ResponseDto, objectKey?)` - 无条件校验响应数据(不推荐使用)
139
+ - 第一个参数:Response DTO 类
140
+ - 第二个参数:可选,指定要校验的数据对象的 key(如 `"data"`)
141
+ - **注意**:虽然存在,但无法控制校验时机,建议使用 `@ResponseValidateIf`
142
+ - **默认行为**:如果不使用任何响应校验装饰器,默认不进行响应校验
143
+ - 校验失败会在返回前抛出异常或返回错误响应
144
+
145
+ ### 3.2 Service 层使用
146
+
147
+ ```typescript
148
+ import { CreateUserServiceDto } from '@src/dto/service/user.service.dto';
149
+ import { ParamValidate } from 'dp-ioc2';
150
+
151
+ async createUser(@ParamValidate(CreateUserServiceDto) dto: CreateUserServiceDto): Promise<CommonServiceResult<YtUserEntity>> {
152
+ // 业务逻辑(校验已在方法调用前自动完成)
153
+ // ...
154
+ }
155
+ ```
156
+
157
+ ### 3.3 DTO 转换规范
158
+
159
+ #### 转换位置
160
+ - **必须在 Controller 方法内部进行转换**
161
+ - 禁止在 Service 层接收 Controller DTO
162
+ - 禁止在 Controller 层直接传递 Controller DTO 给 Service
163
+
164
+ #### 转换示例
165
+ ```typescript
166
+ // ✅ 正确:在 Controller 中转换
167
+ @Post()
168
+ async createUser(@Body(CreateUserControllerDto) body: CreateUserControllerDto) {
169
+ // 框架已自动校验 body,校验失败不会进入方法体
170
+ const serviceDto: CreateUserServiceDto = {
171
+ // 字段映射
172
+ };
173
+ return await this.userService.createUser(serviceDto);
174
+ }
175
+
176
+ // ❌ 错误:直接传递 Controller DTO
177
+ @Post()
178
+ async createUser(@Body(CreateUserControllerDto) body: CreateUserControllerDto) {
179
+ return await this.userService.createUser(body); // 禁止!必须转换为 Service DTO
180
+ }
181
+ ```
182
+
183
+ ## 四、DTO 定义规范(必须)
184
+
185
+ ### 4.1 必须使用 class-validator
186
+ - 所有 DTO 类必须使用 `class-validator` 装饰器
187
+ - 常用装饰器:`@IsString()`, `@IsEmail()`, `@IsNotEmpty()`, `@MinLength()`, `@IsOptional()` 等
188
+
189
+ ### 4.2 Controller DTO 特殊处理
190
+ - 可以使用 `@Transform` 进行数据转换(如字符串转数字、trim)
191
+ - 可以包含 HTTP 层特定的字段(如 `vcodeToken`、`requestId`)
192
+
193
+ ### 4.3 Service DTO 要求
194
+ - **禁止**包含 HTTP 层特性(如 `@Transform`、HTTP 特定字段)
195
+ - 专注于业务领域的数据结构
196
+ - 可被多个 Controller 复用
197
+
198
+ ### 4.4 示例对比
199
+
200
+ #### Controller DTO(包含 HTTP 层转换)
201
+ ```typescript
202
+ export class CreateUserControllerDto {
203
+ @Transform((val) => Trim(String(val)))
204
+ @IsString()
205
+ @IsEmail()
206
+ email: string;
207
+
208
+ @Transform((val) => Number(val))
209
+ @IsNumber()
210
+ age: number;
211
+ }
212
+ ```
213
+
214
+ #### Service DTO(纯业务结构)
215
+ ```typescript
216
+ export class CreateUserServiceDto {
217
+ @IsString()
218
+ @IsEmail()
219
+ email: string;
220
+
221
+ @IsNumber()
222
+ age: number;
223
+ }
224
+ ```
225
+
226
+ ## 五、校验流程
227
+
228
+ ### 5.1 Controller 层校验
229
+
230
+ #### 请求参数校验
231
+ - **必须**将 DTO 类传给装饰器,框架会自动校验:
232
+ ```typescript
233
+ // ✅ 正确:将 DTO 类传给装饰器
234
+ @Get()
235
+ async getUserInfo(@Query(GetUserInfoQueryDto) query: GetUserInfoQueryDto) { }
236
+
237
+ @Post()
238
+ async createUser(@Body(CreateUserControllerDto) body: CreateUserControllerDto) { }
239
+
240
+ @Get('/:id')
241
+ async getUserById(@Params(GetUserByIdParamsDto) params: GetUserByIdParamsDto) { }
242
+
243
+ // ❌ 错误:不传 DTO 类,框架无法自动校验
244
+ @Get()
245
+ async getUserInfo(@Query() query: GetUserInfoQueryDto) { }
246
+ ```
247
+ - 校验失败自动返回错误响应,不会进入方法体
248
+
249
+ #### 响应数据校验
250
+ - 使用 `@ResponseValidateIf` 或 `@ResponseValidator` 装饰器:
251
+ ```typescript
252
+ // 条件校验(推荐)
253
+ @ResponseValidateIf(GetUserInfoResponseDto, (data) => data && data.data)
254
+ @Get()
255
+ async getUserInfo(): Promise<ControllerResponse<GetUserInfoResponseDto>> {
256
+ return this.success({ /* ... */ });
257
+ }
258
+
259
+ // 无条件校验(始终校验)
260
+ @ResponseValidator(GetUserInfoResponseDto)
261
+ @Get()
262
+ async getUserInfo(): Promise<ControllerResponse<GetUserInfoResponseDto>> {
263
+ return this.success({ /* ... */ });
264
+ }
265
+ ```
266
+ - 校验失败会在返回前抛出异常或返回错误响应
267
+
268
+ ### 5.2 Service 层校验
269
+ - **必须**使用 `@ParamValidate` 装饰器进行参数校验(由 dp-ioc2 自动处理)
270
+ - 对象参数(DTO):使用 `@ParamValidate(DtoClass)`,自动使用 class-validator 校验
271
+ - 非对象参数:使用 `@ParamValidate(undefined, JoiSchema)`,使用 joi 校验
272
+ - 校验失败会抛出 `IOCValidationError`,需要在 Service 方法中捕获并转换为 `CommonServiceResult.validationError(...)`
273
+ - 详细规范参见:`21-backend-service.skill.md` 的"四、参数校验规范"
274
+
275
+ ## 六、迁移指南
276
+
277
+ ### 6.1 现有 DTO 迁移
278
+ - `src/dto/user.dto.ts` → `src/dto/service/user.service.dto.ts`
279
+ - `src/dto/goods.dto.ts` → `src/dto/service/goods.service.dto.ts`
280
+ - 重命名:`CreateUserDto` → `CreateUserServiceDto`(或保持 `CreateUserDto`,但文件放在 service 目录)
281
+
282
+ ### 6.2 迁移步骤
283
+ 1. 创建 Service DTO 文件(`src/dto/service/{module}.service.dto.ts`)
284
+ 2. 将业务 DTO 移动到 Service DTO 文件
285
+ 3. 在 Controller 中创建对应的 Controller DTO
286
+ 4. 在 Controller 方法中添加 DTO 转换逻辑
287
+ 5. 更新所有引用
288
+
289
+ ## 七、禁止事项
290
+
291
+ ### 7.1 禁止在 Service 层使用 Controller DTO
292
+ - ❌ `async createUser(dto: CreateUserControllerDto)` - 禁止
293
+ - ✅ `async createUser(dto: CreateUserServiceDto)` - 正确
294
+
295
+ ### 7.2 禁止直接传递 Controller DTO 给 Service
296
+ - ❌ `this.service.createUser(controllerDto)` - 禁止
297
+ - ✅ `this.service.createUser(convertToServiceDto(controllerDto))` - 正确
298
+
299
+ ### 7.3 禁止在 Service DTO 中使用 HTTP 层特性
300
+ - ❌ Service DTO 中使用 `@Transform` - 禁止
301
+ - ✅ Controller DTO 中使用 `@Transform` - 允许
302
+
303
+ ## 八、最佳实践
304
+
305
+ ### 8.1 字段映射
306
+ - 如果 Controller DTO 和 Service DTO 字段名相同,可以直接使用展开运算符
307
+ - 如果字段名不同,必须显式映射
308
+
309
+ ### 8.2 响应 DTO
310
+ - 响应 DTO 应该只包含前端需要的数据
311
+ - 避免直接返回 Entity,应该转换为 Response DTO
312
+
313
+ ### 8.3 复用性
314
+ - Service DTO 应该设计为可被多个 Controller 复用
315
+ - Controller DTO 可以针对特定接口优化
316
+
317
+ ## 九、相关规范
318
+
319
+ - **Service 层规范**:`21-backend-service.skill.md`
320
+ - **Controller 层规范**:`10-backend-api.skill.md`
@@ -0,0 +1,21 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Trae 技能:错误处理与日志规范
5
+
6
+ ## 一、错误处理
7
+
8
+ - 所有 async 方法必须 try/catch
9
+ - 业务错误:
10
+ - 使用 `CommonServiceResult.fail()`
11
+ - 系统错误:
12
+ - 记录日志
13
+ - 返回通用失败响应
14
+
15
+ ---
16
+
17
+ ## 二、日志规范
18
+
19
+ - 使用 `logger.info / warn / error`
20
+ - 日志必须包含上下文信息
21
+ - 敏感信息必须脱敏
@@ -0,0 +1,90 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Trae 技能:启动生命周期规范(setBeforeBootstrap / setAfterBootstrap)
5
+
6
+ ## 适用与触发(重要)
7
+ - 仅当需要修改/新增启动逻辑(`src/app.ts`)或框架启动流程(`src/framework/utils/bootstrap.ts`)时启用本 Skill。
8
+ - 触发口令建议:
9
+ - “请按 `50-backend-bootstrap-lifecycle.skill.md` 调整启动流程”
10
+
11
+ ---
12
+
13
+ ## 一、真实执行顺序(必须理解并遵守)
14
+ 以 `src/framework/utils/bootstrap.ts` 为准:
15
+
16
+ 1. `bootstrap()` 内部 **先执行** `beforeBootstraps(app)`(如果已注册)
17
+ 2. 然后框架挂载:CORS → 日志中间件 → 框架错误处理中间件 → `koaBody()`
18
+ 3. 然后挂载:`router.routes()/allowedMethods()` 并 `app.listen(...)`
19
+ 4. `listen` 成功后 **再执行** `afterBootstraps(app)`(如果已注册)
20
+
21
+ 结论:
22
+ - **before**:发生在“框架中间件/路由挂载/监听端口”之前
23
+ - **after**:发生在“监听端口成功”之后
24
+
25
+ ---
26
+
27
+ ## 二、setBeforeBootstrap(fn) 规范(必须)
28
+
29
+ ### 2.1 允许做的事情(推荐放这里)
30
+ - **注册必须最先执行的中间件**(例如静态资源 `staticMiddleware`)
31
+ - **完成路由注册/绑定**(例如调用 `Router()` 让 `bindRouter` 把 Controller 注册到 router)
32
+ - **初始化框架级系统**(例如注解系统初始化、配置系统初始化)
33
+ - **初始化数据库与依赖它的组件**
34
+ - 连接数据库(`initDb`)
35
+ - 设置 `transactionManager/migrationManager` 的 DataSource
36
+ - 生产环境迁移(如有)
37
+ - 内存库模式初始化测试数据(如有)
38
+
39
+ ### 2.2 必须遵守的约束
40
+ - 回调函数签名必须能接收 `app: Koa`(框架会 `beforeBootstraps(app)` 调用)
41
+ - **只注册一次**:项目当前实现中 `beforeBootstraps` 只有一个槽位,后注册会覆盖先注册
42
+ - 发生异常必须:
43
+ - 记录日志
44
+ - 抛出异常(让启动失败),避免“半初始化”状态继续运行
45
+
46
+ ### 2.3 禁止行为
47
+ - ❌ 在这里启动“永不结束的任务”阻塞启动(例如无限循环、长期 await 不返回)
48
+ - ❌ 在这里写业务逻辑(仅做启动编排/初始化)
49
+
50
+ ---
51
+
52
+ ## 三、setAfterBootstrap(fn) 规范(必须)
53
+
54
+ ### 3.1 允许做的事情(推荐放这里)
55
+ - **启动后台/周期性任务**(例如数据库连接监控 `dbMonitor.startMonitoring()`)
56
+ - **启动只依赖服务器已监听的组件**(例如需要对外暴露端口后再启动的探针/上报)
57
+ - **输出启动完成日志**、打印运行信息
58
+
59
+ ### 3.2 必须遵守的约束
60
+ - 回调函数签名必须能接收 `app: Koa`
61
+ - after 内部出错:
62
+ - 必须记录日志
63
+ - 不应静默失败(至少可观测);必要时应触发优雅退出策略(按项目约定)
64
+ - **只注册一次**:项目当前实现中 `afterBootstraps` 只有一个槽位,后注册会覆盖先注册
65
+
66
+ ### 3.3 禁止行为(强烈)
67
+ - ❌ 在 after 阶段新增路由/中间件/全局行为(会导致启动行为不可预测)
68
+ - 路由与中间件应在 before 阶段完成,保证一致性
69
+ - ❌ 在 after 阶段再做“数据库 schema 级别变更/迁移”等破坏性操作
70
+
71
+ ---
72
+
73
+ ## 四、`src/app.ts` 推荐写法(对齐范式)
74
+
75
+ ### 4.1 before 推荐结构
76
+ - 注册静态中间件(如需要最前置)
77
+ - 初始化注解系统
78
+ - 调用 `Router()` 完成 Controller→router 绑定
79
+ - 初始化数据库、迁移、测试数据、事务管理器 DataSource
80
+
81
+ ### 4.2 after 推荐结构
82
+ - 启动 dbMonitor 等后台任务
83
+ - 打印启动后日志
84
+
85
+ ---
86
+
87
+ ## 五、常见坑(必须避免)
88
+ - before/after **不是数组**,目前实现是单个槽位:多次调用会覆盖
89
+ - `Router()` 必须在 `app.use(router.routes())` 之前执行;因此应放在 before
90
+ - 若在 before 里注册中间件,其执行顺序会早于框架默认中间件(因为 before 先 `app.use`)