create-dp-koa 1.0.0 → 1.0.2

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 (82) hide show
  1. package/package.json +2 -2
  2. package/template/.cursor/commands/cheatsheet-backend-controller.md +45 -0
  3. package/template/.cursor/commands/implement-backend-api-controller.md +60 -0
  4. package/template/.cursor/commands/plan-backend.md +97 -0
  5. package/template/.cursor/rules/00-backend-core.skill.md +61 -0
  6. package/template/.cursor/rules/01-backend-skill-router.skill.md +57 -0
  7. package/template/.cursor/rules/10-backend-api.skill.md +55 -0
  8. package/template/.cursor/rules/11-backend-controller-recipes.skill.md +188 -0
  9. package/template/.cursor/rules/20-backend-repository.skill.md +25 -0
  10. package/template/.cursor/rules/21-backend-service.skill.md +137 -0
  11. package/template/.cursor/rules/25-backend-comments-and-doc.skill.md +98 -0
  12. package/template/.cursor/rules/30-backend-validation.skill.md +342 -0
  13. package/template/.cursor/rules/40-backend-error-logging.skill.md +21 -0
  14. package/template/.cursor/rules/50-backend-bootstrap-lifecycle.skill.md +105 -0
  15. package/template/.cursor/rules/60-backend-router-registration.skill.md +73 -0
  16. package/template/.cursor/rules/70-backend-middleware.skill.md +100 -0
  17. package/template/.cursor/rules/80-backend-utils-and-libs.skill.md +108 -0
  18. package/template/.cursor/rules/85-backend-plugins.rule.md +65 -0
  19. package/template/.cursor/rules/90-backend-testing.skill.md +29 -0
  20. package/template/.cursor/rules/README.md +49 -0
  21. package/template/.trae/skills/11-backend-controller-recipes.skill.md +91 -10
  22. package/template/scripts/sync-template.mjs +0 -1
  23. package/template/src/controllers/example/ExampleController.ts +14 -0
  24. package/template/src/entity/index.ts +1 -15
  25. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +5 -1
  26. package/template/src/routers/index.ts +0 -35
  27. package/template/src/utils/testDataInitializer.ts +2 -269
  28. package/template/test/controllers/example/ExampleController.test.ts +29 -31
  29. package/template/test/framework/annotation/AnnotationDecorators.test.ts +15 -15
  30. package/template/test/framework/annotation/AnnotationExecutor.test.ts +27 -32
  31. package/template/test/framework/annotation/AnnotationProcessor.test.ts +25 -24
  32. package/template/test/framework/annotation/CustomProcessors.test.ts +15 -25
  33. package/template/test/framework/annotation/NewRouter.test.ts +9 -7
  34. package/template/test/framework/annotation/ProcessorManager.test.ts +14 -27
  35. package/template/test/framework/databaseConfig.test.ts +2 -2
  36. package/template/test/integration/integration.test.ts +15 -72
  37. package/template/src/controllers/cacheManagement.controller.ts +0 -131
  38. package/template/src/controllers/captcha.controller.ts +0 -57
  39. package/template/src/controllers/example/NewAnnotationExampleController.ts +0 -159
  40. package/template/src/controllers/example/SwaggerExampleController.ts +0 -205
  41. package/template/src/controllers/example/TransactionExample.controller.ts +0 -336
  42. package/template/src/controllers/health.controller.ts +0 -235
  43. package/template/src/controllers/home/register.controller.ts +0 -58
  44. package/template/src/controllers/home/ytGoods.controller.ts +0 -92
  45. package/template/src/controllers/home/ytShop.controller.ts +0 -135
  46. package/template/src/controllers/home/ytUser.controller.ts +0 -89
  47. package/template/src/controllers/logManagement.controller.ts +0 -396
  48. package/template/src/controllers/public/emailSend.controller.ts +0 -65
  49. package/template/src/controllers/public/ytUserAuth.controller.ts +0 -174
  50. package/template/src/controllers/testData.controller.ts +0 -253
  51. package/template/src/dto/controller/example/NewAnnotationExampleController.dto.ts +0 -73
  52. package/template/src/dto/controller/home/emailSend.controller.dto.ts +0 -40
  53. package/template/src/dto/controller/home/register.controller.dto.ts +0 -45
  54. package/template/src/dto/controller/home/ytGoods.controller.dto.ts +0 -55
  55. package/template/src/dto/controller/home/ytShop.controller.dto.ts +0 -69
  56. package/template/src/dto/controller/home/ytUser.controller.dto.ts +0 -44
  57. package/template/src/dto/controller/public/ytUserAuth.controller.dto.ts +0 -63
  58. package/template/src/dto/goods.dto.ts +0 -212
  59. package/template/src/dto/service/ytService.dto.ts +0 -13
  60. package/template/src/dto/user.dto.ts +0 -177
  61. package/template/src/entity/columnTypes.ts +0 -13
  62. package/template/src/entity/goodsImagesUnlockKey.entity.ts +0 -33
  63. package/template/src/entity/goodsUnlocker.entity.ts +0 -34
  64. package/template/src/entity/shop.entity.ts +0 -52
  65. package/template/src/entity/shopUser.entity.ts +0 -41
  66. package/template/src/entity/ytGoods.entity.ts +0 -94
  67. package/template/src/entity/ytUser.entity.ts +0 -96
  68. package/template/src/examples/SwaggerProcessorExample.ts +0 -169
  69. package/template/src/examples/TransactionManagerDemo.ts +0 -377
  70. package/template/src/framework/utils/dynamicSwagger.ts +0 -410
  71. package/template/src/repository/UserRepository.ts +0 -122
  72. package/template/src/service/paramValidateTest.service.ts +0 -139
  73. package/template/src/service/ytGoods.service.ts +0 -42
  74. package/template/src/service/ytShop.service.ts +0 -90
  75. package/template/src/service/ytUser.service.ts +0 -451
  76. package/template/src/test/swaggerParameterTest.ts +0 -90
  77. package/template/test/controllers/controllers.test.ts +0 -173
  78. package/template/test/controllers/example/NewAnnotationExampleController.test.ts +0 -200
  79. package/template/test/framework/TransactionManagerDemo.test.ts +0 -363
  80. package/template/test/service/business.test.ts +0 -87
  81. package/template/test/service/paramValidateTest.service.test.ts +0 -184
  82. package/template/test/service/ytUser.service.test.ts +0 -566
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "create-dp-koa",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Scaffold a DP-Koa framework project from the official template",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-dp-koa": "./index.mjs"
7
+ "create-dp-koa": "index.mjs"
8
8
  },
9
9
  "files": [
10
10
  "index.mjs",
@@ -0,0 +1,45 @@
1
+ # Command:Backend Controller Cheatsheet
2
+
3
+ 你现在是【后端 Controller 速查助手】。
4
+
5
+ ## 适用场景(触发条件)
6
+ - 用户想要 Cursor 快速给出:**Controller 推荐写法** + **常用注解用法** + **最小可复制模板**。
7
+ - 本 Command **不直接修改代码**(只输出建议与模板)。
8
+
9
+ ---
10
+
11
+ ## 必须遵守的 Skills / Rules
12
+ - 始终遵守:`00-backend-core.skill.md`
13
+ - 本次必须启用并参考:
14
+ - `10-backend-api.skill.md`
15
+ - `11-backend-controller-recipes.skill.md`
16
+
17
+ ---
18
+
19
+ ## 输出要求(严格遵守)
20
+ 请严格按以下结构输出(只输出文本,不直接生成业务代码文件):
21
+
22
+ ```text
23
+ 【适用结论】
24
+ - 这次是否属于“写/改 Controller 路由接口”:是/否
25
+ - 推荐启用的 Skills:
26
+
27
+ 【Controller 推荐骨架(最小模板)】
28
+ - 给出一个可复制的 Controller 方法模板(含 @Get/@Post + @Query/@Body/@State + try/catch + success/fail)
29
+
30
+ 【常用注解速查】
31
+ - @Get/@Post:说明 + 何时用
32
+ - @Query/@Body:说明 + DTO 写法
33
+ - @State() vs @State('user'):差异 + 推荐写法
34
+ - @ResponseCode/@ResponseHeader:何时用
35
+ - @ResponseValidator/@ResponseValidateIf:何时用(可选)
36
+
37
+ 【DTO/Service 设计建议】
38
+ - 入参 DTO 应放在哪个目录、命名建议
39
+ - Service 方法签名建议(含返回类型)
40
+
41
+ 【对齐的参考来源(必须列出)】
42
+ - 至少列出 **`11-backend-controller-recipes.skill.md` 内嵌示例**中的 2 个小节编号(例如 1.1.2、1.1.4);若同时参考了仓库内 `src/controllers/base.controller.ts` 或 `src/controllers/example/*`,可一并写出路径
43
+ ```
44
+
45
+
@@ -0,0 +1,60 @@
1
+ # Command:Implement Backend API Controller
2
+
3
+ 你现在是【后端 API Controller 实现器】。
4
+
5
+ ## 适用场景(触发条件)
6
+ - 仅当用户要 **新增/修改 Controller 路由接口**(含 DTO、Swagger、响应映射)时使用本 Command。
7
+ - 本 Command 的目标是:**直接落地代码改动**(不是只做规划)。
8
+ - 如果用户只要规划,请改用:`plan-backend.md`
9
+
10
+ ---
11
+
12
+ ## 必须遵守的 Skills / Rules
13
+ - 始终遵守:`00-backend-core.skill.md`
14
+ - 本次必须额外启用并严格遵守:`10-backend-api.skill.md`
15
+ - 强烈建议同时启用(用于让写法更“像本项目”):`11-backend-controller-recipes.skill.md`
16
+ - 同时配套使用(按需要):
17
+ - `30-backend-validation.skill.md`(DTO + 校验)
18
+ - `40-backend-error-logging.skill.md`(try/catch + 日志)
19
+ - `20-backend-repository.skill.md`(如涉及事务/数据访问)
20
+ - `90-backend-testing.skill.md`(如需要补测试)
21
+
22
+ ---
23
+
24
+ ## 输入要求(信息不足必须先澄清)
25
+ 当用户未提供以下信息时,必须先提问澄清再写代码:
26
+ - **接口清单**:路径、方法(GET/POST)、接口用途
27
+ - **入参**:Query/Body/State 的字段、类型、是否必填
28
+ - **输出**:成功返回 data 结构、失败场景与错误码/错误信息
29
+ - **Service 目标**:要调用的 Service 方法名(或由你提出建议)
30
+ - **是否需要 Swagger**:对外接口默认需要(若用户明确不需要则不加)
31
+
32
+ ---
33
+
34
+ ## 实现约束(执行时必须检查)
35
+ - **路由/参数装饰器必须使用**:`@Get/@Post` + `@Query/@Body/@State`
36
+ - **DTO 必须强类型**:禁止 `any`;DTO 放到 `src/dto/controller/{module}/`
37
+ - **Controller 必须 try/catch**
38
+ - **Controller 必须映射统一响应**:使用 `BaseController.success/fail`,禁止 `return result`
39
+ - **禁止在 Controller 写业务逻辑/直接访问数据库**
40
+
41
+ ---
42
+
43
+ ## 输出/交付(你必须做到)
44
+ 1. **明确将要修改/新增的文件列表**(含路径)
45
+ 2. **实现 DTO**(必要时新建文件)
46
+ 3. **实现/修改 Controller**(装饰器 + DTO + try/catch + 响应映射)
47
+ 4. **如需**:补 Swagger 装饰器、补/改 Service 接口签名
48
+ 5. **如需**:补 Jest 测试(至少覆盖成功/失败/边界之一)
49
+
50
+ ---
51
+
52
+ ## 写代码前的对齐动作(必须)
53
+ - 在生成/修改 Controller 代码前,先对齐 **`11-backend-controller-recipes.skill.md` 内嵌示例**(章节 **1.1**),重点核对:
54
+ - **1.1.1** `BaseController` / `ControllerResponse` 与 `success` / `fail` 用法
55
+ - **1.1.2** `@State()` 读取整段 `ctx.state`
56
+ - **1.1.3** `@State('user')` 只读 `ctx.state.user`
57
+ - **1.1.4** `@ResponseValidateIf` 条件响应校验
58
+ - 若仓库中仍存在 `src/controllers/base.controller.ts` 或 `src/controllers/example/*`,可作为**补充**对照(以实现代码为准)。
59
+
60
+
@@ -0,0 +1,97 @@
1
+ # Command:Backend Skill Planner
2
+
3
+ 你现在是【后端技能规划器(Backend Skill Planner)】。
4
+
5
+ 你的职责是:
6
+ - 分析用户的后端开发需求
7
+ - 规划应该使用哪些 Backend Skills
8
+ - 给出清晰、可执行的技能调用顺序
9
+ - 不直接生成业务代码
10
+
11
+ ---
12
+
13
+ ## 一、你可以使用的 Skills(已定义)
14
+
15
+ - Backend Core Skill(始终生效)
16
+ - Backend API Skill
17
+ - Backend Service Skill
18
+ - Backend Repository Skill
19
+ - Backend Validation Skill
20
+ - Backend Error & Logging Skill
21
+ - Backend Testing Skill
22
+ - Backend Bootstrap Lifecycle Skill(启动生命周期:before/after/bootstrap)
23
+ - Backend Router Registration Skill(路由注册:routers/index.ts + bindRouter)
24
+
25
+ ---
26
+
27
+ ## 二、规划规则(必须遵守)
28
+
29
+ 1. **不要直接写代码**
30
+ 2. **不要跳过规划步骤**
31
+ 3. 每个 Skill 必须说明:
32
+ - 使用原因
33
+ - 预期输出
34
+ 4. 如果用户信息不足,必须先提出澄清问题
35
+ 5. 输出结构必须严格遵守下方格式
36
+ 6. 若需求涉及启动流程/中间件顺序/路由注册/数据库初始化/监控任务:
37
+ - 必须纳入 Backend Bootstrap Lifecycle Skill(`50-backend-bootstrap-lifecycle.skill.md`)
38
+ 7. 若需求涉及新增/修改路由绑定(`src/routers/index.ts`)、调整 `bindRouter` 或路由体系:
39
+ - 必须纳入 Backend Router Registration Skill(`60-backend-router-registration.skill.md`)
40
+
41
+ ---
42
+
43
+ ## 三、输出格式(严格遵守)
44
+
45
+ ```text
46
+ 【需求理解】
47
+ - 用户目标:
48
+ - 涉及模块:
49
+ - 是否新增 / 修改:
50
+
51
+ 【技能规划】
52
+ Step 1:Backend Validation Skill
53
+ - 原因:
54
+ - 输出:
55
+
56
+ Step 2:Backend API Skill
57
+ - 原因:
58
+ - 输出:
59
+
60
+ Step 3:Backend Service Skill
61
+ - 原因:
62
+ - 输出:
63
+
64
+ Step 4:Backend Repository Skill
65
+ - 原因:
66
+ - 输出:
67
+
68
+ Step 5:Backend Error & Logging Skill
69
+ - 原因:
70
+ - 输出:
71
+
72
+ Step 6:Backend Testing Skill(如需要)
73
+ - 原因:
74
+ - 输出:
75
+
76
+ Step X:Backend Bootstrap Lifecycle Skill(如涉及启动/bootstrapping)
77
+ - 原因:
78
+ - 输出:
79
+
80
+ Step Y:Backend Router Registration Skill(如涉及路由注册/routers/index.ts)
81
+ - 原因:
82
+ - 输出:
83
+
84
+ 【不确定点 / 需要澄清】
85
+ - 问题 1:
86
+ - 问题 2:
87
+
88
+ 【执行建议】
89
+ - 推荐使用的 Commands:
90
+ - 是否可以进入代码生成阶段:
91
+
92
+ ---
93
+
94
+ ## 四、可用 Commands(建议在【执行建议】中引用)
95
+ - `plan-backend.md`:只做技能规划,不直接写代码
96
+ - `implement-backend-api-controller.md`:新增/修改 Controller 路由接口(显式启用 Backend API Skill)
97
+ - `cheatsheet-backend-controller.md`:输出 Controller 推荐写法 + 常用注解速查(不直接改代码)
@@ -0,0 +1,61 @@
1
+ ---
2
+ alwaysApply: true
3
+ ---
4
+ # Skill:后端核心开发规范(Backend Core)
5
+
6
+ ## 适用范围
7
+ - 本项目所有 TypeScript 后端代码
8
+ - 技术栈:Koa + TypeORM + dp-ioc2 + 自定义装饰器体系
9
+ - **包管理工具:必须使用 yarn(禁止使用 npm)**
10
+
11
+ ---
12
+
13
+ ## 运行环境判定(debug 口径,必须)
14
+
15
+ **唯一标准**:以 `src/framework/utils/function.ts` 为准,**不要**用 `process.env.NODE_ENV` 作为“是否生产/是否调试”的单一判断。
16
+
17
+ - **`isDebug()`**:当进程启动参数中包含 `--env=debug` 时为 `true`。
18
+ - **非 debug**:一律按**生产口径**处理(例如:迁移、静态资源长缓存、对外错误信息脱敏等)。
19
+ - **`getRuntimeEnvironmentLabel()`**:返回 `'development' | 'production'`,用于日志与配置元数据,**与 `NODE_ENV` 解耦**。
20
+
21
+ **例外**:`NODE_ENV === 'test'`(Jest 等)仍保留用于测试专用分支,与上述 debug 口径并行,不互相替代。
22
+
23
+ ---
24
+
25
+ ## 一、分层架构(必须遵守)
26
+
27
+ ### 分层职责
28
+ - **Controller 层**
29
+ - 接收请求
30
+ - 参数校验
31
+ - 调用 Service
32
+ - 返回统一响应
33
+ - **Service 层**
34
+ - 编写业务逻辑
35
+ - 调用 Repository
36
+ - **Repository 层**
37
+ - 封装数据库访问逻辑(TypeORM)
38
+
39
+ ---
40
+
41
+ ## 二、基类与返回规范
42
+
43
+ ### 基类继承
44
+ - Controller **必须继承** `BaseController`
45
+ - Service **必须继承** `BaseService`
46
+
47
+ ### Service 返回值
48
+ - Service 方法必须返回 `CommonServiceResult<T>`
49
+
50
+ ### Controller 返回值
51
+ - Controller 必须通过:
52
+ - `this.success<T>(data, message?)`
53
+ - `this.fail<T>(code, message?)`
54
+
55
+ 返回 `ControllerResponse<T>`:
56
+ ```ts
57
+ {
58
+ code: number
59
+ data: T | null
60
+ message: string
61
+ }
@@ -0,0 +1,57 @@
1
+ ---
2
+ alwaysApply: true
3
+ ---
4
+ # Skill:Backend Skill Router(规则路由器)
5
+
6
+ 你现在的角色是【后端 Skill 路由器】:你的目标是帮助选择应启用的 rules/skills/commands,避免盲用规则。
7
+
8
+ ## 总原则(必须遵守)
9
+ - **优先使用 Commands** 来触发正确的 Skills,而不是把所有规则都写成 alwaysApply。
10
+ - 如果用户需求不清晰,必须先提问澄清(不要臆造不存在的接口/文件/配置)。
11
+
12
+ ---
13
+
14
+ ## 你必须做的事(每次用户提出开发/改动请求时)
15
+
16
+ ### 1) 识别任务类型(多选)
17
+ - Controller/API 开发
18
+ - DTO/参数校验
19
+ - Service/Repository/事务
20
+ - 错误处理/日志
21
+ - 启动流程(`app.ts`/`bootstrap.ts`,before/after)
22
+ - 路由注册(`routers/index.ts`、`bindRouter`)
23
+ - 中间件(`src/middlewares/*`)
24
+ - 测试(Jest)
25
+ - 目录结构与放置(libs/utils)
26
+
27
+ ### 2) 给出推荐启用的 Skills(只列文件名即可)
28
+ 按任务类型映射:
29
+ - **Controller/API**:
30
+ - `10-backend-api.skill.md`
31
+ -(需要范式/注解速查时)`11-backend-controller-recipes.skill.md`
32
+ - **Service**:
33
+ - `21-backend-service.skill.md`
34
+ - **DTO/校验**:`30-backend-validation.skill.md`
35
+ - **Service/Repository/事务**:`20-backend-repository.skill.md`
36
+ - **错误/日志**:`40-backend-error-logging.skill.md`
37
+ - **启动流程**:`50-backend-bootstrap-lifecycle.skill.md`
38
+ - **路由注册**:`60-backend-router-registration.skill.md`
39
+ - **中间件**:`70-backend-middleware.skill.md`
40
+ - **测试**:`90-backend-testing.skill.md`
41
+ - **libs/utils 放置**:`80-backend-utils-and-libs.skill.md`
42
+
43
+ 注意:
44
+ - `00-backend-core.skill.md` 已是 alwaysApply,无需重复声明
45
+
46
+ ### 3) 推荐使用的 Command(优先)
47
+ - 需要先规划:`.cursor/commands/plan-backend.md`
48
+ - 要实现/修改 Controller:`.cursor/commands/implement-backend-api-controller.md`
49
+ - 只要 Controller 速查:`.cursor/commands/cheatsheet-backend-controller.md`
50
+
51
+ ---
52
+
53
+ ## 输出要求(简短)
54
+ - 当用户让你“直接写代码”:直接进入实现,但先在心里完成上述路由选择
55
+ - 当用户不确定或信息不足:先问 2~5 个关键澄清问题
56
+
57
+
@@ -0,0 +1,55 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Skill:后端 API 开发规范
5
+
6
+ ## 适用与触发(重要)
7
+ - **仅在**你要生成/修改 **Controller 路由接口** 时应用本 Skill(否则忽略)
8
+ - 触发口令建议:
9
+ - “按 `10-backend-api.skill.md` 实现/重构这个 Controller”
10
+ - “按 API Skill 写路由 + DTO + 统一响应”
11
+
12
+ ---
13
+
14
+ ## 一、路由与参数装饰器(必须)
15
+ - 路由装饰器:`@Get` / `@Post`
16
+ - 参数装饰器:`@Query` / `@Body` / `@State`
17
+ - 禁止在 Controller 中手动解析 ctx(除非该 Controller 明确以 ctx 作为参数且项目已有同类写法)
18
+
19
+ ---
20
+
21
+ ## 二、Controller 编排规范(必须)
22
+
23
+ ### 2.1 只做三件事
24
+ - **参数接收与校验**(DTO)
25
+ - **调用 Service**
26
+ - **映射为统一响应**(`BaseController.success/fail`)
27
+
28
+ ### 2.2 统一响应(必须)
29
+ - Controller 必须返回 `ControllerResponse<T>`(通过 `this.success()` / `this.fail()`)
30
+ - 禁止 `return result`(Service 原始结果):
31
+ - 成功:`return this.success(result.data, result.message?)`
32
+ - 失败:`return this.fail(result.code, result.message)`
33
+
34
+ ### 2.3 错误处理(必须)
35
+ - Controller 的 `async` 方法必须 `try/catch`
36
+ - catch:记录日志(见 `40-backend-error-logging.skill.md`)+ 返回通用失败响应
37
+
38
+ ### 2.4 DTO(必须)
39
+ - `@Query()` / `@Body()` 必须使用 **DTO 类型**(禁止 `any`)
40
+ - DTO 的定义与校验遵循 `30-backend-validation.skill.md`
41
+
42
+ ---
43
+
44
+ ## 三、接口文档与元信息(可选但优先)
45
+ - 对外接口优先补齐 Swagger:`@ApiTags` / `@Api` / `@ApiResponse`
46
+ - 需要显式状态码/响应头时使用:`@ResponseCode` / `@ResponseHeader`
47
+
48
+ ---
49
+
50
+ ## 四、禁止行为(必须)
51
+ - ❌ Controller 中编写业务逻辑(应下沉到 Service)
52
+ - ❌ Controller 中直接访问数据库/Repository
53
+ - ❌ Controller 中返回 Service 原始结果(必须映射为统一响应)
54
+ - ❌ `@Query()` / `@Body()` 使用 `any` 或未校验的入参对象
55
+
@@ -0,0 +1,188 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Skill:Controller 推荐写法 + 常用注解速查(Recipes)
5
+
6
+ ## 适用与触发(重要)
7
+ - 仅当需要**新增/修改 Controller 路由接口**,且希望按本项目框架“推荐范式”实现时使用本 Skill。
8
+ - 触发口令建议:
9
+ - “请同时启用 `11-backend-controller-recipes.skill.md`,按项目范式实现 Controller”
10
+
11
+ ---
12
+
13
+ ## 一、写 Controller 的推荐范式(必须对齐)
14
+
15
+ ### 1.1 内嵌参考样例(本 Skill 自包含)
16
+ 以下为从本项目常用写法整理的最小示例;**实现新接口时请先对齐本节的装饰器与类型风格**。若仓库中另有 `src/controllers/example/*` 等运行时代码,可作为补充参考,但**不必依赖**特定业务 Controller 文件是否存在。
17
+
18
+ #### 1.1.1 `BaseController` 与 `ControllerResponse`(统一响应)
19
+
20
+ ```ts
21
+ export class ControllerResponse<T> {
22
+ code = 0;
23
+ data: T | null = null;
24
+ message = '';
25
+
26
+ constructor(code: number, data: T | null, message?: string) {
27
+ this.code = code;
28
+ this.data = data;
29
+ if (message) this.message = message;
30
+ }
31
+ }
32
+
33
+ export class BaseController {
34
+ success<T>(data: T, message?: string) {
35
+ return new ControllerResponse<T>(0, data, message);
36
+ }
37
+ fail<T>(code: number, message?: string) {
38
+ return new ControllerResponse<T>(code, null, message);
39
+ }
40
+ }
41
+ ```
42
+
43
+ #### 1.1.2 `@State()`:读取整段 `ctx.state`
44
+
45
+ ```ts
46
+ import { Get, State } from '@src/framework/decorator/controller';
47
+ import { BaseController, ControllerResponse } from '@src/controllers/base.controller';
48
+
49
+ export class ExampleStateController extends BaseController {
50
+ @Get('/example/state-full')
51
+ async getWithFullState(
52
+ @State() state: { user: { userId: number; type?: number } },
53
+ ): Promise<ControllerResponse<{ userId: number }>> {
54
+ return this.success({ userId: state.user.userId });
55
+ }
56
+ }
57
+ ```
58
+
59
+ #### 1.1.3 `@State('user')`:只读 `ctx.state.user`
60
+
61
+ ```ts
62
+ import { Get, State } from '@src/framework/decorator/controller';
63
+ import { BaseController, ControllerResponse } from '@src/controllers/base.controller';
64
+
65
+ export class ExampleUserSliceController extends BaseController {
66
+ @Get('/example/state-user')
67
+ async getWithUser(
68
+ @State('user') user: { userId: number; type?: number },
69
+ ): Promise<ControllerResponse<{ ok: boolean }>> {
70
+ return this.success({ ok: user.userId > 0 });
71
+ }
72
+ }
73
+ ```
74
+
75
+ #### 1.1.4 `@ResponseValidateIf`:仅在条件成立时校验响应体
76
+
77
+ ```ts
78
+ import { Get, State, ResponseValidateIf } from '@src/framework/decorator/controller';
79
+ import { BaseController, ControllerResponse } from '@src/controllers/base.controller';
80
+
81
+ // 示例 DTO:按实际接口替换
82
+ class UserProfileResponseDto {
83
+ id!: number;
84
+ nickName!: string;
85
+ }
86
+
87
+ export class ExampleResponseValidateController extends BaseController {
88
+ @ResponseValidateIf(UserProfileResponseDto, (data) => Boolean(data && data.data))
89
+ @Get('/example/profile')
90
+ async getProfile(
91
+ @State() state: { user: { userId: number } },
92
+ ): Promise<ControllerResponse<UserProfileResponseDto | null>> {
93
+ return this.success({
94
+ id: state.user.userId,
95
+ nickName: 'demo',
96
+ });
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### 1.2 Controller 标准骨架(复制这个结构)
102
+ 目标:DTO 入参 → 调用 Service → 统一响应(`success/fail`)→ try/catch + logger
103
+
104
+ ```ts
105
+ import { Get, Post, Query, Body, State, ResponseCode, ResponseHeader } from '@src/framework/decorator/controller';
106
+ import { BaseController, ControllerResponse } from '@src/controllers/base.controller';
107
+ import { Inject } from 'dp-ioc2';
108
+ import { logger } from '@src/framework/utils/logger';
109
+ import { SomeService } from '@src/service/some.service';
110
+ import { SomeQueryDto, SomeBodyDto } from '@src/dto/controller/xxx/some.controller.dto';
111
+ import { CommonServiceResultCode } from '@src/framework/types/ServiceResult';
112
+
113
+ export class SomeController extends BaseController {
114
+ @Inject(SomeService)
115
+ private someService: SomeService;
116
+
117
+ @Get('/some/path')
118
+ @ResponseCode(200)
119
+ async getSomething(
120
+ @Query(SomeQueryDto) query: SomeQueryDto,
121
+ @State('user') user: { userId: number; type?: number },
122
+ ): Promise<ControllerResponse<any>> {
123
+ try {
124
+ const result = await this.someService.someMethod(query, user.userId);
125
+ if (result.code !== CommonServiceResultCode.SUCCESS) {
126
+ return this.fail(-1, result.message);
127
+ }
128
+ return this.success(result.data);
129
+ } catch (error) {
130
+ logger.error('getSomething 失败', error as Error);
131
+ return this.fail(-1, '系统错误');
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ 硬约束:
138
+ - Controller **不写业务逻辑**,只做编排
139
+ - Controller **不直接访问数据库/Repository**
140
+ - Controller **不 return Service 原始结果**,必须映射 `success/fail`
141
+ - Controller `async` **必须 try/catch**
142
+
143
+ ---
144
+
145
+ ## 二、常用注解速查(按本项目实现理解)
146
+
147
+ ### 2.1 路由类注解
148
+ - **`@Get('/path')`**:注册 GET 路由;不传参数时 url 默认使用方法名
149
+ - **`@Post('/path')`**:注册 POST 路由;不传参数时 url 默认使用方法名
150
+
151
+ ### 2.2 参数注解(重点)
152
+ - **`@Query()`**:
153
+ - 读取 query 参数
154
+ - 推荐写法:`@Query(SomeQueryDto) query: XxxQueryDto`
155
+ - **`@Body()`**:
156
+ - 读取 body 参数
157
+ - 推荐写法:`@Body(SomeBodyDto) body: XxxBodyDto`
158
+ - **`@State()`**:
159
+ - 读取整个 `ctx.state`(样例:见 **1.1.2**)
160
+ - 推荐写法:`@State() state: { user: { userId: number; type?: number } }`
161
+ - **`@State('user')`**:
162
+ - 读取 `ctx.state.user`(样例:见 **1.1.3**)
163
+ - 推荐写法:`@State('user') user: { userId: number; type?: number }`
164
+
165
+ 禁止:
166
+ - ❌ `@Query() query: any` / `@Body() body: any` / `@State() state: any`(尽量不要)
167
+
168
+ ### 2.3 响应元信息注解
169
+ - **`@ResponseCode(200|201|...)`**:设置 HTTP 状态码(样例中 GET 用 200,POST 用 201)
170
+ - **`@ResponseHeader(key, value)`**:为响应添加 header
171
+
172
+ ### 2.4 响应校验注解(进阶,按需)
173
+ - **`@ResponseValidator(DtoClass, objectKey?)`**:对响应数据做校验
174
+ - **`@ResponseValidateIf(DtoClass, fn)`**:仅当 fn 返回真时才校验(样例:见 **1.1.4**)
175
+
176
+ ---
177
+
178
+ ## 三、常见组合(直接套用)
179
+
180
+ ### 3.1 需要登录用户的 GET 接口
181
+ - `@Get('/xxx') + @State('user')`(或 `@State()` 取整段 state)
182
+
183
+ ### 3.2 带 body 的 POST 接口
184
+ - `@Post('/xxx') + @Body(SomeBodyDto) body: SomeBodyDto + @ResponseCode(201)`
185
+
186
+ ### 3.3 需要自定义 header
187
+ - `@ResponseHeader('X-XXX', 'value')`
188
+
@@ -0,0 +1,25 @@
1
+ ---
2
+ alwaysApply: false
3
+ ---
4
+ # Skill:Repository 与数据访问规范
5
+
6
+ ## 一、Repository 使用方式
7
+
8
+ - Service 中通过:
9
+ - `getDataRepository<Entity>(EntityClass)`
10
+ - 或 `createLazyRepository()`(推荐)
11
+
12
+ ---
13
+
14
+ ## 二、事务管理
15
+
16
+ - 涉及多表操作时:
17
+ - 必须使用 `transactionManager.executeInTransaction()`
18
+ - 禁止手动管理事务
19
+
20
+ ---
21
+
22
+ ## 三、禁止行为
23
+
24
+ - ❌ Controller 中访问 Repository
25
+ - ❌ Service 中直接获取 DataSource