后端迁移云触手调试流程
This commit is contained in:
+17
-9
@@ -1,5 +1,3 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
import { createHttpError } from '../../../utils/http.js'
|
import { createHttpError } from '../../../utils/http.js'
|
||||||
import { getCloudtentaclesAsset, listCloudtentaclesSku, buyCloudtentaclesSku } from './catalog-service.js'
|
import { getCloudtentaclesAsset, listCloudtentaclesSku, buyCloudtentaclesSku } from './catalog-service.js'
|
||||||
import { getCloudtentaclesKnapsack } from './knapsack-service.js'
|
import { getCloudtentaclesKnapsack } from './knapsack-service.js'
|
||||||
@@ -11,7 +9,13 @@ import {
|
|||||||
verifyCloudtentaclesLoginCode,
|
verifyCloudtentaclesLoginCode,
|
||||||
} from './virtual-number-service.js'
|
} from './virtual-number-service.js'
|
||||||
|
|
||||||
export async function runCloudtentaclesFullDebugFlow(payload = {}) {
|
type JsonObject = Record<string, any>
|
||||||
|
type FlowStepOptions = {
|
||||||
|
retries?: number
|
||||||
|
retryDelayMs?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runCloudtentaclesFullDebugFlow(payload: JsonObject = {}) {
|
||||||
const skuId = normalizePositiveInteger(payload.skuId, 0)
|
const skuId = normalizePositiveInteger(payload.skuId, 0)
|
||||||
const skuCount = normalizePositiveInteger(payload.skuCount, 1)
|
const skuCount = normalizePositiveInteger(payload.skuCount, 1)
|
||||||
const vnKey = String(payload.vnKey || '').trim()
|
const vnKey = String(payload.vnKey || '').trim()
|
||||||
@@ -163,16 +167,20 @@ export async function runCloudtentaclesFullDebugFlow(payload = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizePositiveInteger(value, fallback) {
|
function normalizePositiveInteger(value: unknown, fallback: number) {
|
||||||
const parsed = Number(value)
|
const parsed = Number(value)
|
||||||
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
function findKnapsackItem(items, skuId) {
|
function findKnapsackItem(items: unknown, skuId: unknown) {
|
||||||
return (Array.isArray(items) ? items : []).find((item) => Number(item.id || 0) === Number(skuId)) || null
|
return (Array.isArray(items) ? items : []).find((item) => Number(item.id || 0) === Number(skuId)) || null
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runFlowStep(label, runner, options = {}) {
|
async function runFlowStep<T>(
|
||||||
|
label: string,
|
||||||
|
runner: () => Promise<T>,
|
||||||
|
options: FlowStepOptions = {},
|
||||||
|
) {
|
||||||
const retries = Number.isInteger(options.retries) && options.retries > 0 ? options.retries : 0
|
const retries = Number.isInteger(options.retries) && options.retries > 0 ? options.retries : 0
|
||||||
const retryDelayMs = Number.isFinite(options.retryDelayMs) && options.retryDelayMs > 0 ? options.retryDelayMs : 1000
|
const retryDelayMs = Number.isFinite(options.retryDelayMs) && options.retryDelayMs > 0 ? options.retryDelayMs : 1000
|
||||||
|
|
||||||
@@ -194,12 +202,12 @@ async function runFlowStep(label, runner, options = {}) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function isHighFrequencyError(error) {
|
function isHighFrequencyError(error: unknown) {
|
||||||
const message = error instanceof Error ? error.message : String(error || '')
|
const message = error instanceof Error ? error.message : String(error || '')
|
||||||
return message.toLowerCase().includes('high-frequency request')
|
return message.toLowerCase().includes('high-frequency request')
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapStepError(label, error) {
|
function wrapStepError(label: string, error: unknown) {
|
||||||
const message = error instanceof Error ? error.message : String(error || '未知错误')
|
const message = error instanceof Error ? error.message : String(error || '未知错误')
|
||||||
|
|
||||||
if (isHighFrequencyError(error)) {
|
if (isHighFrequencyError(error)) {
|
||||||
@@ -225,7 +233,7 @@ function wrapStepError(label, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function sleep(ms) {
|
function sleep(ms: number) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(resolve, ms)
|
setTimeout(resolve, ms)
|
||||||
})
|
})
|
||||||
@@ -658,6 +658,14 @@
|
|||||||
- `npm run typecheck`
|
- `npm run typecheck`
|
||||||
- `npm run build`
|
- `npm run build`
|
||||||
- `npm test` 共 139 个用例通过
|
- `npm test` 共 139 个用例通过
|
||||||
|
159. Cloudtentacles 完整调试流程服务迁移到 `.ts`:
|
||||||
|
- `src/services/platforms/cloudtentacles/debug-flow-service.ts`
|
||||||
|
160. Cloudtentacles 余额 / SKU / 背包校验、购买、申请虚拟号、生成登录码、获取验证码、校验验证码、获取兑换链接的后台调试串联流程已进入 TS 编译链路;流程 payload、步骤 runner、重试 options、错误包装补齐类型
|
||||||
|
161. Docker 内验证通过:
|
||||||
|
- `src/services/admin/platform-config/*.test.js` 共 37 个用例通过
|
||||||
|
- `npm run typecheck`
|
||||||
|
- `npm run build`
|
||||||
|
- `npm test` 共 139 个用例通过
|
||||||
|
|
||||||
## 下一步建议
|
## 下一步建议
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user