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.
- package/README.md +45 -0
- package/cli.js +104 -0
- package/package.json +15 -0
- package/template/.cursorrules +479 -0
- package/template/.prettierignore +29 -0
- package/template/.prettierrc +11 -0
- package/template/.vscode/extensions.json +8 -0
- package/template/.vscode/settings.json +122 -0
- package/template/CLAUDE.md +762 -0
- package/template/README.md +125 -0
- package/template/apps/api/.env.example +11 -0
- package/template/apps/api/.eslintrc.js +222 -0
- package/template/apps/api/config.local.yaml +397 -0
- package/template/apps/api/libs/domain/auth/package.json +11 -0
- package/template/apps/api/libs/domain/auth/src/README.md +189 -0
- package/template/apps/api/libs/domain/auth/src/auth-validation.service.ts +37 -0
- package/template/apps/api/libs/domain/auth/src/auth.guard.ts +173 -0
- package/template/apps/api/libs/domain/auth/src/auth.module.ts +23 -0
- package/template/apps/api/libs/domain/auth/src/auth.service.ts +198 -0
- package/template/apps/api/libs/domain/auth/src/auth.ts +66 -0
- package/template/apps/api/libs/domain/auth/src/decorators/presets.decorator.ts +50 -0
- package/template/apps/api/libs/domain/auth/src/decorators/rbac.decorator.ts +67 -0
- package/template/apps/api/libs/domain/auth/src/decorators/resource-owner.decorator.ts +67 -0
- package/template/apps/api/libs/domain/auth/src/dto/auth.dto.ts +10 -0
- package/template/apps/api/libs/domain/auth/src/guards/streaming-asr-session.guard.ts +179 -0
- package/template/apps/api/libs/domain/auth/src/index.ts +12 -0
- package/template/apps/api/libs/domain/auth/src/types/auth.interface.ts +52 -0
- package/template/apps/api/libs/domain/auth/tsconfig.lib.json +9 -0
- package/template/apps/api/libs/domain/db/package.json +11 -0
- package/template/apps/api/libs/domain/db/src/index.ts +14 -0
- package/template/apps/api/libs/domain/db/src/modules/country-code/country-code.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/country-code/country-code.service.ts +140 -0
- package/template/apps/api/libs/domain/db/src/modules/country-code/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/discord-auth/discord-auth.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/discord-auth/discord-auth.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/discord-auth/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/email-auth/email-auth.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/email-auth/email-auth.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/email-auth/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/file-source/file-source.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/file-source/file-source.service.ts +109 -0
- package/template/apps/api/libs/domain/db/src/modules/file-source/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/google-auth/google-auth.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/google-auth/google-auth.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/google-auth/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/message/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/message/message.module.ts +10 -0
- package/template/apps/api/libs/domain/db/src/modules/message/message.service.ts +314 -0
- package/template/apps/api/libs/domain/db/src/modules/mobile-auth/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/mobile-auth/mobile-auth.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/mobile-auth/mobile-auth.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/risk-detection-record.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/risk-detection-record/risk-detection-record.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/system-task-queue/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/system-task-queue/system-task-queue.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/system-task-queue/system-task-queue.service.ts +101 -0
- package/template/apps/api/libs/domain/db/src/modules/user-info/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/user-info/user-info.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/user-info/user-info.service.ts +139 -0
- package/template/apps/api/libs/domain/db/src/modules/wechat-auth/index.ts +2 -0
- package/template/apps/api/libs/domain/db/src/modules/wechat-auth/wechat-auth.module.ts +12 -0
- package/template/apps/api/libs/domain/db/src/modules/wechat-auth/wechat-auth.service.ts +101 -0
- package/template/apps/api/libs/domain/db/tsconfig.lib.json +9 -0
- package/template/apps/api/libs/infra/clients/internal/ai/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/ai/risk-detection.client.ts +301 -0
- package/template/apps/api/libs/infra/clients/internal/ai/risk-detection.module.ts +22 -0
- package/template/apps/api/libs/infra/clients/internal/crypt/crypt-client.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/clients/internal/crypt/crypt.client.ts +37 -0
- package/template/apps/api/libs/infra/clients/internal/crypt/crypt.module.ts +10 -0
- package/template/apps/api/libs/infra/clients/internal/crypt/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/email/dto/email.dto.ts +75 -0
- package/template/apps/api/libs/infra/clients/internal/email/index.ts +11 -0
- package/template/apps/api/libs/infra/clients/internal/email/sendcloud.client.ts +400 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/README.md +255 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/dto/file-cdn.dto.ts +96 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn-client.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn.client.ts +620 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/file-cdn.module.ts +19 -0
- package/template/apps/api/libs/infra/clients/internal/file-cdn/index.ts +40 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/config/file.config.ts +14 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/dto/file.dto.ts +127 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-gcs.client.ts +154 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-qiniu.client.ts +729 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-s3.client.ts +1097 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-storage.interface.ts +114 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-tos.client.ts +767 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/file-us3.client.ts +176 -0
- package/template/apps/api/libs/infra/clients/internal/file-storage/index.ts +16 -0
- package/template/apps/api/libs/infra/clients/internal/ocr/dto/ocr.dto.ts +61 -0
- package/template/apps/api/libs/infra/clients/internal/ocr/index.ts +3 -0
- package/template/apps/api/libs/infra/clients/internal/ocr/ocr.client.ts +123 -0
- package/template/apps/api/libs/infra/clients/internal/ocr/ocr.module.ts +15 -0
- package/template/apps/api/libs/infra/clients/internal/openai/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/openai/openai.client.ts +135 -0
- package/template/apps/api/libs/infra/clients/internal/openai/openai.module.ts +17 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/README.md +508 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/index.ts +44 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.client.ts +441 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.factory.ts +450 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/openspeech.module.ts +56 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/providers/aliyun.provider.ts +308 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/providers/base.provider.ts +114 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/providers/index.ts +10 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/providers/volcengine-streaming.provider.ts +1689 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/providers/volcengine.provider.ts +387 -0
- package/template/apps/api/libs/infra/clients/internal/openspeech/types.ts +467 -0
- package/template/apps/api/libs/infra/clients/internal/sms/dto/sms.dto.ts +97 -0
- package/template/apps/api/libs/infra/clients/internal/sms/index.ts +15 -0
- package/template/apps/api/libs/infra/clients/internal/sms/sms-aliyun.client.ts +52 -0
- package/template/apps/api/libs/infra/clients/internal/sms/sms-http.client.ts +111 -0
- package/template/apps/api/libs/infra/clients/internal/sms/sms-tencent.client.ts +54 -0
- package/template/apps/api/libs/infra/clients/internal/sms/sms-volcengine.client.ts +165 -0
- package/template/apps/api/libs/infra/clients/internal/sms/sms-zxjc.client.ts +47 -0
- package/template/apps/api/libs/infra/clients/internal/sse/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/sse/sse-client.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/clients/internal/sse/sse.client.ts +360 -0
- package/template/apps/api/libs/infra/clients/internal/sse/sse.module.ts +17 -0
- package/template/apps/api/libs/infra/clients/internal/third-party-sse/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.client.ts +51 -0
- package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.module.ts +10 -0
- package/template/apps/api/libs/infra/clients/internal/third-party-sse/third-party-sse.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/clients/internal/verify/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/verify/verify.client.ts +42 -0
- package/template/apps/api/libs/infra/clients/internal/verify/verify.module.ts +10 -0
- package/template/apps/api/libs/infra/clients/internal/volcengine-tts/dto/tts.dto.ts +64 -0
- package/template/apps/api/libs/infra/clients/internal/volcengine-tts/index.ts +3 -0
- package/template/apps/api/libs/infra/clients/internal/volcengine-tts/volcengine-tts.client.ts +846 -0
- package/template/apps/api/libs/infra/clients/internal/volcengine-tts/volcengine-tts.module.ts +21 -0
- package/template/apps/api/libs/infra/clients/internal/wechat/index.ts +2 -0
- package/template/apps/api/libs/infra/clients/internal/wechat/wechat-client.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/clients/internal/wechat/wechat.client.ts +4 -0
- package/template/apps/api/libs/infra/clients/internal/wechat/wechat.module.ts +8 -0
- package/template/apps/api/libs/infra/clients/plugin/decorators/inject-client.decorator.ts +60 -0
- package/template/apps/api/libs/infra/clients/plugin/index.ts +21 -0
- package/template/apps/api/libs/infra/clients/plugin/interceptors/http-logging.interceptor.ts +130 -0
- package/template/apps/api/libs/infra/clients/plugin/interfaces/client.interface.ts +86 -0
- package/template/apps/api/libs/infra/clients/plugin/utils/retry.util.ts +157 -0
- package/template/apps/api/libs/infra/common/adapters/base.adapter.ts +94 -0
- package/template/apps/api/libs/infra/common/adapters/index.ts +38 -0
- package/template/apps/api/libs/infra/common/config/README.md +254 -0
- package/template/apps/api/libs/infra/common/config/agentx.config.ts +91 -0
- package/template/apps/api/libs/infra/common/config/configuration.ts +289 -0
- package/template/apps/api/libs/infra/common/config/constant/config.constants.ts +92 -0
- package/template/apps/api/libs/infra/common/config/dto/config.dto.ts +282 -0
- package/template/apps/api/libs/infra/common/config/package.json +11 -0
- package/template/apps/api/libs/infra/common/config/validation/env.validation.ts +161 -0
- package/template/apps/api/libs/infra/common/config/validation/index.ts +188 -0
- package/template/apps/api/libs/infra/common/config/validation/keys.validation.ts +564 -0
- package/template/apps/api/libs/infra/common/config/validation/yaml.validation.ts +582 -0
- package/template/apps/api/libs/infra/common/decorators/app-version/app-version.controller.ts +135 -0
- package/template/apps/api/libs/infra/common/decorators/app-version/app-version.interceptor.ts +36 -0
- package/template/apps/api/libs/infra/common/decorators/app-version/app-version.module.ts +27 -0
- package/template/apps/api/libs/infra/common/decorators/app-version/app-version.service.ts +252 -0
- package/template/apps/api/libs/infra/common/decorators/app-version/index.ts +13 -0
- package/template/apps/api/libs/infra/common/decorators/cache/cache.decorator.ts +437 -0
- package/template/apps/api/libs/infra/common/decorators/cache/cache.interceptor.ts +268 -0
- package/template/apps/api/libs/infra/common/decorators/cache/cache.module.ts +24 -0
- package/template/apps/api/libs/infra/common/decorators/cache/index.ts +33 -0
- package/template/apps/api/libs/infra/common/decorators/event/event.decorator.ts +229 -0
- package/template/apps/api/libs/infra/common/decorators/event/event.interceptor.ts +155 -0
- package/template/apps/api/libs/infra/common/decorators/event/event.module.ts +47 -0
- package/template/apps/api/libs/infra/common/decorators/event/handlers/cache-event.handler.ts +159 -0
- package/template/apps/api/libs/infra/common/decorators/event/index.ts +29 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.decorator.ts +221 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.interceptor.ts +150 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.module.ts +27 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.service.spec.ts +330 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/feature-flag.service.ts +423 -0
- package/template/apps/api/libs/infra/common/decorators/feature-flag/index.ts +28 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/dto/rate-limit.dto.ts +201 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/index.ts +54 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.decorator.ts +216 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.exception.ts +74 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.module.ts +37 -0
- package/template/apps/api/libs/infra/common/decorators/rate-limit/rate-limit.service.ts +430 -0
- package/template/apps/api/libs/infra/common/decorators/response.decorator.ts +67 -0
- package/template/apps/api/libs/infra/common/decorators/skip-version-check.decorator.ts +27 -0
- package/template/apps/api/libs/infra/common/decorators/transaction/index.ts +12 -0
- package/template/apps/api/libs/infra/common/decorators/transaction/transactional.decorator.ts +677 -0
- package/template/apps/api/libs/infra/common/decorators/ts-rest-controller.decorator.ts +63 -0
- package/template/apps/api/libs/infra/common/decorators/validation.decorator.ts +120 -0
- package/template/apps/api/libs/infra/common/decorators/version/index.ts +24 -0
- package/template/apps/api/libs/infra/common/decorators/version/version.decorator.ts +168 -0
- package/template/apps/api/libs/infra/common/decorators/version/version.interceptor.ts +97 -0
- package/template/apps/api/libs/infra/common/decorators/version/version.module.ts +21 -0
- package/template/apps/api/libs/infra/common/enums/action.enum.ts +7 -0
- package/template/apps/api/libs/infra/common/enums/error-codes.ts +71 -0
- package/template/apps/api/libs/infra/common/enums/role.enum.ts +4 -0
- package/template/apps/api/libs/infra/common/filter/exception/api.exception.ts +168 -0
- package/template/apps/api/libs/infra/common/filter/exception/exception.ts +47 -0
- package/template/apps/api/libs/infra/common/filter/exception/http.exception.ts +126 -0
- package/template/apps/api/libs/infra/common/guards/index.ts +1 -0
- package/template/apps/api/libs/infra/common/guards/version.guard.ts +312 -0
- package/template/apps/api/libs/infra/common/interceptor/mask/index.ts +1 -0
- package/template/apps/api/libs/infra/common/interceptor/mask/mask.interceptor.ts +242 -0
- package/template/apps/api/libs/infra/common/interceptor/rate-limit/no-rate-limit.interceptor.ts +14 -0
- package/template/apps/api/libs/infra/common/interceptor/rate-limit/rate-limit.interceptor.ts +230 -0
- package/template/apps/api/libs/infra/common/interceptor/transform/transform.interceptor.spec.ts +7 -0
- package/template/apps/api/libs/infra/common/interceptor/transform/transform.interceptor.ts +75 -0
- package/template/apps/api/libs/infra/common/interceptor/version/index.ts +1 -0
- package/template/apps/api/libs/infra/common/interceptor/version/version-header.interceptor.ts +62 -0
- package/template/apps/api/libs/infra/common/middleware/request.middleware.ts +109 -0
- package/template/apps/api/libs/infra/common/package.json +11 -0
- package/template/apps/api/libs/infra/common/pipes/transform-root.pipe.ts +12 -0
- package/template/apps/api/libs/infra/common/ts-rest/index.ts +26 -0
- package/template/apps/api/libs/infra/common/ts-rest/response.helper.ts +233 -0
- package/template/apps/api/libs/infra/i18n/en/errors.json +77 -0
- package/template/apps/api/libs/infra/i18n/en/events.json +1 -0
- package/template/apps/api/libs/infra/i18n/package.json +11 -0
- package/template/apps/api/libs/infra/i18n/zh-CN/errors.json +77 -0
- package/template/apps/api/libs/infra/i18n/zh-CN/events.json +1 -0
- package/template/apps/api/libs/infra/jwt/dto/jwt.dto.ts +1 -0
- package/template/apps/api/libs/infra/jwt/jwt.module.ts +26 -0
- package/template/apps/api/libs/infra/jwt/package.json +11 -0
- package/template/apps/api/libs/infra/prisma/db-metrics/package.json +11 -0
- package/template/apps/api/libs/infra/prisma/db-metrics/src/db-metrics.module.ts +141 -0
- package/template/apps/api/libs/infra/prisma/db-metrics/src/db-metrics.service.ts +456 -0
- package/template/apps/api/libs/infra/prisma/db-metrics/src/index.ts +2 -0
- package/template/apps/api/libs/infra/prisma/db-metrics/tsconfig.lib.json +9 -0
- package/template/apps/api/libs/infra/prisma/middleware/soft-delete.middleware.ts +179 -0
- package/template/apps/api/libs/infra/prisma/package.json +11 -0
- package/template/apps/api/libs/infra/prisma/prisma/index.ts +3 -0
- package/template/apps/api/libs/infra/prisma/prisma/prisma.module.ts +12 -0
- package/template/apps/api/libs/infra/prisma/prisma/prisma.service.ts +18 -0
- package/template/apps/api/libs/infra/prisma/prisma/types.ts +6 -0
- package/template/apps/api/libs/infra/prisma/prisma-read/prisma-read.module.ts +11 -0
- package/template/apps/api/libs/infra/prisma/prisma-read/prisma-read.service.ts +280 -0
- package/template/apps/api/libs/infra/prisma/prisma-write/prisma-write.module.ts +11 -0
- package/template/apps/api/libs/infra/prisma/prisma-write/prisma-write.service.ts +278 -0
- package/template/apps/api/libs/infra/prisma/prometheus/index.ts +1 -0
- package/template/apps/api/libs/infra/prisma/prometheus/prometheus.module.ts +231 -0
- package/template/apps/api/libs/infra/rabbitmq/package.json +11 -0
- package/template/apps/api/libs/infra/rabbitmq/src/dto/rabbitmq.dto.ts +13 -0
- package/template/apps/api/libs/infra/rabbitmq/src/index.ts +5 -0
- package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq-events.module.ts +132 -0
- package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq-events.service.ts +199 -0
- package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.module.ts +101 -0
- package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/rabbitmq/src/rabbitmq.service.ts +543 -0
- package/template/apps/api/libs/infra/rabbitmq/tsconfig.lib.json +9 -0
- package/template/apps/api/libs/infra/redis/dto/redis.dto.ts +3 -0
- package/template/apps/api/libs/infra/redis/package.json +11 -0
- package/template/apps/api/libs/infra/redis/src/index.ts +2 -0
- package/template/apps/api/libs/infra/redis/src/redis.module.ts +63 -0
- package/template/apps/api/libs/infra/redis/src/redis.service.spec.ts +18 -0
- package/template/apps/api/libs/infra/redis/src/redis.service.ts +730 -0
- package/template/apps/api/libs/infra/redis/tsconfig.lib.json +9 -0
- package/template/apps/api/libs/infra/shared-db/index.ts +14 -0
- package/template/apps/api/libs/infra/shared-db/transaction-context.ts +51 -0
- package/template/apps/api/libs/infra/shared-db/transaction.module.ts +15 -0
- package/template/apps/api/libs/infra/shared-db/transaction.perf.spec.ts +226 -0
- package/template/apps/api/libs/infra/shared-db/transactional-service.base.ts +102 -0
- package/template/apps/api/libs/infra/shared-db/unit-of-work.service.ts +142 -0
- package/template/apps/api/libs/infra/shared-services/email/dto/email.dto.ts +87 -0
- package/template/apps/api/libs/infra/shared-services/email/email.module.ts +27 -0
- package/template/apps/api/libs/infra/shared-services/email/email.service.ts +258 -0
- package/template/apps/api/libs/infra/shared-services/email/index.ts +5 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/README.md +376 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/bucket-resolver.ts +306 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.factory.ts +347 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.module.ts +62 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/file-storage.service.ts +849 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/index.ts +57 -0
- package/template/apps/api/libs/infra/shared-services/file-storage/types.ts +210 -0
- package/template/apps/api/libs/infra/shared-services/ip-info/index.ts +2 -0
- package/template/apps/api/libs/infra/shared-services/ip-info/ip-info.module.ts +18 -0
- package/template/apps/api/libs/infra/shared-services/ip-info/ip-info.service.ts +118 -0
- package/template/apps/api/libs/infra/shared-services/sms/index.ts +11 -0
- package/template/apps/api/libs/infra/shared-services/sms/sms.factory.ts +367 -0
- package/template/apps/api/libs/infra/shared-services/sms/sms.module.ts +27 -0
- package/template/apps/api/libs/infra/shared-services/sms/sms.service.ts +315 -0
- package/template/apps/api/libs/infra/shared-services/sms/types.ts +297 -0
- package/template/apps/api/libs/infra/shared-services/streaming-asr/index.ts +50 -0
- package/template/apps/api/libs/infra/shared-services/streaming-asr/streaming-asr.module.ts +47 -0
- package/template/apps/api/libs/infra/shared-services/streaming-asr/streaming-asr.service.ts +1336 -0
- package/template/apps/api/libs/infra/shared-services/streaming-asr/types.ts +208 -0
- package/template/apps/api/libs/infra/shared-services/system-health/index.ts +3 -0
- package/template/apps/api/libs/infra/shared-services/system-health/system-health.controller.ts +61 -0
- package/template/apps/api/libs/infra/shared-services/system-health/system-health.module.ts +16 -0
- package/template/apps/api/libs/infra/shared-services/system-health/system-health.service.ts +69 -0
- package/template/apps/api/libs/infra/shared-services/uploader/index.ts +2 -0
- package/template/apps/api/libs/infra/shared-services/uploader/uploader.module.ts +11 -0
- package/template/apps/api/libs/infra/shared-services/uploader/uploader.service.ts +265 -0
- package/template/apps/api/libs/infra/utils/array-buffer.util.ts +8 -0
- package/template/apps/api/libs/infra/utils/array.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/bcrypt.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/bigint.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/bytes.convert.util.ts +13 -0
- package/template/apps/api/libs/infra/utils/crypto.util.ts +206 -0
- package/template/apps/api/libs/infra/utils/download.ts +21 -0
- package/template/apps/api/libs/infra/utils/enviroment.util.ts +130 -0
- package/template/apps/api/libs/infra/utils/ffmpeg.util.ts +29 -0
- package/template/apps/api/libs/infra/utils/file.util.ts +448 -0
- package/template/apps/api/libs/infra/utils/folder.util.ts +11 -0
- package/template/apps/api/libs/infra/utils/frame.util.ts +24 -0
- package/template/apps/api/libs/infra/utils/http-client.ts +133 -0
- package/template/apps/api/libs/infra/utils/ip.util.ts +22 -0
- package/template/apps/api/libs/infra/utils/json.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/load-env.util.ts +53 -0
- package/template/apps/api/libs/infra/utils/logger.util.ts +121 -0
- package/template/apps/api/libs/infra/utils/object.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/package.json +11 -0
- package/template/apps/api/libs/infra/utils/prisma-error.util.ts +397 -0
- package/template/apps/api/libs/infra/utils/response.ts +23 -0
- package/template/apps/api/libs/infra/utils/serialize.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/string.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/timer.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/urlencode.util.ts +3 -0
- package/template/apps/api/libs/infra/utils/validate.util.ts +3 -0
- package/template/apps/api/nest-cli.json +25 -0
- package/template/apps/api/package.json +174 -0
- package/template/apps/api/prisma/schema.prisma +352 -0
- package/template/apps/api/prisma/seed.ts +30 -0
- package/template/apps/api/scripts/generate-db-crud.js +344 -0
- package/template/apps/api/scripts/insert-country-codes.ts +325 -0
- package/template/apps/api/scripts/link-prisma.js +44 -0
- package/template/apps/api/scripts/validate-api-versions.ts +273 -0
- package/template/apps/api/src/app.module.ts +208 -0
- package/template/apps/api/src/main.ts +298 -0
- package/template/apps/api/src/modules/health/health.controller.ts +13 -0
- package/template/apps/api/src/modules/health/health.module.ts +7 -0
- package/template/apps/api/tsconfig.build.json +4 -0
- package/template/apps/api/tsconfig.json +123 -0
- package/template/apps/web/.env.example +5 -0
- package/template/apps/web/app/globals.css +27 -0
- package/template/apps/web/app/layout.tsx +19 -0
- package/template/apps/web/app/page.tsx +42 -0
- package/template/apps/web/hooks/useAspectRatioSize.ts +187 -0
- package/template/apps/web/hooks/useDebouncedValue.ts +25 -0
- package/template/apps/web/hooks/useErrorHandler.ts +113 -0
- package/template/apps/web/hooks/useHotkeys.ts +251 -0
- package/template/apps/web/hooks/useI18nToast.ts +240 -0
- package/template/apps/web/hooks/useI18nValidation.ts +262 -0
- package/template/apps/web/hooks/useNotificationSSE.ts +270 -0
- package/template/apps/web/hooks/useOperationFeedback.ts +108 -0
- package/template/apps/web/hooks/usePerformanceMonitor.ts +105 -0
- package/template/apps/web/hooks/usePermissions.ts +17 -0
- package/template/apps/web/hooks/useTask.ts +489 -0
- package/template/apps/web/hooks/useVersionCheck.ts +329 -0
- package/template/apps/web/i18n/config.ts +50 -0
- package/template/apps/web/i18n/index.ts +30 -0
- package/template/apps/web/i18n/navigation.ts +26 -0
- package/template/apps/web/i18n/request.ts +50 -0
- package/template/apps/web/i18n/routing.ts +21 -0
- package/template/apps/web/i18n/types.ts +57 -0
- package/template/apps/web/lib/actions/auth.ts +81 -0
- package/template/apps/web/lib/actions/chat.ts +129 -0
- package/template/apps/web/lib/actions/common.ts +13 -0
- package/template/apps/web/lib/actions/task.ts +20 -0
- package/template/apps/web/lib/agent/chat-client.ts +42 -0
- package/template/apps/web/lib/agent/prompts.ts +43 -0
- package/template/apps/web/lib/analytics/components/PageTracker.tsx +137 -0
- package/template/apps/web/lib/analytics/hooks/usePageTracking.ts +137 -0
- package/template/apps/web/lib/analytics/index.ts +180 -0
- package/template/apps/web/lib/api/agents.ts +7 -0
- package/template/apps/web/lib/api/agno-chat.ts +263 -0
- package/template/apps/web/lib/api/auth-server.ts +244 -0
- package/template/apps/web/lib/api/avatar-upload.ts +96 -0
- package/template/apps/web/lib/api/cache-config.ts +236 -0
- package/template/apps/web/lib/api/client.ts +649 -0
- package/template/apps/web/lib/api/contracts/client.ts +336 -0
- package/template/apps/web/lib/api/contracts/hooks/index.ts +25 -0
- package/template/apps/web/lib/api/contracts/hooks/notification.ts +180 -0
- package/template/apps/web/lib/api/contracts/hooks/setting.ts +33 -0
- package/template/apps/web/lib/api/contracts/index.ts +18 -0
- package/template/apps/web/lib/api/contracts/server-client.ts +145 -0
- package/template/apps/web/lib/api/hooks/use-python-task.ts +154 -0
- package/template/apps/web/lib/api/queries/analytics.ts +51 -0
- package/template/apps/web/lib/api/queries/message.ts +75 -0
- package/template/apps/web/lib/api.ts +179 -0
- package/template/apps/web/lib/aspect-ratio.ts +10 -0
- package/template/apps/web/lib/audio-buffer-queue.ts +273 -0
- package/template/apps/web/lib/config.ts +163 -0
- package/template/apps/web/lib/data/industry.json +369 -0
- package/template/apps/web/lib/data/region.json +501 -0
- package/template/apps/web/lib/errors/error-handler.ts +194 -0
- package/template/apps/web/lib/errors/index.ts +16 -0
- package/template/apps/web/lib/errors/streaming-asr-errors.ts +434 -0
- package/template/apps/web/lib/form/index.ts +23 -0
- package/template/apps/web/lib/form/use-form.ts +143 -0
- package/template/apps/web/lib/icons-usage.md +99 -0
- package/template/apps/web/lib/icons.tsx +395 -0
- package/template/apps/web/lib/performance/monitor.ts +225 -0
- package/template/apps/web/lib/requests.ts +177 -0
- package/template/apps/web/lib/storage/index.ts +158 -0
- package/template/apps/web/lib/upload/api.ts +260 -0
- package/template/apps/web/lib/upload/batch-uploader.ts +286 -0
- package/template/apps/web/lib/upload/errors.ts +44 -0
- package/template/apps/web/lib/upload/folder-utils.ts +295 -0
- package/template/apps/web/lib/upload/uploader.ts +439 -0
- package/template/apps/web/lib/utils/reconnect.ts +223 -0
- package/template/apps/web/lib/utils/transcript-export.ts +321 -0
- package/template/apps/web/lib/version-mismatch.ts +147 -0
- package/template/apps/web/lib/version.ts +60 -0
- package/template/apps/web/next-env.d.ts +6 -0
- package/template/apps/web/next.config.ts +97 -0
- package/template/apps/web/package.json +89 -0
- package/template/apps/web/providers/app-provider.tsx +45 -0
- package/template/apps/web/providers/index.tsx +45 -0
- package/template/apps/web/providers/query-provider.tsx +181 -0
- package/template/apps/web/providers/theme-provider.tsx +26 -0
- package/template/apps/web/tsconfig.json +30 -0
- package/template/package.json +91 -0
- package/template/packages/config/eslint/base.js +32 -0
- package/template/packages/config/eslint/next.js +134 -0
- package/template/packages/config/eslint/react-internal.js +41 -0
- package/template/packages/config/eslint.config.mjs +26 -0
- package/template/packages/config/eslint.nestjs.config.mjs +62 -0
- package/template/packages/config/index.ts +2 -0
- package/template/packages/config/package.json +44 -0
- package/template/packages/config/postcss.config.mjs +8 -0
- package/template/packages/config/prettier.config.mjs +14 -0
- package/template/packages/config/tsconfig.json +19 -0
- package/template/packages/config/typescript/base.json +20 -0
- package/template/packages/config/typescript/nextjs.json +12 -0
- package/template/packages/config/typescript/react-library.json +8 -0
- package/template/packages/constants/README.md +111 -0
- package/template/packages/constants/package.json +25 -0
- package/template/packages/constants/src/index.ts +243 -0
- package/template/packages/constants/tsconfig.build.json +13 -0
- package/template/packages/constants/tsconfig.json +12 -0
- package/template/packages/contracts/ERROR-MIGRATION.md +179 -0
- package/template/packages/contracts/README.md +203 -0
- package/template/packages/contracts/jest.config.js +11 -0
- package/template/packages/contracts/package.json +60 -0
- package/template/packages/contracts/src/api/analytics.contract.ts +45 -0
- package/template/packages/contracts/src/api/download.contract.ts +66 -0
- package/template/packages/contracts/src/api/index.ts +12 -0
- package/template/packages/contracts/src/api/message.contract.ts +70 -0
- package/template/packages/contracts/src/api/risk-words.contract.ts +44 -0
- package/template/packages/contracts/src/api/setting.contract.ts +127 -0
- package/template/packages/contracts/src/api/sign.contract.ts +269 -0
- package/template/packages/contracts/src/api/sms.contract.ts +95 -0
- package/template/packages/contracts/src/api/system.contract.ts +52 -0
- package/template/packages/contracts/src/api/task.contract.ts +58 -0
- package/template/packages/contracts/src/api/uploader.contract.ts +93 -0
- package/template/packages/contracts/src/api/user.contract.ts +60 -0
- package/template/packages/contracts/src/api/webhook.contract.ts +73 -0
- package/template/packages/contracts/src/base.ts +319 -0
- package/template/packages/contracts/src/errors/codes.ts +55 -0
- package/template/packages/contracts/src/errors/domains/common.errors.ts +212 -0
- package/template/packages/contracts/src/errors/domains/index.ts +7 -0
- package/template/packages/contracts/src/errors/domains/user.errors.ts +51 -0
- package/template/packages/contracts/src/errors/error-response.ts +145 -0
- package/template/packages/contracts/src/errors/index.ts +16 -0
- package/template/packages/contracts/src/errors/messages.ts +240 -0
- package/template/packages/contracts/src/index.ts +16 -0
- package/template/packages/contracts/src/schemas/analytics.schema.ts +81 -0
- package/template/packages/contracts/src/schemas/download.schema.ts +59 -0
- package/template/packages/contracts/src/schemas/index.ts +18 -0
- package/template/packages/contracts/src/schemas/message.schema.ts +83 -0
- package/template/packages/contracts/src/schemas/risk-words.schema.ts +25 -0
- package/template/packages/contracts/src/schemas/setting.schema.ts +84 -0
- package/template/packages/contracts/src/schemas/sign.schema.ts +171 -0
- package/template/packages/contracts/src/schemas/sms.schema.ts +53 -0
- package/template/packages/contracts/src/schemas/sse.schema.ts +30 -0
- package/template/packages/contracts/src/schemas/system.schema.ts +26 -0
- package/template/packages/contracts/src/schemas/tag.schema.ts +65 -0
- package/template/packages/contracts/src/schemas/task.schema.ts +47 -0
- package/template/packages/contracts/src/schemas/uploader.schema.ts +121 -0
- package/template/packages/contracts/src/schemas/user.schema.ts +75 -0
- package/template/packages/contracts/src/schemas/webhook.schema.ts +72 -0
- package/template/packages/contracts/tsconfig.build.json +20 -0
- package/template/packages/contracts/tsconfig.json +12 -0
- package/template/packages/types/README.md +143 -0
- package/template/packages/types/ai.ts +30 -0
- package/template/packages/types/auth.ts +99 -0
- package/template/packages/types/common.ts +13 -0
- package/template/packages/types/creative.ts +68 -0
- package/template/packages/types/image-factory.ts +122 -0
- package/template/packages/types/index.ts +8 -0
- package/template/packages/types/package.json +21 -0
- package/template/packages/types/task.ts +27 -0
- package/template/packages/types/tsconfig.json +11 -0
- package/template/packages/ui/README.md +30 -0
- package/template/packages/ui/components.json +22 -0
- package/template/packages/ui/eslint.config.js +4 -0
- package/template/packages/ui/package.json +58 -0
- package/template/packages/ui/postcss.config.mjs +6 -0
- package/template/packages/ui/src/components/accordion.tsx +66 -0
- package/template/packages/ui/src/components/alert.tsx +61 -0
- package/template/packages/ui/src/components/avatar.tsx +57 -0
- package/template/packages/ui/src/components/badge.tsx +38 -0
- package/template/packages/ui/src/components/button.tsx +60 -0
- package/template/packages/ui/src/components/calendar.tsx +71 -0
- package/template/packages/ui/src/components/card.tsx +92 -0
- package/template/packages/ui/src/components/carousel.tsx +241 -0
- package/template/packages/ui/src/components/checkbox.tsx +32 -0
- package/template/packages/ui/src/components/command.tsx +184 -0
- package/template/packages/ui/src/components/dialog.tsx +134 -0
- package/template/packages/ui/src/components/dropdown-menu.tsx +257 -0
- package/template/packages/ui/src/components/empty.tsx +104 -0
- package/template/packages/ui/src/components/field.tsx +248 -0
- package/template/packages/ui/src/components/form.tsx +172 -0
- package/template/packages/ui/src/components/input-group.tsx +170 -0
- package/template/packages/ui/src/components/input.tsx +21 -0
- package/template/packages/ui/src/components/item.tsx +193 -0
- package/template/packages/ui/src/components/label.tsx +24 -0
- package/template/packages/ui/src/components/password-strength.tsx +248 -0
- package/template/packages/ui/src/components/popover.tsx +48 -0
- package/template/packages/ui/src/components/progress.tsx +35 -0
- package/template/packages/ui/src/components/scroll-area.tsx +48 -0
- package/template/packages/ui/src/components/select.tsx +190 -0
- package/template/packages/ui/src/components/separator.tsx +28 -0
- package/template/packages/ui/src/components/sheet.tsx +139 -0
- package/template/packages/ui/src/components/sidebar.tsx +729 -0
- package/template/packages/ui/src/components/skeleton.tsx +13 -0
- package/template/packages/ui/src/components/slider.tsx +87 -0
- package/template/packages/ui/src/components/sonner.tsx +40 -0
- package/template/packages/ui/src/components/switch.tsx +31 -0
- package/template/packages/ui/src/components/tabs.tsx +66 -0
- package/template/packages/ui/src/components/textarea.tsx +18 -0
- package/template/packages/ui/src/components/tooltip.tsx +61 -0
- package/template/packages/ui/src/hooks/use-mobile.ts +21 -0
- package/template/packages/ui/src/index.ts +38 -0
- package/template/packages/ui/src/lib/utils.ts +6 -0
- package/template/packages/ui/src/styles/globals.css +134 -0
- package/template/packages/ui/tsconfig.json +11 -0
- package/template/packages/ui/tsconfig.lint.json +8 -0
- package/template/packages/utils/README.md +173 -0
- package/template/packages/utils/array.util.ts +335 -0
- package/template/packages/utils/bcrypt.util.ts +10 -0
- package/template/packages/utils/bigint.util.ts +111 -0
- package/template/packages/utils/cn.ts +6 -0
- package/template/packages/utils/encrypt.ts +104 -0
- package/template/packages/utils/fetch.ts +170 -0
- package/template/packages/utils/file.ts +275 -0
- package/template/packages/utils/headers.ts +116 -0
- package/template/packages/utils/index.ts +22 -0
- package/template/packages/utils/jest.config.js +28 -0
- package/template/packages/utils/json.util.ts +9 -0
- package/template/packages/utils/mask.util.ts +348 -0
- package/template/packages/utils/object.util.ts +149 -0
- package/template/packages/utils/package.json +112 -0
- package/template/packages/utils/serialize.util.ts +17 -0
- package/template/packages/utils/string.util.ts +159 -0
- package/template/packages/utils/timer.util.ts +210 -0
- package/template/packages/utils/tsconfig.build.json +17 -0
- package/template/packages/utils/tsconfig.json +13 -0
- package/template/packages/utils/urlencode.util.ts +18 -0
- package/template/packages/utils/validate.util.ts +25 -0
- package/template/packages/validators/README.md +149 -0
- package/template/packages/validators/jest.config.js +20 -0
- package/template/packages/validators/package.json +32 -0
- package/template/packages/validators/src/index.ts +178 -0
- package/template/packages/validators/tsconfig.build.json +19 -0
- package/template/packages/validators/tsconfig.json +12 -0
- package/template/pnpm-lock.yaml +21574 -0
- package/template/pnpm-workspace.yaml +4 -0
- package/template/scripts/generate-i18n-errors.ts +371 -0
- package/template/scripts/generate-prisma-enums.js +170 -0
- package/template/scripts/generate-prisma-enums.ts +172 -0
- package/template/scripts/init-project.js +232 -0
- package/template/turbo.json +55 -0
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transactional Decorator
|
|
3
|
+
* 事务处理装饰器
|
|
4
|
+
*
|
|
5
|
+
* Automatically wraps method execution in a Prisma transaction.
|
|
6
|
+
* Works with the project's read/write separation architecture.
|
|
7
|
+
* Supports optional retry mechanism for deadlock and write conflict errors.
|
|
8
|
+
*
|
|
9
|
+
* 自动将方法执行包装在 Prisma 事务中。
|
|
10
|
+
* 与项目的读写分离架构配合工作。
|
|
11
|
+
* 支持可选的死锁和写冲突错误重试机制。
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* @Injectable()
|
|
16
|
+
* export class ApiService {
|
|
17
|
+
* constructor(private readonly prisma: PrismaService) {}
|
|
18
|
+
*
|
|
19
|
+
* // Basic usage
|
|
20
|
+
* @Transactional()
|
|
21
|
+
* async createWithOwner(userId: string, data: CreateInput) {
|
|
22
|
+
* const data = await this.prisma.write.create({ data });
|
|
23
|
+
* return data;
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* // With retry enabled
|
|
27
|
+
* @Transactional({ retry: true, maxRetries: 3 })
|
|
28
|
+
* async updateCriticalData(id: string, data: UpdateInput) {
|
|
29
|
+
* // Automatically retries on deadlock or write conflict
|
|
30
|
+
* return this.prisma.write.data.update({ where: { id }, data });
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* // With custom isolation level
|
|
34
|
+
* @Transactional({ isolationLevel: 'Serializable', retry: true })
|
|
35
|
+
* async transferOwnership(fromId: string, toId: string) {
|
|
36
|
+
* // Critical operation requiring serializable isolation
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { PrismaClient, Prisma } from '@prisma/client';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Transaction isolation levels
|
|
46
|
+
* 事务隔离级别
|
|
47
|
+
*/
|
|
48
|
+
export type TransactionIsolationLevel = Prisma.TransactionIsolationLevel;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retryable error codes
|
|
52
|
+
* 可重试的错误码
|
|
53
|
+
*
|
|
54
|
+
* These error codes indicate transient failures that can be retried:
|
|
55
|
+
* - P2034: Transaction failed due to write conflict or deadlock (Prisma)
|
|
56
|
+
* - P2028: Transaction API error (Prisma)
|
|
57
|
+
* - 40001: Serialization failure (PostgreSQL)
|
|
58
|
+
* - 40P01: Deadlock detected (PostgreSQL)
|
|
59
|
+
*/
|
|
60
|
+
const RETRYABLE_ERROR_CODES = new Set([
|
|
61
|
+
'P2034', // Prisma: Write conflict or deadlock
|
|
62
|
+
'P2028', // Prisma: Transaction API error
|
|
63
|
+
'40001', // PostgreSQL: Serialization failure
|
|
64
|
+
'40P01', // PostgreSQL: Deadlock detected
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check if an error is retryable
|
|
69
|
+
* 检查错误是否可重试
|
|
70
|
+
*/
|
|
71
|
+
function isRetryableError(error: unknown): boolean {
|
|
72
|
+
if (!error || typeof error !== 'object') return false;
|
|
73
|
+
|
|
74
|
+
// Check Prisma error code
|
|
75
|
+
const prismaCode = (error as { code?: string }).code;
|
|
76
|
+
if (prismaCode && RETRYABLE_ERROR_CODES.has(prismaCode)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Check PostgreSQL error code in message
|
|
81
|
+
const message = (error as { message?: string }).message || '';
|
|
82
|
+
for (const code of RETRYABLE_ERROR_CODES) {
|
|
83
|
+
if (message.includes(code)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Calculate retry delay with exponential backoff and jitter
|
|
93
|
+
* 使用指数退避和抖动计算重试延迟
|
|
94
|
+
*/
|
|
95
|
+
function calculateRetryDelay(
|
|
96
|
+
attempt: number,
|
|
97
|
+
baseDelay: number,
|
|
98
|
+
backoffMultiplier: number,
|
|
99
|
+
maxDelay: number,
|
|
100
|
+
): number {
|
|
101
|
+
const exponentialDelay = baseDelay * Math.pow(backoffMultiplier, attempt);
|
|
102
|
+
const cappedDelay = Math.min(exponentialDelay, maxDelay);
|
|
103
|
+
// Add jitter (0-25% of delay) to prevent thundering herd
|
|
104
|
+
const jitter = cappedDelay * Math.random() * 0.25;
|
|
105
|
+
return Math.floor(cappedDelay + jitter);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Sleep for specified milliseconds
|
|
110
|
+
* 睡眠指定毫秒数
|
|
111
|
+
*/
|
|
112
|
+
function sleep(ms: number): Promise<void> {
|
|
113
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Transaction options
|
|
118
|
+
* 事务选项
|
|
119
|
+
*/
|
|
120
|
+
export interface TransactionOptions {
|
|
121
|
+
/**
|
|
122
|
+
* Maximum wait time to acquire a transaction lock (ms)
|
|
123
|
+
* 获取事务锁的最大等待时间(毫秒)
|
|
124
|
+
* @default 5000
|
|
125
|
+
*/
|
|
126
|
+
maxWait?: number;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Maximum transaction execution time (ms)
|
|
130
|
+
* 事务执行的最大时间(毫秒)
|
|
131
|
+
* @default 30000
|
|
132
|
+
*/
|
|
133
|
+
timeout?: number;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Transaction isolation level
|
|
137
|
+
* 事务隔离级别
|
|
138
|
+
*/
|
|
139
|
+
isolationLevel?: TransactionIsolationLevel;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Enable retry mechanism for transient failures
|
|
143
|
+
* 启用瞬态失败的重试机制
|
|
144
|
+
* @default false
|
|
145
|
+
*/
|
|
146
|
+
retry?: boolean;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Maximum number of retry attempts
|
|
150
|
+
* 最大重试次数
|
|
151
|
+
* @default 3
|
|
152
|
+
*/
|
|
153
|
+
maxRetries?: number;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Base delay between retries in milliseconds
|
|
157
|
+
* 重试之间的基础延迟(毫秒)
|
|
158
|
+
* @default 100
|
|
159
|
+
*/
|
|
160
|
+
retryDelay?: number;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Exponential backoff multiplier
|
|
164
|
+
* 指数退避倍数
|
|
165
|
+
* @default 2
|
|
166
|
+
*/
|
|
167
|
+
retryBackoffMultiplier?: number;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Maximum retry delay in milliseconds
|
|
171
|
+
* 最大重试延迟(毫秒)
|
|
172
|
+
* @default 5000
|
|
173
|
+
*/
|
|
174
|
+
maxRetryDelay?: number;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Transaction result for monitoring
|
|
179
|
+
* 用于监控的事务结果
|
|
180
|
+
*/
|
|
181
|
+
export interface TransactionResult {
|
|
182
|
+
success: boolean;
|
|
183
|
+
duration: number;
|
|
184
|
+
retryCount: number;
|
|
185
|
+
error?: Error;
|
|
186
|
+
methodName: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Symbol to store transaction client in context
|
|
191
|
+
*/
|
|
192
|
+
const TRANSACTION_CLIENT = Symbol('TRANSACTION_CLIENT');
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Symbol to store transaction context for monitoring
|
|
196
|
+
*/
|
|
197
|
+
const TRANSACTION_CONTEXT = Symbol('TRANSACTION_CONTEXT');
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Transaction context for monitoring
|
|
201
|
+
* 用于监控的事务上下文
|
|
202
|
+
*/
|
|
203
|
+
export interface TransactionContextData {
|
|
204
|
+
startTime: number;
|
|
205
|
+
methodName: string;
|
|
206
|
+
retryCount: number;
|
|
207
|
+
sqlCount: number;
|
|
208
|
+
tablesInvolved: Set<string>;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get the current transaction client or undefined if not in a transaction
|
|
213
|
+
* 获取当前事务客户端,如果不在事务中则返回 undefined
|
|
214
|
+
*/
|
|
215
|
+
export function getTransactionClient(
|
|
216
|
+
context: object,
|
|
217
|
+
): PrismaClient | undefined {
|
|
218
|
+
return (context as Record<symbol, PrismaClient>)[TRANSACTION_CLIENT];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get the current transaction context for monitoring
|
|
223
|
+
* 获取当前事务上下文用于监控
|
|
224
|
+
*/
|
|
225
|
+
export function getTransactionContext(
|
|
226
|
+
context: object,
|
|
227
|
+
): TransactionContextData | undefined {
|
|
228
|
+
return (context as Record<symbol, TransactionContextData>)[
|
|
229
|
+
TRANSACTION_CONTEXT
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Set the transaction client in context
|
|
235
|
+
* 在上下文中设置事务客户端
|
|
236
|
+
*/
|
|
237
|
+
function setTransactionClient(context: object, client: PrismaClient): void {
|
|
238
|
+
(context as Record<symbol, PrismaClient>)[TRANSACTION_CLIENT] = client;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Set the transaction context for monitoring
|
|
243
|
+
* 设置事务上下文用于监控
|
|
244
|
+
*/
|
|
245
|
+
function setTransactionContext(
|
|
246
|
+
context: object,
|
|
247
|
+
txContext: TransactionContextData,
|
|
248
|
+
): void {
|
|
249
|
+
(context as Record<symbol, TransactionContextData>)[TRANSACTION_CONTEXT] =
|
|
250
|
+
txContext;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Clear the transaction client from context
|
|
255
|
+
* 从上下文中清除事务客户端
|
|
256
|
+
*/
|
|
257
|
+
function clearTransactionClient(context: object): void {
|
|
258
|
+
delete (context as Record<symbol, PrismaClient>)[TRANSACTION_CLIENT];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Clear the transaction context from context
|
|
263
|
+
* 从上下文中清除事务上下文
|
|
264
|
+
*/
|
|
265
|
+
function clearTransactionContext(context: object): void {
|
|
266
|
+
delete (context as Record<symbol, TransactionContextData>)[
|
|
267
|
+
TRANSACTION_CONTEXT
|
|
268
|
+
];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Default transaction options
|
|
273
|
+
* 默认事务选项
|
|
274
|
+
*/
|
|
275
|
+
const DEFAULT_OPTIONS: Required<TransactionOptions> = {
|
|
276
|
+
maxWait: 5000,
|
|
277
|
+
timeout: 30000,
|
|
278
|
+
isolationLevel: undefined as unknown as TransactionIsolationLevel,
|
|
279
|
+
retry: false,
|
|
280
|
+
maxRetries: 3,
|
|
281
|
+
retryDelay: 100,
|
|
282
|
+
retryBackoffMultiplier: 2,
|
|
283
|
+
maxRetryDelay: 5000,
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Transactional decorator
|
|
288
|
+
* 事务装饰器
|
|
289
|
+
*
|
|
290
|
+
* Wraps the decorated method in a Prisma transaction.
|
|
291
|
+
* The service class must have a `prisma` property with a `write` client.
|
|
292
|
+
*
|
|
293
|
+
* @param options - Transaction options
|
|
294
|
+
*/
|
|
295
|
+
export function Transactional(options: TransactionOptions = {}) {
|
|
296
|
+
const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
297
|
+
|
|
298
|
+
return function (
|
|
299
|
+
target: object,
|
|
300
|
+
propertyKey: string,
|
|
301
|
+
descriptor: PropertyDescriptor,
|
|
302
|
+
) {
|
|
303
|
+
const originalMethod = descriptor.value;
|
|
304
|
+
const methodName = `${target.constructor.name}.${propertyKey}`;
|
|
305
|
+
|
|
306
|
+
descriptor.value = async function (...args: unknown[]) {
|
|
307
|
+
// Check if already in a transaction
|
|
308
|
+
const existingClient = getTransactionClient(this);
|
|
309
|
+
if (existingClient) {
|
|
310
|
+
// Already in a transaction, just execute the method
|
|
311
|
+
// Increment SQL count in parent transaction context
|
|
312
|
+
const parentContext = getTransactionContext(this);
|
|
313
|
+
if (parentContext) {
|
|
314
|
+
parentContext.sqlCount++;
|
|
315
|
+
}
|
|
316
|
+
return originalMethod.apply(this, args);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Get the Prisma service
|
|
320
|
+
const prismaService = (this as { prisma?: { write: PrismaClient } })
|
|
321
|
+
.prisma;
|
|
322
|
+
if (!prismaService?.write) {
|
|
323
|
+
throw new Error(
|
|
324
|
+
`@Transactional decorator requires a 'prisma' property with a 'write' client on ${target.constructor.name}`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const writeClient = prismaService.write as PrismaClient;
|
|
329
|
+
|
|
330
|
+
// Execute with retry logic
|
|
331
|
+
return executeWithRetry(
|
|
332
|
+
this,
|
|
333
|
+
writeClient,
|
|
334
|
+
originalMethod,
|
|
335
|
+
args,
|
|
336
|
+
methodName,
|
|
337
|
+
mergedOptions,
|
|
338
|
+
);
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
return descriptor;
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Execute transaction with retry logic
|
|
347
|
+
* 使用重试逻辑执行事务
|
|
348
|
+
*/
|
|
349
|
+
async function executeWithRetry(
|
|
350
|
+
context: object,
|
|
351
|
+
writeClient: PrismaClient,
|
|
352
|
+
originalMethod: (...args: unknown[]) => Promise<unknown>,
|
|
353
|
+
args: unknown[],
|
|
354
|
+
methodName: string,
|
|
355
|
+
options: Required<TransactionOptions>,
|
|
356
|
+
): Promise<unknown> {
|
|
357
|
+
let lastError: Error | undefined;
|
|
358
|
+
let retryCount = 0;
|
|
359
|
+
|
|
360
|
+
for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
|
|
361
|
+
try {
|
|
362
|
+
const result = await executeTransaction(
|
|
363
|
+
context,
|
|
364
|
+
writeClient,
|
|
365
|
+
originalMethod,
|
|
366
|
+
args,
|
|
367
|
+
methodName,
|
|
368
|
+
options,
|
|
369
|
+
retryCount,
|
|
370
|
+
);
|
|
371
|
+
return result;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
lastError = error as Error;
|
|
374
|
+
|
|
375
|
+
// Check if we should retry
|
|
376
|
+
if (
|
|
377
|
+
options.retry &&
|
|
378
|
+
attempt < options.maxRetries &&
|
|
379
|
+
isRetryableError(error)
|
|
380
|
+
) {
|
|
381
|
+
retryCount++;
|
|
382
|
+
const delay = calculateRetryDelay(
|
|
383
|
+
attempt,
|
|
384
|
+
options.retryDelay,
|
|
385
|
+
options.retryBackoffMultiplier,
|
|
386
|
+
options.maxRetryDelay,
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
// Log retry attempt
|
|
390
|
+
console.warn(
|
|
391
|
+
`Transaction ${methodName} failed with retryable error, ` +
|
|
392
|
+
`retrying in ${delay}ms (attempt ${retryCount}/${options.maxRetries})`,
|
|
393
|
+
{ error: (error as Error).message },
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
await sleep(delay);
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Not retryable or max retries exceeded
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Should not reach here, but just in case
|
|
406
|
+
throw lastError || new Error('Transaction failed after max retries');
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Execute a single transaction attempt
|
|
411
|
+
* 执行单次事务尝试
|
|
412
|
+
*/
|
|
413
|
+
async function executeTransaction(
|
|
414
|
+
context: object,
|
|
415
|
+
writeClient: PrismaClient,
|
|
416
|
+
originalMethod: (...args: unknown[]) => Promise<unknown>,
|
|
417
|
+
args: unknown[],
|
|
418
|
+
methodName: string,
|
|
419
|
+
options: Required<TransactionOptions>,
|
|
420
|
+
retryCount: number,
|
|
421
|
+
): Promise<unknown> {
|
|
422
|
+
const startTime = Date.now();
|
|
423
|
+
|
|
424
|
+
// 获取 DbMetricsService 上下文(如果可用)
|
|
425
|
+
const metricsService = metricsServiceGetter?.();
|
|
426
|
+
const metricsCtx = metricsService?.recordTransactionStart();
|
|
427
|
+
|
|
428
|
+
// Create transaction context for monitoring
|
|
429
|
+
const txContext: TransactionContextData = {
|
|
430
|
+
startTime,
|
|
431
|
+
methodName,
|
|
432
|
+
retryCount,
|
|
433
|
+
sqlCount: 0,
|
|
434
|
+
tablesInvolved: new Set<string>(),
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
try {
|
|
438
|
+
const result = await writeClient.$transaction(
|
|
439
|
+
async (tx) => {
|
|
440
|
+
// Store the transaction client and context
|
|
441
|
+
setTransactionClient(context, tx as unknown as PrismaClient);
|
|
442
|
+
setTransactionContext(context, txContext);
|
|
443
|
+
|
|
444
|
+
try {
|
|
445
|
+
return await originalMethod.apply(context, args);
|
|
446
|
+
} finally {
|
|
447
|
+
// Clear the transaction client and context
|
|
448
|
+
clearTransactionClient(context);
|
|
449
|
+
clearTransactionContext(context);
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
maxWait: options.maxWait,
|
|
454
|
+
timeout: options.timeout,
|
|
455
|
+
isolationLevel: options.isolationLevel || undefined,
|
|
456
|
+
},
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
// Log successful transaction
|
|
460
|
+
const duration = Date.now() - startTime;
|
|
461
|
+
logTransactionComplete(
|
|
462
|
+
methodName,
|
|
463
|
+
duration,
|
|
464
|
+
retryCount,
|
|
465
|
+
true,
|
|
466
|
+
undefined,
|
|
467
|
+
metricsCtx,
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
return result;
|
|
471
|
+
} catch (error) {
|
|
472
|
+
// Log failed transaction
|
|
473
|
+
const duration = Date.now() - startTime;
|
|
474
|
+
logTransactionComplete(
|
|
475
|
+
methodName,
|
|
476
|
+
duration,
|
|
477
|
+
retryCount,
|
|
478
|
+
false,
|
|
479
|
+
error as Error,
|
|
480
|
+
metricsCtx,
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
throw error;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Transaction metrics service holder
|
|
489
|
+
* 事务指标服务持有者
|
|
490
|
+
*
|
|
491
|
+
* 用于延迟获取 DbMetricsService,避免循环依赖
|
|
492
|
+
*/
|
|
493
|
+
let metricsServiceGetter: (() => DbMetricsServiceInterface | undefined) | null =
|
|
494
|
+
null;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* DbMetricsService interface for loose coupling
|
|
498
|
+
* 松耦合的 DbMetricsService 接口
|
|
499
|
+
*/
|
|
500
|
+
interface DbMetricsServiceInterface {
|
|
501
|
+
recordTransactionStart(): { startTime: number; traceId: string };
|
|
502
|
+
recordTransactionEnd(
|
|
503
|
+
ctx: { startTime: number; traceId: string },
|
|
504
|
+
status: 'success' | 'error' | 'rollback',
|
|
505
|
+
metadata?: {
|
|
506
|
+
retryCount?: number;
|
|
507
|
+
methodName?: string;
|
|
508
|
+
errorType?: string;
|
|
509
|
+
errorMessage?: string;
|
|
510
|
+
},
|
|
511
|
+
): void;
|
|
512
|
+
isEnabled(): boolean;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Set the metrics service getter
|
|
517
|
+
* 设置指标服务获取器
|
|
518
|
+
*
|
|
519
|
+
* 应该在应用启动时调用,例如在 AppModule 的 onModuleInit 中
|
|
520
|
+
*/
|
|
521
|
+
export function setTransactionMetricsService(
|
|
522
|
+
getter: () => DbMetricsServiceInterface | undefined,
|
|
523
|
+
): void {
|
|
524
|
+
metricsServiceGetter = getter;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Log transaction completion with DbMetricsService integration
|
|
529
|
+
* 使用 DbMetricsService 集成记录事务完成
|
|
530
|
+
*/
|
|
531
|
+
function logTransactionComplete(
|
|
532
|
+
methodName: string,
|
|
533
|
+
duration: number,
|
|
534
|
+
retryCount: number,
|
|
535
|
+
success: boolean,
|
|
536
|
+
error?: Error,
|
|
537
|
+
metricsCtx?: { startTime: number; traceId: string },
|
|
538
|
+
): void {
|
|
539
|
+
// 使用 DbMetricsService 记录指标(如果可用)
|
|
540
|
+
const metricsService = metricsServiceGetter?.();
|
|
541
|
+
if (metricsService && metricsCtx) {
|
|
542
|
+
metricsService.recordTransactionEnd(
|
|
543
|
+
metricsCtx,
|
|
544
|
+
success ? 'success' : 'error',
|
|
545
|
+
{
|
|
546
|
+
retryCount,
|
|
547
|
+
methodName,
|
|
548
|
+
errorType: error?.name,
|
|
549
|
+
errorMessage: error?.message,
|
|
550
|
+
},
|
|
551
|
+
);
|
|
552
|
+
return; // DbMetricsService 会处理日志
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// 回退到 console(仅在 DbMetricsService 不可用时)
|
|
556
|
+
// 生产环境应该配置 DbMetricsService
|
|
557
|
+
if (process.env.NODE_ENV === 'dev' || !success || duration > 1000) {
|
|
558
|
+
const logData = {
|
|
559
|
+
methodName,
|
|
560
|
+
duration: `${duration}ms`,
|
|
561
|
+
retryCount,
|
|
562
|
+
success,
|
|
563
|
+
timestamp: new Date().toISOString(),
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
if (success) {
|
|
567
|
+
if (duration > 1000) {
|
|
568
|
+
console.warn('Slow Transaction', logData);
|
|
569
|
+
}
|
|
570
|
+
// dev 环境下记录所有事务,生产环境只记录慢事务
|
|
571
|
+
} else {
|
|
572
|
+
console.error('Transaction Failed', {
|
|
573
|
+
...logData,
|
|
574
|
+
error: error ? { name: error.name, message: error.message } : undefined,
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* TransactionalService mixin
|
|
582
|
+
* 事务服务 Mixin
|
|
583
|
+
*
|
|
584
|
+
* Provides helper methods for transaction-aware services.
|
|
585
|
+
*
|
|
586
|
+
* @example
|
|
587
|
+
* ```typescript
|
|
588
|
+
* @Injectable()
|
|
589
|
+
* export class ApiService extends TransactionalService {
|
|
590
|
+
* constructor(prisma: PrismaService) {
|
|
591
|
+
* super(prisma);
|
|
592
|
+
* }
|
|
593
|
+
*
|
|
594
|
+
* async create(data: CreateInput) {
|
|
595
|
+
* // Uses transaction client if in a transaction, otherwise uses write client
|
|
596
|
+
* return this.getWriteClient().create({ data });
|
|
597
|
+
* }
|
|
598
|
+
* }
|
|
599
|
+
* ```
|
|
600
|
+
*/
|
|
601
|
+
export abstract class TransactionalService {
|
|
602
|
+
constructor(
|
|
603
|
+
protected readonly prisma: { write: PrismaClient; read: PrismaClient },
|
|
604
|
+
) {}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Get the write client (transaction-aware)
|
|
608
|
+
* 获取写客户端(事务感知)
|
|
609
|
+
*
|
|
610
|
+
* Returns the transaction client if currently in a transaction,
|
|
611
|
+
* otherwise returns the regular write client.
|
|
612
|
+
*/
|
|
613
|
+
protected getWriteClient(): PrismaClient {
|
|
614
|
+
const txClient = getTransactionClient(this);
|
|
615
|
+
return txClient ?? this.prisma.write;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Get the read client
|
|
620
|
+
* 获取读客户端
|
|
621
|
+
*
|
|
622
|
+
* Always returns the read client (transactions are for writes only).
|
|
623
|
+
*/
|
|
624
|
+
protected getReadClient(): PrismaClient {
|
|
625
|
+
return this.prisma.read;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Get current transaction context for monitoring
|
|
630
|
+
* 获取当前事务上下文用于监控
|
|
631
|
+
*/
|
|
632
|
+
protected getTransactionContext(): TransactionContextData | undefined {
|
|
633
|
+
return getTransactionContext(this);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Record a table access in the current transaction
|
|
638
|
+
* 在当前事务中记录表访问
|
|
639
|
+
*/
|
|
640
|
+
protected recordTableAccess(tableName: string): void {
|
|
641
|
+
const txContext = getTransactionContext(this);
|
|
642
|
+
if (txContext) {
|
|
643
|
+
txContext.sqlCount++;
|
|
644
|
+
txContext.tablesInvolved.add(tableName);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Execute a callback within a transaction
|
|
650
|
+
* 在事务中执行回调
|
|
651
|
+
*
|
|
652
|
+
* @param callback - The callback to execute
|
|
653
|
+
* @param options - Transaction options
|
|
654
|
+
*/
|
|
655
|
+
protected async runInTransaction<T>(
|
|
656
|
+
callback: (tx: PrismaClient) => Promise<T>,
|
|
657
|
+
options: TransactionOptions = {},
|
|
658
|
+
): Promise<T> {
|
|
659
|
+
const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
660
|
+
|
|
661
|
+
return this.prisma.write.$transaction(
|
|
662
|
+
async (tx) => {
|
|
663
|
+
setTransactionClient(this, tx as unknown as PrismaClient);
|
|
664
|
+
try {
|
|
665
|
+
return await callback(tx as unknown as PrismaClient);
|
|
666
|
+
} finally {
|
|
667
|
+
clearTransactionClient(this);
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
maxWait: mergedOptions.maxWait,
|
|
672
|
+
timeout: mergedOptions.timeout,
|
|
673
|
+
isolationLevel: mergedOptions.isolationLevel || undefined,
|
|
674
|
+
},
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
}
|