create-pardx-scaffold 0.1.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 (555) hide show
  1. package/README.md +45 -0
  2. package/cli.js +104 -0
  3. package/package.json +15 -0
  4. package/template/.cursorrules +479 -0
  5. package/template/.prettierignore +29 -0
  6. package/template/.prettierrc +11 -0
  7. package/template/.vscode/extensions.json +8 -0
  8. package/template/.vscode/settings.json +122 -0
  9. package/template/CLAUDE.md +762 -0
  10. package/template/README.md +125 -0
  11. package/template/apps/api/.env.example +11 -0
  12. package/template/apps/api/.eslintrc.js +222 -0
  13. package/template/apps/api/config.local.yaml +397 -0
  14. package/template/apps/api/libs/domain/auth/package.json +11 -0
  15. package/template/apps/api/libs/domain/auth/src/README.md +189 -0
  16. package/template/apps/api/libs/domain/auth/src/auth-validation.service.ts +37 -0
  17. package/template/apps/api/libs/domain/auth/src/auth.guard.ts +173 -0
  18. package/template/apps/api/libs/domain/auth/src/auth.module.ts +23 -0
  19. package/template/apps/api/libs/domain/auth/src/auth.service.ts +198 -0
  20. package/template/apps/api/libs/domain/auth/src/auth.ts +66 -0
  21. package/template/apps/api/libs/domain/auth/src/decorators/presets.decorator.ts +50 -0
  22. package/template/apps/api/libs/domain/auth/src/decorators/rbac.decorator.ts +67 -0
  23. package/template/apps/api/libs/domain/auth/src/decorators/resource-owner.decorator.ts +67 -0
  24. package/template/apps/api/libs/domain/auth/src/dto/auth.dto.ts +10 -0
  25. package/template/apps/api/libs/domain/auth/src/guards/streaming-asr-session.guard.ts +179 -0
  26. package/template/apps/api/libs/domain/auth/src/index.ts +12 -0
  27. package/template/apps/api/libs/domain/auth/src/types/auth.interface.ts +52 -0
  28. package/template/apps/api/libs/domain/auth/tsconfig.lib.json +9 -0
  29. package/template/apps/api/libs/domain/db/package.json +11 -0
  30. package/template/apps/api/libs/domain/db/src/index.ts +14 -0
  31. package/template/apps/api/libs/domain/db/src/modules/country-code/country-code.module.ts +12 -0
  32. package/template/apps/api/libs/domain/db/src/modules/country-code/country-code.service.ts +140 -0
  33. package/template/apps/api/libs/domain/db/src/modules/country-code/index.ts +2 -0
  34. package/template/apps/api/libs/domain/db/src/modules/discord-auth/discord-auth.module.ts +12 -0
  35. package/template/apps/api/libs/domain/db/src/modules/discord-auth/discord-auth.service.ts +101 -0
  36. package/template/apps/api/libs/domain/db/src/modules/discord-auth/index.ts +2 -0
  37. package/template/apps/api/libs/domain/db/src/modules/email-auth/email-auth.module.ts +12 -0
  38. package/template/apps/api/libs/domain/db/src/modules/email-auth/email-auth.service.ts +101 -0
  39. package/template/apps/api/libs/domain/db/src/modules/email-auth/index.ts +2 -0
  40. package/template/apps/api/libs/domain/db/src/modules/file-source/file-source.module.ts +12 -0
  41. package/template/apps/api/libs/domain/db/src/modules/file-source/file-source.service.ts +109 -0
  42. package/template/apps/api/libs/domain/db/src/modules/file-source/index.ts +2 -0
  43. package/template/apps/api/libs/domain/db/src/modules/google-auth/google-auth.module.ts +12 -0
  44. package/template/apps/api/libs/domain/db/src/modules/google-auth/google-auth.service.ts +101 -0
  45. package/template/apps/api/libs/domain/db/src/modules/google-auth/index.ts +2 -0
  46. package/template/apps/api/libs/domain/db/src/modules/message/index.ts +2 -0
  47. package/template/apps/api/libs/domain/db/src/modules/message/message.module.ts +10 -0
  48. package/template/apps/api/libs/domain/db/src/modules/message/message.service.ts +314 -0
  49. package/template/apps/api/libs/domain/db/src/modules/mobile-auth/index.ts +2 -0
  50. package/template/apps/api/libs/domain/db/src/modules/mobile-auth/mobile-auth.module.ts +12 -0
  51. package/template/apps/api/libs/domain/db/src/modules/mobile-auth/mobile-auth.service.ts +101 -0
  52. package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/index.ts +2 -0
  53. package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/risk-detection-record.module.ts +12 -0
  54. package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/risk-detection-record.service.ts +101 -0
  55. package/template/apps/api/libs/domain/db/src/modules/system-task-queue/index.ts +2 -0
  56. package/template/apps/api/libs/domain/db/src/modules/system-task-queue/system-task-queue.module.ts +12 -0
  57. package/template/apps/api/libs/domain/db/src/modules/system-task-queue/system-task-queue.service.ts +101 -0
  58. package/template/apps/api/libs/domain/db/src/modules/user-info/index.ts +2 -0
  59. package/template/apps/api/libs/domain/db/src/modules/user-info/user-info.module.ts +12 -0
  60. package/template/apps/api/libs/domain/db/src/modules/user-info/user-info.service.ts +139 -0
  61. package/template/apps/api/libs/domain/db/src/modules/wechat-auth/index.ts +2 -0
  62. package/template/apps/api/libs/domain/db/src/modules/wechat-auth/wechat-auth.module.ts +12 -0
  63. package/template/apps/api/libs/domain/db/src/modules/wechat-auth/wechat-auth.service.ts +101 -0
  64. package/template/apps/api/libs/domain/db/tsconfig.lib.json +9 -0
  65. package/template/apps/api/libs/infra/clients/internal/ai/index.ts +2 -0
  66. package/template/apps/api/libs/infra/clients/internal/ai/risk-detection.client.ts +301 -0
  67. package/template/apps/api/libs/infra/clients/internal/ai/risk-detection.module.ts +22 -0
  68. package/template/apps/api/libs/infra/clients/internal/crypt/crypt-client.service.spec.ts +18 -0
  69. package/template/apps/api/libs/infra/clients/internal/crypt/crypt.client.ts +37 -0
  70. package/template/apps/api/libs/infra/clients/internal/crypt/crypt.module.ts +10 -0
  71. package/template/apps/api/libs/infra/clients/internal/crypt/index.ts +2 -0
  72. package/template/apps/api/libs/infra/clients/internal/email/dto/email.dto.ts +75 -0
  73. package/template/apps/api/libs/infra/clients/internal/email/index.ts +11 -0
  74. package/template/apps/api/libs/infra/clients/internal/email/sendcloud.client.ts +400 -0
  75. package/template/apps/api/libs/infra/clients/internal/file-cdn/README.md +255 -0
  76. package/template/apps/api/libs/infra/clients/internal/file-cdn/dto/file-cdn.dto.ts +96 -0
  77. package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn-client.service.spec.ts +18 -0
  78. package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn.client.ts +620 -0
  79. package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn.module.ts +19 -0
  80. package/template/apps/api/libs/infra/clients/internal/file-cdn/index.ts +40 -0
  81. package/template/apps/api/libs/infra/clients/internal/file-storage/config/file.config.ts +14 -0
  82. package/template/apps/api/libs/infra/clients/internal/file-storage/dto/file.dto.ts +127 -0
  83. package/template/apps/api/libs/infra/clients/internal/file-storage/file-gcs.client.ts +154 -0
  84. package/template/apps/api/libs/infra/clients/internal/file-storage/file-qiniu.client.ts +729 -0
  85. package/template/apps/api/libs/infra/clients/internal/file-storage/file-s3.client.ts +1097 -0
  86. package/template/apps/api/libs/infra/clients/internal/file-storage/file-storage.interface.ts +114 -0
  87. package/template/apps/api/libs/infra/clients/internal/file-storage/file-tos.client.ts +767 -0
  88. package/template/apps/api/libs/infra/clients/internal/file-storage/file-us3.client.ts +176 -0
  89. package/template/apps/api/libs/infra/clients/internal/file-storage/index.ts +16 -0
  90. package/template/apps/api/libs/infra/clients/internal/ocr/dto/ocr.dto.ts +61 -0
  91. package/template/apps/api/libs/infra/clients/internal/ocr/index.ts +3 -0
  92. package/template/apps/api/libs/infra/clients/internal/ocr/ocr.client.ts +123 -0
  93. package/template/apps/api/libs/infra/clients/internal/ocr/ocr.module.ts +15 -0
  94. package/template/apps/api/libs/infra/clients/internal/openai/index.ts +2 -0
  95. package/template/apps/api/libs/infra/clients/internal/openai/openai.client.ts +135 -0
  96. package/template/apps/api/libs/infra/clients/internal/openai/openai.module.ts +17 -0
  97. package/template/apps/api/libs/infra/clients/internal/openspeech/README.md +508 -0
  98. package/template/apps/api/libs/infra/clients/internal/openspeech/index.ts +44 -0
  99. package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.client.ts +441 -0
  100. package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.factory.ts +450 -0
  101. package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.module.ts +56 -0
  102. package/template/apps/api/libs/infra/clients/internal/openspeech/providers/aliyun.provider.ts +308 -0
  103. package/template/apps/api/libs/infra/clients/internal/openspeech/providers/base.provider.ts +114 -0
  104. package/template/apps/api/libs/infra/clients/internal/openspeech/providers/index.ts +10 -0
  105. package/template/apps/api/libs/infra/clients/internal/openspeech/providers/volcengine-streaming.provider.ts +1689 -0
  106. package/template/apps/api/libs/infra/clients/internal/openspeech/providers/volcengine.provider.ts +387 -0
  107. package/template/apps/api/libs/infra/clients/internal/openspeech/types.ts +467 -0
  108. package/template/apps/api/libs/infra/clients/internal/sms/dto/sms.dto.ts +97 -0
  109. package/template/apps/api/libs/infra/clients/internal/sms/index.ts +15 -0
  110. package/template/apps/api/libs/infra/clients/internal/sms/sms-aliyun.client.ts +52 -0
  111. package/template/apps/api/libs/infra/clients/internal/sms/sms-http.client.ts +111 -0
  112. package/template/apps/api/libs/infra/clients/internal/sms/sms-tencent.client.ts +54 -0
  113. package/template/apps/api/libs/infra/clients/internal/sms/sms-volcengine.client.ts +165 -0
  114. package/template/apps/api/libs/infra/clients/internal/sms/sms-zxjc.client.ts +47 -0
  115. package/template/apps/api/libs/infra/clients/internal/sse/index.ts +2 -0
  116. package/template/apps/api/libs/infra/clients/internal/sse/sse-client.service.spec.ts +18 -0
  117. package/template/apps/api/libs/infra/clients/internal/sse/sse.client.ts +360 -0
  118. package/template/apps/api/libs/infra/clients/internal/sse/sse.module.ts +17 -0
  119. package/template/apps/api/libs/infra/clients/internal/third-party-sse/index.ts +2 -0
  120. package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.client.ts +51 -0
  121. package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.module.ts +10 -0
  122. package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.service.spec.ts +18 -0
  123. package/template/apps/api/libs/infra/clients/internal/verify/index.ts +2 -0
  124. package/template/apps/api/libs/infra/clients/internal/verify/verify.client.ts +42 -0
  125. package/template/apps/api/libs/infra/clients/internal/verify/verify.module.ts +10 -0
  126. package/template/apps/api/libs/infra/clients/internal/volcengine-tts/dto/tts.dto.ts +64 -0
  127. package/template/apps/api/libs/infra/clients/internal/volcengine-tts/index.ts +3 -0
  128. package/template/apps/api/libs/infra/clients/internal/volcengine-tts/volcengine-tts.client.ts +846 -0
  129. package/template/apps/api/libs/infra/clients/internal/volcengine-tts/volcengine-tts.module.ts +21 -0
  130. package/template/apps/api/libs/infra/clients/internal/wechat/index.ts +2 -0
  131. package/template/apps/api/libs/infra/clients/internal/wechat/wechat-client.service.spec.ts +18 -0
  132. package/template/apps/api/libs/infra/clients/internal/wechat/wechat.client.ts +4 -0
  133. package/template/apps/api/libs/infra/clients/internal/wechat/wechat.module.ts +8 -0
  134. package/template/apps/api/libs/infra/clients/plugin/decorators/inject-client.decorator.ts +60 -0
  135. package/template/apps/api/libs/infra/clients/plugin/index.ts +21 -0
  136. package/template/apps/api/libs/infra/clients/plugin/interceptors/http-logging.interceptor.ts +130 -0
  137. package/template/apps/api/libs/infra/clients/plugin/interfaces/client.interface.ts +86 -0
  138. package/template/apps/api/libs/infra/clients/plugin/utils/retry.util.ts +157 -0
  139. package/template/apps/api/libs/infra/common/adapters/base.adapter.ts +94 -0
  140. package/template/apps/api/libs/infra/common/adapters/index.ts +38 -0
  141. package/template/apps/api/libs/infra/common/config/README.md +254 -0
  142. package/template/apps/api/libs/infra/common/config/agentx.config.ts +91 -0
  143. package/template/apps/api/libs/infra/common/config/configuration.ts +289 -0
  144. package/template/apps/api/libs/infra/common/config/constant/config.constants.ts +92 -0
  145. package/template/apps/api/libs/infra/common/config/dto/config.dto.ts +282 -0
  146. package/template/apps/api/libs/infra/common/config/package.json +11 -0
  147. package/template/apps/api/libs/infra/common/config/validation/env.validation.ts +161 -0
  148. package/template/apps/api/libs/infra/common/config/validation/index.ts +188 -0
  149. package/template/apps/api/libs/infra/common/config/validation/keys.validation.ts +564 -0
  150. package/template/apps/api/libs/infra/common/config/validation/yaml.validation.ts +582 -0
  151. package/template/apps/api/libs/infra/common/decorators/app-version/app-version.controller.ts +135 -0
  152. package/template/apps/api/libs/infra/common/decorators/app-version/app-version.interceptor.ts +36 -0
  153. package/template/apps/api/libs/infra/common/decorators/app-version/app-version.module.ts +27 -0
  154. package/template/apps/api/libs/infra/common/decorators/app-version/app-version.service.ts +252 -0
  155. package/template/apps/api/libs/infra/common/decorators/app-version/index.ts +13 -0
  156. package/template/apps/api/libs/infra/common/decorators/cache/cache.decorator.ts +437 -0
  157. package/template/apps/api/libs/infra/common/decorators/cache/cache.interceptor.ts +268 -0
  158. package/template/apps/api/libs/infra/common/decorators/cache/cache.module.ts +24 -0
  159. package/template/apps/api/libs/infra/common/decorators/cache/index.ts +33 -0
  160. package/template/apps/api/libs/infra/common/decorators/event/event.decorator.ts +229 -0
  161. package/template/apps/api/libs/infra/common/decorators/event/event.interceptor.ts +155 -0
  162. package/template/apps/api/libs/infra/common/decorators/event/event.module.ts +47 -0
  163. package/template/apps/api/libs/infra/common/decorators/event/handlers/cache-event.handler.ts +159 -0
  164. package/template/apps/api/libs/infra/common/decorators/event/index.ts +29 -0
  165. package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.decorator.ts +221 -0
  166. package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.interceptor.ts +150 -0
  167. package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.module.ts +27 -0
  168. package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.service.spec.ts +330 -0
  169. package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.service.ts +423 -0
  170. package/template/apps/api/libs/infra/common/decorators/feature-flag/index.ts +28 -0
  171. package/template/apps/api/libs/infra/common/decorators/rate-limit/dto/rate-limit.dto.ts +201 -0
  172. package/template/apps/api/libs/infra/common/decorators/rate-limit/index.ts +54 -0
  173. package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.decorator.ts +216 -0
  174. package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.exception.ts +74 -0
  175. package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.module.ts +37 -0
  176. package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.service.ts +430 -0
  177. package/template/apps/api/libs/infra/common/decorators/response.decorator.ts +67 -0
  178. package/template/apps/api/libs/infra/common/decorators/skip-version-check.decorator.ts +27 -0
  179. package/template/apps/api/libs/infra/common/decorators/transaction/index.ts +12 -0
  180. package/template/apps/api/libs/infra/common/decorators/transaction/transactional.decorator.ts +677 -0
  181. package/template/apps/api/libs/infra/common/decorators/ts-rest-controller.decorator.ts +63 -0
  182. package/template/apps/api/libs/infra/common/decorators/validation.decorator.ts +120 -0
  183. package/template/apps/api/libs/infra/common/decorators/version/index.ts +24 -0
  184. package/template/apps/api/libs/infra/common/decorators/version/version.decorator.ts +168 -0
  185. package/template/apps/api/libs/infra/common/decorators/version/version.interceptor.ts +97 -0
  186. package/template/apps/api/libs/infra/common/decorators/version/version.module.ts +21 -0
  187. package/template/apps/api/libs/infra/common/enums/action.enum.ts +7 -0
  188. package/template/apps/api/libs/infra/common/enums/error-codes.ts +71 -0
  189. package/template/apps/api/libs/infra/common/enums/role.enum.ts +4 -0
  190. package/template/apps/api/libs/infra/common/filter/exception/api.exception.ts +168 -0
  191. package/template/apps/api/libs/infra/common/filter/exception/exception.ts +47 -0
  192. package/template/apps/api/libs/infra/common/filter/exception/http.exception.ts +126 -0
  193. package/template/apps/api/libs/infra/common/guards/index.ts +1 -0
  194. package/template/apps/api/libs/infra/common/guards/version.guard.ts +312 -0
  195. package/template/apps/api/libs/infra/common/interceptor/mask/index.ts +1 -0
  196. package/template/apps/api/libs/infra/common/interceptor/mask/mask.interceptor.ts +242 -0
  197. package/template/apps/api/libs/infra/common/interceptor/rate-limit/no-rate-limit.interceptor.ts +14 -0
  198. package/template/apps/api/libs/infra/common/interceptor/rate-limit/rate-limit.interceptor.ts +230 -0
  199. package/template/apps/api/libs/infra/common/interceptor/transform/transform.interceptor.spec.ts +7 -0
  200. package/template/apps/api/libs/infra/common/interceptor/transform/transform.interceptor.ts +75 -0
  201. package/template/apps/api/libs/infra/common/interceptor/version/index.ts +1 -0
  202. package/template/apps/api/libs/infra/common/interceptor/version/version-header.interceptor.ts +62 -0
  203. package/template/apps/api/libs/infra/common/middleware/request.middleware.ts +109 -0
  204. package/template/apps/api/libs/infra/common/package.json +11 -0
  205. package/template/apps/api/libs/infra/common/pipes/transform-root.pipe.ts +12 -0
  206. package/template/apps/api/libs/infra/common/ts-rest/index.ts +26 -0
  207. package/template/apps/api/libs/infra/common/ts-rest/response.helper.ts +233 -0
  208. package/template/apps/api/libs/infra/i18n/en/errors.json +77 -0
  209. package/template/apps/api/libs/infra/i18n/en/events.json +1 -0
  210. package/template/apps/api/libs/infra/i18n/package.json +11 -0
  211. package/template/apps/api/libs/infra/i18n/zh-CN/errors.json +77 -0
  212. package/template/apps/api/libs/infra/i18n/zh-CN/events.json +1 -0
  213. package/template/apps/api/libs/infra/jwt/dto/jwt.dto.ts +1 -0
  214. package/template/apps/api/libs/infra/jwt/jwt.module.ts +26 -0
  215. package/template/apps/api/libs/infra/jwt/package.json +11 -0
  216. package/template/apps/api/libs/infra/prisma/db-metrics/package.json +11 -0
  217. package/template/apps/api/libs/infra/prisma/db-metrics/src/db-metrics.module.ts +141 -0
  218. package/template/apps/api/libs/infra/prisma/db-metrics/src/db-metrics.service.ts +456 -0
  219. package/template/apps/api/libs/infra/prisma/db-metrics/src/index.ts +2 -0
  220. package/template/apps/api/libs/infra/prisma/db-metrics/tsconfig.lib.json +9 -0
  221. package/template/apps/api/libs/infra/prisma/middleware/soft-delete.middleware.ts +179 -0
  222. package/template/apps/api/libs/infra/prisma/package.json +11 -0
  223. package/template/apps/api/libs/infra/prisma/prisma/index.ts +3 -0
  224. package/template/apps/api/libs/infra/prisma/prisma/prisma.module.ts +12 -0
  225. package/template/apps/api/libs/infra/prisma/prisma/prisma.service.ts +18 -0
  226. package/template/apps/api/libs/infra/prisma/prisma/types.ts +6 -0
  227. package/template/apps/api/libs/infra/prisma/prisma-read/prisma-read.module.ts +11 -0
  228. package/template/apps/api/libs/infra/prisma/prisma-read/prisma-read.service.ts +280 -0
  229. package/template/apps/api/libs/infra/prisma/prisma-write/prisma-write.module.ts +11 -0
  230. package/template/apps/api/libs/infra/prisma/prisma-write/prisma-write.service.ts +278 -0
  231. package/template/apps/api/libs/infra/prisma/prometheus/index.ts +1 -0
  232. package/template/apps/api/libs/infra/prisma/prometheus/prometheus.module.ts +231 -0
  233. package/template/apps/api/libs/infra/rabbitmq/package.json +11 -0
  234. package/template/apps/api/libs/infra/rabbitmq/src/dto/rabbitmq.dto.ts +13 -0
  235. package/template/apps/api/libs/infra/rabbitmq/src/index.ts +5 -0
  236. package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq-events.module.ts +132 -0
  237. package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq-events.service.ts +199 -0
  238. package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.module.ts +101 -0
  239. package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.service.spec.ts +18 -0
  240. package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.service.ts +543 -0
  241. package/template/apps/api/libs/infra/rabbitmq/tsconfig.lib.json +9 -0
  242. package/template/apps/api/libs/infra/redis/dto/redis.dto.ts +3 -0
  243. package/template/apps/api/libs/infra/redis/package.json +11 -0
  244. package/template/apps/api/libs/infra/redis/src/index.ts +2 -0
  245. package/template/apps/api/libs/infra/redis/src/redis.module.ts +63 -0
  246. package/template/apps/api/libs/infra/redis/src/redis.service.spec.ts +18 -0
  247. package/template/apps/api/libs/infra/redis/src/redis.service.ts +730 -0
  248. package/template/apps/api/libs/infra/redis/tsconfig.lib.json +9 -0
  249. package/template/apps/api/libs/infra/shared-db/index.ts +14 -0
  250. package/template/apps/api/libs/infra/shared-db/transaction-context.ts +51 -0
  251. package/template/apps/api/libs/infra/shared-db/transaction.module.ts +15 -0
  252. package/template/apps/api/libs/infra/shared-db/transaction.perf.spec.ts +226 -0
  253. package/template/apps/api/libs/infra/shared-db/transactional-service.base.ts +102 -0
  254. package/template/apps/api/libs/infra/shared-db/unit-of-work.service.ts +142 -0
  255. package/template/apps/api/libs/infra/shared-services/email/dto/email.dto.ts +87 -0
  256. package/template/apps/api/libs/infra/shared-services/email/email.module.ts +27 -0
  257. package/template/apps/api/libs/infra/shared-services/email/email.service.ts +258 -0
  258. package/template/apps/api/libs/infra/shared-services/email/index.ts +5 -0
  259. package/template/apps/api/libs/infra/shared-services/file-storage/README.md +376 -0
  260. package/template/apps/api/libs/infra/shared-services/file-storage/bucket-resolver.ts +306 -0
  261. package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.factory.ts +347 -0
  262. package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.module.ts +62 -0
  263. package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.service.ts +849 -0
  264. package/template/apps/api/libs/infra/shared-services/file-storage/index.ts +57 -0
  265. package/template/apps/api/libs/infra/shared-services/file-storage/types.ts +210 -0
  266. package/template/apps/api/libs/infra/shared-services/ip-info/index.ts +2 -0
  267. package/template/apps/api/libs/infra/shared-services/ip-info/ip-info.module.ts +18 -0
  268. package/template/apps/api/libs/infra/shared-services/ip-info/ip-info.service.ts +118 -0
  269. package/template/apps/api/libs/infra/shared-services/sms/index.ts +11 -0
  270. package/template/apps/api/libs/infra/shared-services/sms/sms.factory.ts +367 -0
  271. package/template/apps/api/libs/infra/shared-services/sms/sms.module.ts +27 -0
  272. package/template/apps/api/libs/infra/shared-services/sms/sms.service.ts +315 -0
  273. package/template/apps/api/libs/infra/shared-services/sms/types.ts +297 -0
  274. package/template/apps/api/libs/infra/shared-services/streaming-asr/index.ts +50 -0
  275. package/template/apps/api/libs/infra/shared-services/streaming-asr/streaming-asr.module.ts +47 -0
  276. package/template/apps/api/libs/infra/shared-services/streaming-asr/streaming-asr.service.ts +1336 -0
  277. package/template/apps/api/libs/infra/shared-services/streaming-asr/types.ts +208 -0
  278. package/template/apps/api/libs/infra/shared-services/system-health/index.ts +3 -0
  279. package/template/apps/api/libs/infra/shared-services/system-health/system-health.controller.ts +61 -0
  280. package/template/apps/api/libs/infra/shared-services/system-health/system-health.module.ts +16 -0
  281. package/template/apps/api/libs/infra/shared-services/system-health/system-health.service.ts +69 -0
  282. package/template/apps/api/libs/infra/shared-services/uploader/index.ts +2 -0
  283. package/template/apps/api/libs/infra/shared-services/uploader/uploader.module.ts +11 -0
  284. package/template/apps/api/libs/infra/shared-services/uploader/uploader.service.ts +265 -0
  285. package/template/apps/api/libs/infra/utils/array-buffer.util.ts +8 -0
  286. package/template/apps/api/libs/infra/utils/array.util.ts +3 -0
  287. package/template/apps/api/libs/infra/utils/bcrypt.util.ts +3 -0
  288. package/template/apps/api/libs/infra/utils/bigint.util.ts +3 -0
  289. package/template/apps/api/libs/infra/utils/bytes.convert.util.ts +13 -0
  290. package/template/apps/api/libs/infra/utils/crypto.util.ts +206 -0
  291. package/template/apps/api/libs/infra/utils/download.ts +21 -0
  292. package/template/apps/api/libs/infra/utils/enviroment.util.ts +130 -0
  293. package/template/apps/api/libs/infra/utils/ffmpeg.util.ts +29 -0
  294. package/template/apps/api/libs/infra/utils/file.util.ts +448 -0
  295. package/template/apps/api/libs/infra/utils/folder.util.ts +11 -0
  296. package/template/apps/api/libs/infra/utils/frame.util.ts +24 -0
  297. package/template/apps/api/libs/infra/utils/http-client.ts +133 -0
  298. package/template/apps/api/libs/infra/utils/ip.util.ts +22 -0
  299. package/template/apps/api/libs/infra/utils/json.util.ts +3 -0
  300. package/template/apps/api/libs/infra/utils/load-env.util.ts +53 -0
  301. package/template/apps/api/libs/infra/utils/logger.util.ts +121 -0
  302. package/template/apps/api/libs/infra/utils/object.util.ts +3 -0
  303. package/template/apps/api/libs/infra/utils/package.json +11 -0
  304. package/template/apps/api/libs/infra/utils/prisma-error.util.ts +397 -0
  305. package/template/apps/api/libs/infra/utils/response.ts +23 -0
  306. package/template/apps/api/libs/infra/utils/serialize.util.ts +3 -0
  307. package/template/apps/api/libs/infra/utils/string.util.ts +3 -0
  308. package/template/apps/api/libs/infra/utils/timer.util.ts +3 -0
  309. package/template/apps/api/libs/infra/utils/urlencode.util.ts +3 -0
  310. package/template/apps/api/libs/infra/utils/validate.util.ts +3 -0
  311. package/template/apps/api/nest-cli.json +25 -0
  312. package/template/apps/api/package.json +174 -0
  313. package/template/apps/api/prisma/schema.prisma +352 -0
  314. package/template/apps/api/prisma/seed.ts +30 -0
  315. package/template/apps/api/scripts/generate-db-crud.js +344 -0
  316. package/template/apps/api/scripts/insert-country-codes.ts +325 -0
  317. package/template/apps/api/scripts/link-prisma.js +44 -0
  318. package/template/apps/api/scripts/validate-api-versions.ts +273 -0
  319. package/template/apps/api/src/app.module.ts +208 -0
  320. package/template/apps/api/src/main.ts +298 -0
  321. package/template/apps/api/src/modules/health/health.controller.ts +13 -0
  322. package/template/apps/api/src/modules/health/health.module.ts +7 -0
  323. package/template/apps/api/tsconfig.build.json +4 -0
  324. package/template/apps/api/tsconfig.json +123 -0
  325. package/template/apps/web/.env.example +5 -0
  326. package/template/apps/web/app/globals.css +27 -0
  327. package/template/apps/web/app/layout.tsx +19 -0
  328. package/template/apps/web/app/page.tsx +42 -0
  329. package/template/apps/web/hooks/useAspectRatioSize.ts +187 -0
  330. package/template/apps/web/hooks/useDebouncedValue.ts +25 -0
  331. package/template/apps/web/hooks/useErrorHandler.ts +113 -0
  332. package/template/apps/web/hooks/useHotkeys.ts +251 -0
  333. package/template/apps/web/hooks/useI18nToast.ts +240 -0
  334. package/template/apps/web/hooks/useI18nValidation.ts +262 -0
  335. package/template/apps/web/hooks/useNotificationSSE.ts +270 -0
  336. package/template/apps/web/hooks/useOperationFeedback.ts +108 -0
  337. package/template/apps/web/hooks/usePerformanceMonitor.ts +105 -0
  338. package/template/apps/web/hooks/usePermissions.ts +17 -0
  339. package/template/apps/web/hooks/useTask.ts +489 -0
  340. package/template/apps/web/hooks/useVersionCheck.ts +329 -0
  341. package/template/apps/web/i18n/config.ts +50 -0
  342. package/template/apps/web/i18n/index.ts +30 -0
  343. package/template/apps/web/i18n/navigation.ts +26 -0
  344. package/template/apps/web/i18n/request.ts +50 -0
  345. package/template/apps/web/i18n/routing.ts +21 -0
  346. package/template/apps/web/i18n/types.ts +57 -0
  347. package/template/apps/web/lib/actions/auth.ts +81 -0
  348. package/template/apps/web/lib/actions/chat.ts +129 -0
  349. package/template/apps/web/lib/actions/common.ts +13 -0
  350. package/template/apps/web/lib/actions/task.ts +20 -0
  351. package/template/apps/web/lib/agent/chat-client.ts +42 -0
  352. package/template/apps/web/lib/agent/prompts.ts +43 -0
  353. package/template/apps/web/lib/analytics/components/PageTracker.tsx +137 -0
  354. package/template/apps/web/lib/analytics/hooks/usePageTracking.ts +137 -0
  355. package/template/apps/web/lib/analytics/index.ts +180 -0
  356. package/template/apps/web/lib/api/agents.ts +7 -0
  357. package/template/apps/web/lib/api/agno-chat.ts +263 -0
  358. package/template/apps/web/lib/api/auth-server.ts +244 -0
  359. package/template/apps/web/lib/api/avatar-upload.ts +96 -0
  360. package/template/apps/web/lib/api/cache-config.ts +236 -0
  361. package/template/apps/web/lib/api/client.ts +649 -0
  362. package/template/apps/web/lib/api/contracts/client.ts +336 -0
  363. package/template/apps/web/lib/api/contracts/hooks/index.ts +25 -0
  364. package/template/apps/web/lib/api/contracts/hooks/notification.ts +180 -0
  365. package/template/apps/web/lib/api/contracts/hooks/setting.ts +33 -0
  366. package/template/apps/web/lib/api/contracts/index.ts +18 -0
  367. package/template/apps/web/lib/api/contracts/server-client.ts +145 -0
  368. package/template/apps/web/lib/api/hooks/use-python-task.ts +154 -0
  369. package/template/apps/web/lib/api/queries/analytics.ts +51 -0
  370. package/template/apps/web/lib/api/queries/message.ts +75 -0
  371. package/template/apps/web/lib/api.ts +179 -0
  372. package/template/apps/web/lib/aspect-ratio.ts +10 -0
  373. package/template/apps/web/lib/audio-buffer-queue.ts +273 -0
  374. package/template/apps/web/lib/config.ts +163 -0
  375. package/template/apps/web/lib/data/industry.json +369 -0
  376. package/template/apps/web/lib/data/region.json +501 -0
  377. package/template/apps/web/lib/errors/error-handler.ts +194 -0
  378. package/template/apps/web/lib/errors/index.ts +16 -0
  379. package/template/apps/web/lib/errors/streaming-asr-errors.ts +434 -0
  380. package/template/apps/web/lib/form/index.ts +23 -0
  381. package/template/apps/web/lib/form/use-form.ts +143 -0
  382. package/template/apps/web/lib/icons-usage.md +99 -0
  383. package/template/apps/web/lib/icons.tsx +395 -0
  384. package/template/apps/web/lib/performance/monitor.ts +225 -0
  385. package/template/apps/web/lib/requests.ts +177 -0
  386. package/template/apps/web/lib/storage/index.ts +158 -0
  387. package/template/apps/web/lib/upload/api.ts +260 -0
  388. package/template/apps/web/lib/upload/batch-uploader.ts +286 -0
  389. package/template/apps/web/lib/upload/errors.ts +44 -0
  390. package/template/apps/web/lib/upload/folder-utils.ts +295 -0
  391. package/template/apps/web/lib/upload/uploader.ts +439 -0
  392. package/template/apps/web/lib/utils/reconnect.ts +223 -0
  393. package/template/apps/web/lib/utils/transcript-export.ts +321 -0
  394. package/template/apps/web/lib/version-mismatch.ts +147 -0
  395. package/template/apps/web/lib/version.ts +60 -0
  396. package/template/apps/web/next-env.d.ts +6 -0
  397. package/template/apps/web/next.config.ts +97 -0
  398. package/template/apps/web/package.json +89 -0
  399. package/template/apps/web/providers/app-provider.tsx +45 -0
  400. package/template/apps/web/providers/index.tsx +45 -0
  401. package/template/apps/web/providers/query-provider.tsx +181 -0
  402. package/template/apps/web/providers/theme-provider.tsx +26 -0
  403. package/template/apps/web/tsconfig.json +30 -0
  404. package/template/package.json +91 -0
  405. package/template/packages/config/eslint/base.js +32 -0
  406. package/template/packages/config/eslint/next.js +134 -0
  407. package/template/packages/config/eslint/react-internal.js +41 -0
  408. package/template/packages/config/eslint.config.mjs +26 -0
  409. package/template/packages/config/eslint.nestjs.config.mjs +62 -0
  410. package/template/packages/config/index.ts +2 -0
  411. package/template/packages/config/package.json +44 -0
  412. package/template/packages/config/postcss.config.mjs +8 -0
  413. package/template/packages/config/prettier.config.mjs +14 -0
  414. package/template/packages/config/tsconfig.json +19 -0
  415. package/template/packages/config/typescript/base.json +20 -0
  416. package/template/packages/config/typescript/nextjs.json +12 -0
  417. package/template/packages/config/typescript/react-library.json +8 -0
  418. package/template/packages/constants/README.md +111 -0
  419. package/template/packages/constants/package.json +25 -0
  420. package/template/packages/constants/src/index.ts +243 -0
  421. package/template/packages/constants/tsconfig.build.json +13 -0
  422. package/template/packages/constants/tsconfig.json +12 -0
  423. package/template/packages/contracts/ERROR-MIGRATION.md +179 -0
  424. package/template/packages/contracts/README.md +203 -0
  425. package/template/packages/contracts/jest.config.js +11 -0
  426. package/template/packages/contracts/package.json +60 -0
  427. package/template/packages/contracts/src/api/analytics.contract.ts +45 -0
  428. package/template/packages/contracts/src/api/download.contract.ts +66 -0
  429. package/template/packages/contracts/src/api/index.ts +12 -0
  430. package/template/packages/contracts/src/api/message.contract.ts +70 -0
  431. package/template/packages/contracts/src/api/risk-words.contract.ts +44 -0
  432. package/template/packages/contracts/src/api/setting.contract.ts +127 -0
  433. package/template/packages/contracts/src/api/sign.contract.ts +269 -0
  434. package/template/packages/contracts/src/api/sms.contract.ts +95 -0
  435. package/template/packages/contracts/src/api/system.contract.ts +52 -0
  436. package/template/packages/contracts/src/api/task.contract.ts +58 -0
  437. package/template/packages/contracts/src/api/uploader.contract.ts +93 -0
  438. package/template/packages/contracts/src/api/user.contract.ts +60 -0
  439. package/template/packages/contracts/src/api/webhook.contract.ts +73 -0
  440. package/template/packages/contracts/src/base.ts +319 -0
  441. package/template/packages/contracts/src/errors/codes.ts +55 -0
  442. package/template/packages/contracts/src/errors/domains/common.errors.ts +212 -0
  443. package/template/packages/contracts/src/errors/domains/index.ts +7 -0
  444. package/template/packages/contracts/src/errors/domains/user.errors.ts +51 -0
  445. package/template/packages/contracts/src/errors/error-response.ts +145 -0
  446. package/template/packages/contracts/src/errors/index.ts +16 -0
  447. package/template/packages/contracts/src/errors/messages.ts +240 -0
  448. package/template/packages/contracts/src/index.ts +16 -0
  449. package/template/packages/contracts/src/schemas/analytics.schema.ts +81 -0
  450. package/template/packages/contracts/src/schemas/download.schema.ts +59 -0
  451. package/template/packages/contracts/src/schemas/index.ts +18 -0
  452. package/template/packages/contracts/src/schemas/message.schema.ts +83 -0
  453. package/template/packages/contracts/src/schemas/risk-words.schema.ts +25 -0
  454. package/template/packages/contracts/src/schemas/setting.schema.ts +84 -0
  455. package/template/packages/contracts/src/schemas/sign.schema.ts +171 -0
  456. package/template/packages/contracts/src/schemas/sms.schema.ts +53 -0
  457. package/template/packages/contracts/src/schemas/sse.schema.ts +30 -0
  458. package/template/packages/contracts/src/schemas/system.schema.ts +26 -0
  459. package/template/packages/contracts/src/schemas/tag.schema.ts +65 -0
  460. package/template/packages/contracts/src/schemas/task.schema.ts +47 -0
  461. package/template/packages/contracts/src/schemas/uploader.schema.ts +121 -0
  462. package/template/packages/contracts/src/schemas/user.schema.ts +75 -0
  463. package/template/packages/contracts/src/schemas/webhook.schema.ts +72 -0
  464. package/template/packages/contracts/tsconfig.build.json +20 -0
  465. package/template/packages/contracts/tsconfig.json +12 -0
  466. package/template/packages/types/README.md +143 -0
  467. package/template/packages/types/ai.ts +30 -0
  468. package/template/packages/types/auth.ts +99 -0
  469. package/template/packages/types/common.ts +13 -0
  470. package/template/packages/types/creative.ts +68 -0
  471. package/template/packages/types/image-factory.ts +122 -0
  472. package/template/packages/types/index.ts +8 -0
  473. package/template/packages/types/package.json +21 -0
  474. package/template/packages/types/task.ts +27 -0
  475. package/template/packages/types/tsconfig.json +11 -0
  476. package/template/packages/ui/README.md +30 -0
  477. package/template/packages/ui/components.json +22 -0
  478. package/template/packages/ui/eslint.config.js +4 -0
  479. package/template/packages/ui/package.json +58 -0
  480. package/template/packages/ui/postcss.config.mjs +6 -0
  481. package/template/packages/ui/src/components/accordion.tsx +66 -0
  482. package/template/packages/ui/src/components/alert.tsx +61 -0
  483. package/template/packages/ui/src/components/avatar.tsx +57 -0
  484. package/template/packages/ui/src/components/badge.tsx +38 -0
  485. package/template/packages/ui/src/components/button.tsx +60 -0
  486. package/template/packages/ui/src/components/calendar.tsx +71 -0
  487. package/template/packages/ui/src/components/card.tsx +92 -0
  488. package/template/packages/ui/src/components/carousel.tsx +241 -0
  489. package/template/packages/ui/src/components/checkbox.tsx +32 -0
  490. package/template/packages/ui/src/components/command.tsx +184 -0
  491. package/template/packages/ui/src/components/dialog.tsx +134 -0
  492. package/template/packages/ui/src/components/dropdown-menu.tsx +257 -0
  493. package/template/packages/ui/src/components/empty.tsx +104 -0
  494. package/template/packages/ui/src/components/field.tsx +248 -0
  495. package/template/packages/ui/src/components/form.tsx +172 -0
  496. package/template/packages/ui/src/components/input-group.tsx +170 -0
  497. package/template/packages/ui/src/components/input.tsx +21 -0
  498. package/template/packages/ui/src/components/item.tsx +193 -0
  499. package/template/packages/ui/src/components/label.tsx +24 -0
  500. package/template/packages/ui/src/components/password-strength.tsx +248 -0
  501. package/template/packages/ui/src/components/popover.tsx +48 -0
  502. package/template/packages/ui/src/components/progress.tsx +35 -0
  503. package/template/packages/ui/src/components/scroll-area.tsx +48 -0
  504. package/template/packages/ui/src/components/select.tsx +190 -0
  505. package/template/packages/ui/src/components/separator.tsx +28 -0
  506. package/template/packages/ui/src/components/sheet.tsx +139 -0
  507. package/template/packages/ui/src/components/sidebar.tsx +729 -0
  508. package/template/packages/ui/src/components/skeleton.tsx +13 -0
  509. package/template/packages/ui/src/components/slider.tsx +87 -0
  510. package/template/packages/ui/src/components/sonner.tsx +40 -0
  511. package/template/packages/ui/src/components/switch.tsx +31 -0
  512. package/template/packages/ui/src/components/tabs.tsx +66 -0
  513. package/template/packages/ui/src/components/textarea.tsx +18 -0
  514. package/template/packages/ui/src/components/tooltip.tsx +61 -0
  515. package/template/packages/ui/src/hooks/use-mobile.ts +21 -0
  516. package/template/packages/ui/src/index.ts +38 -0
  517. package/template/packages/ui/src/lib/utils.ts +6 -0
  518. package/template/packages/ui/src/styles/globals.css +134 -0
  519. package/template/packages/ui/tsconfig.json +11 -0
  520. package/template/packages/ui/tsconfig.lint.json +8 -0
  521. package/template/packages/utils/README.md +173 -0
  522. package/template/packages/utils/array.util.ts +335 -0
  523. package/template/packages/utils/bcrypt.util.ts +10 -0
  524. package/template/packages/utils/bigint.util.ts +111 -0
  525. package/template/packages/utils/cn.ts +6 -0
  526. package/template/packages/utils/encrypt.ts +104 -0
  527. package/template/packages/utils/fetch.ts +170 -0
  528. package/template/packages/utils/file.ts +275 -0
  529. package/template/packages/utils/headers.ts +116 -0
  530. package/template/packages/utils/index.ts +22 -0
  531. package/template/packages/utils/jest.config.js +28 -0
  532. package/template/packages/utils/json.util.ts +9 -0
  533. package/template/packages/utils/mask.util.ts +348 -0
  534. package/template/packages/utils/object.util.ts +149 -0
  535. package/template/packages/utils/package.json +112 -0
  536. package/template/packages/utils/serialize.util.ts +17 -0
  537. package/template/packages/utils/string.util.ts +159 -0
  538. package/template/packages/utils/timer.util.ts +210 -0
  539. package/template/packages/utils/tsconfig.build.json +17 -0
  540. package/template/packages/utils/tsconfig.json +13 -0
  541. package/template/packages/utils/urlencode.util.ts +18 -0
  542. package/template/packages/utils/validate.util.ts +25 -0
  543. package/template/packages/validators/README.md +149 -0
  544. package/template/packages/validators/jest.config.js +20 -0
  545. package/template/packages/validators/package.json +32 -0
  546. package/template/packages/validators/src/index.ts +178 -0
  547. package/template/packages/validators/tsconfig.build.json +19 -0
  548. package/template/packages/validators/tsconfig.json +12 -0
  549. package/template/pnpm-lock.yaml +21574 -0
  550. package/template/pnpm-workspace.yaml +4 -0
  551. package/template/scripts/generate-i18n-errors.ts +371 -0
  552. package/template/scripts/generate-prisma-enums.js +170 -0
  553. package/template/scripts/generate-prisma-enums.ts +172 -0
  554. package/template/scripts/init-project.js +232 -0
  555. package/template/turbo.json +55 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true,
5
+ "outDir": "../../dist/libs/redis"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
9
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Transaction Module
3
+ * 事务模块导出
4
+ */
5
+
6
+ export { TransactionModule } from './transaction.module';
7
+ export { UnitOfWorkService } from './unit-of-work.service';
8
+ export type { TransactionOptions } from './unit-of-work.service';
9
+ export {
10
+ getTransactionClient,
11
+ runInTransactionContext,
12
+ isInTransaction,
13
+ } from './transaction-context';
14
+ export { TransactionalServiceBase } from './transactional-service.base';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Transaction Context
3
+ * 事务上下文管理
4
+ *
5
+ * 使用 AsyncLocalStorage 在调用链中传递事务客户端
6
+ * 让 db 服务层能够自动感知当前是否在事务中
7
+ */
8
+
9
+ import { AsyncLocalStorage } from 'async_hooks';
10
+ import { PrismaClient } from '@prisma/client';
11
+
12
+ /**
13
+ * Transaction context storage
14
+ * 事务上下文存储
15
+ */
16
+ const transactionContext = new AsyncLocalStorage<PrismaClient>();
17
+
18
+ /**
19
+ * Get current transaction client if in a transaction
20
+ * 获取当前事务客户端(如果在事务中)
21
+ *
22
+ * @returns Transaction client or undefined
23
+ */
24
+ export function getTransactionClient(): PrismaClient | undefined {
25
+ return transactionContext.getStore();
26
+ }
27
+
28
+ /**
29
+ * Run callback with transaction context
30
+ * 在事务上下文中运行回调
31
+ *
32
+ * @param tx - Transaction client
33
+ * @param callback - Callback function
34
+ * @returns Result of callback
35
+ */
36
+ export async function runInTransactionContext<T>(
37
+ tx: PrismaClient,
38
+ callback: () => Promise<T>,
39
+ ): Promise<T> {
40
+ return transactionContext.run(tx, callback);
41
+ }
42
+
43
+ /**
44
+ * Check if currently in a transaction
45
+ * 检查当前是否在事务中
46
+ *
47
+ * @returns True if in transaction
48
+ */
49
+ export function isInTransaction(): boolean {
50
+ return transactionContext.getStore() !== undefined;
51
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Transaction Module
3
+ * 事务模块
4
+ */
5
+
6
+ import { Module } from '@nestjs/common';
7
+ import { UnitOfWorkService } from './unit-of-work.service';
8
+ import { PrismaModule } from '@/prisma/prisma.module';
9
+
10
+ @Module({
11
+ imports: [PrismaModule],
12
+ providers: [UnitOfWorkService],
13
+ exports: [UnitOfWorkService],
14
+ })
15
+ export class TransactionModule {}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Transaction Performance Tests
3
+ * 事务性能测试
4
+ *
5
+ * 验证事务管理的性能开销和正确性
6
+ *
7
+ * 注意:这些测试使用纯 JavaScript 模拟,不依赖完整的 NestJS/Prisma 运行时
8
+ */
9
+
10
+ import { AsyncLocalStorage } from 'async_hooks';
11
+
12
+ /**
13
+ * 模拟 AsyncLocalStorage 性能测试
14
+ */
15
+ describe('AsyncLocalStorage Performance', () => {
16
+ const als = new AsyncLocalStorage<{ txClient: object }>();
17
+
18
+ it('should have minimal overhead for context operations', () => {
19
+ const iterations = 10000;
20
+ const times: number[] = [];
21
+
22
+ for (let i = 0; i < iterations; i++) {
23
+ const start = performance.now();
24
+
25
+ // 模拟 runInTransactionContext
26
+ als.run({ txClient: {} }, () => {
27
+ // 模拟 getTransactionClient
28
+ const store = als.getStore();
29
+ return store?.txClient;
30
+ });
31
+
32
+ times.push(performance.now() - start);
33
+ }
34
+
35
+ const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
36
+ const p99Time = times.sort((a, b) => a - b)[Math.floor(iterations * 0.99)];
37
+
38
+ console.log(`AsyncLocalStorage Performance (${iterations} iterations):`);
39
+ console.log(` - Average: ${(avgTime * 1000).toFixed(2)}μs`);
40
+ console.log(` - P99: ${(p99Time * 1000).toFixed(2)}μs`);
41
+
42
+ // AsyncLocalStorage 操作应该 < 0.1ms
43
+ expect(avgTime).toBeLessThan(0.1);
44
+ });
45
+
46
+ it('should handle nested context correctly', () => {
47
+ let outerValue: object | undefined;
48
+ let innerValue: object | undefined;
49
+
50
+ const outerCtx = { txClient: { id: 'outer' } };
51
+ const innerCtx = { txClient: { id: 'inner' } };
52
+
53
+ als.run(outerCtx, () => {
54
+ outerValue = als.getStore()?.txClient;
55
+
56
+ // 嵌套上下文不应该覆盖外层
57
+ als.run(innerCtx, () => {
58
+ innerValue = als.getStore()?.txClient;
59
+ });
60
+
61
+ // 退出嵌套后应该恢复外层
62
+ expect(als.getStore()?.txClient).toBe(outerCtx.txClient);
63
+ });
64
+
65
+ expect(outerValue).toBe(outerCtx.txClient);
66
+ expect(innerValue).toBe(innerCtx.txClient);
67
+ });
68
+ });
69
+
70
+ /**
71
+ * 模拟 Symbol 事务存储性能测试
72
+ */
73
+ describe('Symbol Transaction Storage Performance', () => {
74
+ const TX_CLIENT = Symbol('TX_CLIENT');
75
+
76
+ it('should have minimal overhead for symbol operations', () => {
77
+ const iterations = 10000;
78
+ const times: number[] = [];
79
+ const context: Record<symbol, object> = {};
80
+ const mockClient = { id: 'mock-tx' };
81
+
82
+ for (let i = 0; i < iterations; i++) {
83
+ const start = performance.now();
84
+
85
+ // 模拟 setTransactionClient
86
+ context[TX_CLIENT] = mockClient;
87
+
88
+ // 模拟 getTransactionClient
89
+ const client = context[TX_CLIENT];
90
+
91
+ // 模拟 clearTransactionClient
92
+ delete context[TX_CLIENT];
93
+
94
+ times.push(performance.now() - start);
95
+ }
96
+
97
+ const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
98
+ const p99Time = times.sort((a, b) => a - b)[Math.floor(iterations * 0.99)];
99
+
100
+ console.log(`Symbol Storage Performance (${iterations} iterations):`);
101
+ console.log(` - Average: ${(avgTime * 1000).toFixed(2)}μs`);
102
+ console.log(` - P99: ${(p99Time * 1000).toFixed(2)}μs`);
103
+
104
+ // Symbol 操作应该 < 0.01ms
105
+ expect(avgTime).toBeLessThan(0.01);
106
+ });
107
+ });
108
+
109
+ /**
110
+ * 模拟 @Transactional 装饰器开销测试
111
+ */
112
+ describe('Transactional Decorator Overhead', () => {
113
+ const TX_CLIENT = Symbol('TX_CLIENT');
114
+
115
+ // 模拟装饰器包装函数
116
+ function simulateTransactionalWrapper(
117
+ context: Record<symbol, object>,
118
+ originalMethod: () => Promise<unknown>,
119
+ mockTx: object,
120
+ ): () => Promise<unknown> {
121
+ return async () => {
122
+ // 检查是否已在事务中
123
+ if (context[TX_CLIENT]) {
124
+ return originalMethod();
125
+ }
126
+
127
+ const startTime = Date.now();
128
+
129
+ try {
130
+ // 模拟 $transaction
131
+ context[TX_CLIENT] = mockTx;
132
+ const result = await originalMethod();
133
+ return result;
134
+ } finally {
135
+ delete context[TX_CLIENT];
136
+ const duration = Date.now() - startTime;
137
+ // 模拟日志(生产环境下条件日志)
138
+ if (process.env.NODE_ENV === 'dev' || duration > 1000) {
139
+ // console.log 在生产环境下被跳过
140
+ }
141
+ }
142
+ };
143
+ }
144
+
145
+ it('should have minimal wrapper overhead', async () => {
146
+ const iterations = 1000;
147
+ const times: number[] = [];
148
+ const context: Record<symbol, object> = {};
149
+ const mockTx = { id: 'mock-tx' };
150
+
151
+ const originalMethod = async () => {
152
+ // 模拟简单操作
153
+ return { success: true };
154
+ };
155
+
156
+ const wrappedMethod = simulateTransactionalWrapper(
157
+ context,
158
+ originalMethod,
159
+ mockTx,
160
+ );
161
+
162
+ for (let i = 0; i < iterations; i++) {
163
+ const start = performance.now();
164
+ await wrappedMethod();
165
+ times.push(performance.now() - start);
166
+ }
167
+
168
+ const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
169
+ const p99Time = times.sort((a, b) => a - b)[Math.floor(iterations * 0.99)];
170
+
171
+ console.log(`Decorator Wrapper Performance (${iterations} iterations):`);
172
+ console.log(` - Average: ${avgTime.toFixed(3)}ms`);
173
+ console.log(` - P99: ${p99Time.toFixed(3)}ms`);
174
+
175
+ // 装饰器包装开销应该 < 1ms
176
+ expect(avgTime).toBeLessThan(1);
177
+ });
178
+
179
+ it('should skip transaction creation for nested calls', async () => {
180
+ const context: Record<symbol, object> = {};
181
+ const mockTx = { id: 'mock-tx' };
182
+ let transactionCreated = 0;
183
+
184
+ const createTransaction = async () => {
185
+ transactionCreated++;
186
+ context[TX_CLIENT] = mockTx;
187
+ };
188
+
189
+ const wrappedMethod = async () => {
190
+ if (!context[TX_CLIENT]) {
191
+ await createTransaction();
192
+ }
193
+ // 嵌套调用
194
+ if (!context[TX_CLIENT]) {
195
+ await createTransaction();
196
+ }
197
+ };
198
+
199
+ await wrappedMethod();
200
+
201
+ // 应该只创建一次事务
202
+ expect(transactionCreated).toBe(1);
203
+ });
204
+ });
205
+
206
+ /**
207
+ * 性能基准目标
208
+ */
209
+ describe('Performance Benchmarks Summary', () => {
210
+ it('should document performance targets', () => {
211
+ const targets = {
212
+ asyncLocalStorageOverhead: '< 0.1ms per operation',
213
+ symbolStorageOverhead: '< 0.01ms per operation',
214
+ decoratorWrapperOverhead: '< 1ms per transaction',
215
+ nestedTransactionDetection: '< 0.01ms',
216
+ totalTransactionOverhead: '< 5ms (excluding DB operations)',
217
+ };
218
+
219
+ console.log('\n=== Transaction Performance Targets ===');
220
+ Object.entries(targets).forEach(([key, value]) => {
221
+ console.log(` ${key}: ${value}`);
222
+ });
223
+
224
+ expect(true).toBe(true);
225
+ });
226
+ });
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Transactional Service Base
3
+ * 事务感知服务基类
4
+ *
5
+ * 所有 db 服务层应该继承此基类,以支持事务上下文
6
+ * 自动检测是否在事务中,如果在事务中则使用事务客户端,否则使用常规客户端
7
+ *
8
+ * 支持两种事务方式:
9
+ * 1. @Transactional 装饰器(使用 Symbol 存储,适合单个服务内部事务)
10
+ * 2. UnitOfWorkService(使用 AsyncLocalStorage,适合跨服务事务)
11
+ *
12
+ * 两种方式可以协同工作,服务层会自动检测并使用正确的事务客户端
13
+ */
14
+
15
+ import { PrismaClient } from '@prisma/client';
16
+ import { PrismaService } from '@app/prisma';
17
+ import {
18
+ getTransactionClient as getAsyncTransactionClient,
19
+ isInTransaction as isInAsyncTransaction,
20
+ } from './transaction-context';
21
+ import { getTransactionClient as getSymbolTransactionClient } from '@/decorators/transaction/transactional.decorator';
22
+
23
+ /**
24
+ * Base class for transactional services
25
+ * 事务感知服务基类
26
+ */
27
+ export abstract class TransactionalServiceBase {
28
+ constructor(protected readonly prisma: PrismaService) {}
29
+
30
+ /**
31
+ * Get write client (transaction-aware)
32
+ * 获取写客户端(事务感知)
33
+ *
34
+ * 优先使用 AsyncLocalStorage 中的事务客户端(UnitOfWorkService)
35
+ * 其次使用 Symbol 中的事务客户端(@Transactional 装饰器)
36
+ * 最后使用常规写客户端
37
+ *
38
+ * Returns transaction client if in a transaction,
39
+ * otherwise returns regular write client.
40
+ */
41
+ protected getWriteClient(): PrismaClient {
42
+ // 1. 优先检查 AsyncLocalStorage(UnitOfWorkService)
43
+ const asyncTxClient = getAsyncTransactionClient();
44
+ if (asyncTxClient) {
45
+ return asyncTxClient;
46
+ }
47
+
48
+ // 2. 检查 Symbol(@Transactional 装饰器)
49
+ const symbolTxClient = getSymbolTransactionClient(this);
50
+ if (symbolTxClient) {
51
+ return symbolTxClient;
52
+ }
53
+
54
+ // 3. 使用常规写客户端
55
+ return this.prisma.write;
56
+ }
57
+
58
+ /**
59
+ * Get read client
60
+ * 获取读客户端
61
+ *
62
+ * Note: In transaction, read operations should also use write client
63
+ * to ensure consistency (read-after-write)
64
+ */
65
+ protected getReadClient(): PrismaClient {
66
+ // 如果在事务中,使用事务客户端以确保读取一致性
67
+ // 如果不在事务中,使用读客户端
68
+
69
+ // 1. 优先检查 AsyncLocalStorage(UnitOfWorkService)
70
+ const asyncTxClient = getAsyncTransactionClient();
71
+ if (asyncTxClient) {
72
+ return asyncTxClient;
73
+ }
74
+
75
+ // 2. 检查 Symbol(@Transactional 装饰器)
76
+ const symbolTxClient = getSymbolTransactionClient(this);
77
+ if (symbolTxClient) {
78
+ return symbolTxClient;
79
+ }
80
+
81
+ // 3. 使用常规读客户端
82
+ return this.prisma.read;
83
+ }
84
+
85
+ /**
86
+ * Check if currently in a transaction
87
+ * 检查当前是否在事务中
88
+ */
89
+ protected isInTransaction(): boolean {
90
+ // 检查 AsyncLocalStorage
91
+ if (isInAsyncTransaction()) {
92
+ return true;
93
+ }
94
+
95
+ // 检查 Symbol
96
+ if (getSymbolTransactionClient(this)) {
97
+ return true;
98
+ }
99
+
100
+ return false;
101
+ }
102
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Unit of Work Service
3
+ * 工作单元服务 - 统一管理跨服务事务
4
+ *
5
+ * 职责:
6
+ * 1. 提供统一的事务管理接口
7
+ * 2. 支持跨多个 db 服务的事务操作
8
+ * 3. 自动处理事务的提交和回滚
9
+ * 4. 支持嵌套事务检测
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * @Injectable()
14
+ * export class SignService {
15
+ * constructor(
16
+ * private readonly uow: UnitOfWorkService,
17
+ * private readonly userService: UserService,
18
+ * ) {}
19
+ *
20
+ * async createAccount(data: CreateAccountDto) {
21
+ * return await this.uow.execute(async () => {
22
+ * // 在事务中调用服务层方法,服务层会自动使用事务客户端
23
+ * const user = await this.userService.createUser(data);
24
+ * return { user };
25
+ * });
26
+ * }
27
+ * }
28
+ * ```
29
+ */
30
+
31
+ import { Injectable } from '@nestjs/common';
32
+ import { PrismaClient } from '@prisma/client';
33
+ import { PrismaService } from '@app/prisma';
34
+ import { runInTransactionContext } from './transaction-context';
35
+
36
+ /**
37
+ * Transaction options
38
+ * 事务选项
39
+ */
40
+ export interface TransactionOptions {
41
+ maxWait?: number;
42
+ timeout?: number;
43
+ isolationLevel?:
44
+ | 'ReadUncommitted'
45
+ | 'ReadCommitted'
46
+ | 'RepeatableRead'
47
+ | 'Serializable';
48
+ }
49
+
50
+ /**
51
+ * Unit of Work Service
52
+ * 工作单元服务
53
+ */
54
+ @Injectable()
55
+ export class UnitOfWorkService {
56
+ constructor(private readonly prisma: PrismaService) {}
57
+
58
+ /**
59
+ * Execute a callback within a transaction
60
+ * 在事务中执行回调
61
+ *
62
+ * 使用 AsyncLocalStorage 在调用链中传递事务客户端
63
+ * db 服务层会自动检测并使用事务客户端
64
+ *
65
+ * @param callback - Callback function (no need to pass tx parameter)
66
+ * @param options - Transaction options
67
+ * @returns Result of the callback
68
+ */
69
+ async execute<T>(
70
+ callback: () => Promise<T>,
71
+ options?: TransactionOptions,
72
+ ): Promise<T> {
73
+ return await this.prisma.write.$transaction(async (tx) => {
74
+ // 在事务上下文中运行回调
75
+ // db 服务层会自动通过 getTransactionClient() 获取事务客户端
76
+ return await runInTransactionContext(
77
+ tx as unknown as PrismaClient,
78
+ callback,
79
+ );
80
+ }, options);
81
+ }
82
+
83
+ /**
84
+ * Execute with retry on deadlock/conflict
85
+ * 在死锁/冲突时重试执行
86
+ *
87
+ * @param callback - Callback function
88
+ * @param options - Transaction options with retry config
89
+ * @returns Result of the callback
90
+ */
91
+ async executeWithRetry<T>(
92
+ callback: () => Promise<T>,
93
+ options?: TransactionOptions & {
94
+ maxRetries?: number;
95
+ retryDelay?: number;
96
+ },
97
+ ): Promise<T> {
98
+ const maxRetries = options?.maxRetries ?? 3;
99
+ const retryDelay = options?.retryDelay ?? 100;
100
+ const { maxRetries: _, retryDelay: __, ...txOptions } = options || {};
101
+
102
+ let lastError: Error | undefined;
103
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
104
+ try {
105
+ return await this.execute(callback, txOptions);
106
+ } catch (error) {
107
+ lastError = error as Error;
108
+ if (this.isRetryableError(error) && attempt < maxRetries) {
109
+ await this.sleep(retryDelay * Math.pow(2, attempt));
110
+ continue;
111
+ }
112
+ throw error;
113
+ }
114
+ }
115
+ throw lastError || new Error('Transaction failed after max retries');
116
+ }
117
+
118
+ /**
119
+ * Check if error is retryable
120
+ * 检查错误是否可重试
121
+ */
122
+ private isRetryableError(error: unknown): boolean {
123
+ if (!error || typeof error !== 'object') return false;
124
+
125
+ const prismaCode = (error as { code?: string }).code;
126
+ const retryableCodes = ['P2034', 'P2028', '40001', '40P01'];
127
+ if (prismaCode && retryableCodes.includes(prismaCode)) {
128
+ return true;
129
+ }
130
+
131
+ const message = (error as { message?: string }).message || '';
132
+ return retryableCodes.some((code) => message.includes(code));
133
+ }
134
+
135
+ /**
136
+ * Sleep for specified milliseconds
137
+ * 睡眠指定毫秒数
138
+ */
139
+ private sleep(ms: number): Promise<void> {
140
+ return new Promise((resolve) => setTimeout(resolve, ms));
141
+ }
142
+ }
@@ -0,0 +1,87 @@
1
+ import { z } from 'zod';
2
+
3
+ // ============================================================================
4
+ // Email Configuration Schemas
5
+ // ============================================================================
6
+
7
+ export const EmailKeysSchema = z.object({
8
+ accessKey: z.string(),
9
+ accessSecret: z.string(),
10
+ host: z.string(),
11
+ port: z.number(),
12
+ secure: z.boolean(),
13
+ user: z.string(),
14
+ pass: z.string(),
15
+ });
16
+
17
+ export const EmailTemplateSchema = z.object({
18
+ name: z.string(),
19
+ subject: z.string(),
20
+ from: z.string(),
21
+ templateInvokeName: z.string(),
22
+ codeExpire: z.number().optional(),
23
+ frequency: z.number().optional(),
24
+ sub: z.record(z.string()).nullable().optional(),
25
+ });
26
+
27
+ export const EmailConfigSchema = z.object({
28
+ vendor: z.string(),
29
+ apiUser: z.string(),
30
+ apiKey: z.string(),
31
+ domain: z.string(),
32
+ name: z.string(),
33
+ templates: z.array(EmailTemplateSchema),
34
+ });
35
+
36
+ // ============================================================================
37
+ // Email Message Schemas
38
+ // ============================================================================
39
+
40
+ export const EmailSubValuesSchema = z.object({
41
+ name: z.string(),
42
+ code: z.string(),
43
+ });
44
+
45
+ export const SignalMessageSchema = z.object({
46
+ to: z.string().email(),
47
+ subject: z.string().optional(),
48
+ templateInvokeName: z.string(),
49
+ sub: z.record(z.array(z.string())),
50
+ options: z.any().optional(),
51
+ queueMailId: z.string().optional(),
52
+ metadata: z.record(z.any()).optional(),
53
+ });
54
+
55
+ // ============================================================================
56
+ // Email Account Schemas
57
+ // ============================================================================
58
+
59
+ export const EmailAccountSchema = z.object({
60
+ email: z.string().email(),
61
+ name: z.string(),
62
+ });
63
+
64
+ export const EmailAccountInputSchema = EmailAccountSchema.partial();
65
+
66
+ // ============================================================================
67
+ // Type Exports
68
+ // ============================================================================
69
+
70
+ export type EmailKeys = z.infer<typeof EmailKeysSchema>;
71
+ export type EmailTemplate = z.infer<typeof EmailTemplateSchema>;
72
+ export type EmailConfig = z.infer<typeof EmailConfigSchema>;
73
+ export type EmailSubValues = z.infer<typeof EmailSubValuesSchema>;
74
+ export type SignalMessage = z.infer<typeof SignalMessageSchema>;
75
+ export type EmailAccount = z.infer<typeof EmailAccountSchema>;
76
+
77
+ // ============================================================================
78
+ // Legacy Namespace (for backward compatibility)
79
+ // ============================================================================
80
+
81
+ export namespace PardxEmailSender {
82
+ export type EmailKeys = z.infer<typeof EmailKeysSchema>;
83
+ export type Config = z.infer<typeof EmailConfigSchema>;
84
+ export type SignalMessage = z.infer<typeof SignalMessageSchema>;
85
+ export type RegisterEmailSub = z.infer<typeof EmailSubValuesSchema>;
86
+ export type EmailTemplate = z.infer<typeof EmailTemplateSchema>;
87
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Email Service Module
3
+ *
4
+ * 职责:提供邮件发送的业务逻辑服务
5
+ */
6
+ import { Module } from '@nestjs/common';
7
+ import { ConfigModule } from '@nestjs/config';
8
+ import { HttpModule } from '@nestjs/axios';
9
+ import { RedisModule } from '@app/redis';
10
+ import { RabbitmqModule } from '@app/rabbitmq';
11
+ import { VerifyModule } from '@app/clients/internal/verify';
12
+ import { SystemTaskQueueModule } from '@app/db';
13
+ import { EmailService } from './email.service';
14
+
15
+ @Module({
16
+ imports: [
17
+ ConfigModule,
18
+ HttpModule,
19
+ RedisModule,
20
+ RabbitmqModule,
21
+ VerifyModule,
22
+ SystemTaskQueueModule,
23
+ ],
24
+ providers: [EmailService],
25
+ exports: [EmailService],
26
+ })
27
+ export class EmailServiceModule {}