Files
2026-10-27 17:44:41 +08:00

72 lines
4.3 KiB
JavaScript

const MODULE = 'merchant-qualification-fixture'
function id(value) { return value == null ? '' : String(value) }
async function waitForDimensionInitialization(context, tenantId) {
let response = null
let status = 'PENDING'
let attempt = 0
for (; attempt < 30; attempt += 1) {
response = await context.request('GET',
`/api/platform/v1/iam/tenants/${encodeURIComponent(tenantId)}/dimension-initialization`)
status = response.http === 200 && String(response.body?.code) === '200'
? response.body?.data?.status : 'REQUEST_FAILED'
if (status === 'READY' || status === 'FAILED') break
await new Promise((resolve) => setTimeout(resolve, 500))
}
context.assert(MODULE, '客户默认尺寸后台初始化已就绪', response, status === 'READY',
`tenantId=${tenantId}, status=${status}, attempts=${attempt + 1}`, { deploymentBlocker: true })
if (status !== 'READY') throw new Error(`客户默认尺寸初始化未就绪: ${status}`)
}
export function normalizeFixedCustomerId(value) {
const text = String(value || '').trim().replace(/^TEN/, '')
if (!/^[1-9]\d{0,19}$/.test(text)) throw new Error('固定客户编号必须为 TEN 编号或数字 ID')
return text
}
export function requireFixedSecondaryCustomer(options) {
const secondary = options.fixedSecondaryCustomer
if (!secondary?.customerId || !secondary.username || !secondary.password)
throw new Error('固定客户模式未配置第二个客户,跨客户场景阻断;禁止自动建客或用同一客户替代隔离验证')
if (normalizeFixedCustomerId(secondary.customerId) === normalizeFixedCustomerId(options.fixedCustomerId))
throw new Error('第二个固定客户必须不同于主客户,禁止替代隔离验证')
return secondary
}
async function reuseFixedCustomer(context, publishEnvironment, requireDistinctCustomer) {
const secondary = requireDistinctCustomer ? requireFixedSecondaryCustomer(context.options) : null
const tenantId = normalizeFixedCustomerId(secondary?.customerId || context.options.fixedCustomerId)
const prefix = context.options.environment === 'gray' ? 'MERCHANT_GRAY' : 'MERCHANT_TEST'
const username = secondary ? secondary.username : context.options.merchantUsername || process.env[`${prefix}_USERNAME`]
const password = secondary ? secondary.password : context.options.merchantPassword || process.env[`${prefix}_PASSWORD`]
if (!username || !password) throw new Error(`请配置固定客户的 ${prefix}_USERNAME / ${prefix}_PASSWORD;不会新建客户或重置密码`)
const loginResponse = await context.request('POST', '/api/auth/login', {loginId:username,password}, '')
const login = context.apiSuccess(MODULE, '登录已配置的固定客户账号', loginResponse)
if (!login?.accessToken) throw new Error('固定客户账号登录失败')
let profile
try {
const response = await context.request('GET', '/api/merchant/v1/iam/tenant/profile', undefined, login.accessToken)
profile = context.apiSuccess(MODULE, '核对固定客户账号实际归属和状态', response)
const valid = id(profile?.id) === tenantId && profile?.status === 'ACTIVE'
context.assert(MODULE, '固定客户账号属于指定已审核客户', response, valid,
`expected=${tenantId}, actual=${id(profile?.id)}, status=${profile?.status}`, {deploymentBlocker:true})
if (!valid) throw new Error('固定客户账号归属或状态不匹配,停止造数;不会新建客户')
await waitForDimensionInitialization(context, tenantId)
} finally {
await context.request('POST', '/api/auth/logout', {refreshToken:login.refreshToken}, login.accessToken)
}
if (publishEnvironment) {
process.env[`${prefix}_USERNAME`] = username
process.env[`${prefix}_PASSWORD`] = password
}
const fixture = {tenantId,tenantName:profile.tenantName,username,marker:context.marker,reused:true}
context.context.merchantQualificationFixture = {...fixture,password}
context.context.customerId = tenantId
context.createdResources.merchantQualificationFixture = fixture
}
export async function run(context, { publishEnvironment = true, requireDistinctCustomer = !publishEnvironment } = {}) {
if (!context.options?.fixedCustomerId) throw new Error('必须配置固定客户,禁止自动建客、补交资质或自动审核')
return reuseFixedCustomer(context, publishEnvironment, requireDistinctCustomer)
}