抽离后台平台配置领域匹配辅助逻辑
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
// @ts-check
|
||||
|
||||
import { normalizeAgisoMessageTemplate } from '../platforms/agiso/xianyu/message-service.js'
|
||||
import { maskSecret } from './admin-platform-config-mappers.js'
|
||||
|
||||
export function mapAdminAgisoMessagingDefaults(defaults = {}) {
|
||||
return {
|
||||
messageTemplate: normalizeAgisoMessageTemplate(String(defaults.messageTemplate || '').trim()),
|
||||
autoDeliveryMessageTemplate: normalizeAgisoMessageTemplate(
|
||||
String(defaults.autoDeliveryMessageTemplate || '').trim(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
export function mapAdminAgisoShopConfigItem(shopId, config = {}) {
|
||||
return {
|
||||
shopId,
|
||||
shopName: String(config.shopName || '').trim(),
|
||||
accessToken: String(config.accessToken || '').trim(),
|
||||
accessTokenMasked: maskSecret(config.accessToken),
|
||||
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
||||
messageTemplate: normalizeAgisoMessageTemplate(String(config.messageTemplate || '').trim()),
|
||||
autoDeliveryMessageTemplate: normalizeAgisoMessageTemplate(
|
||||
String(config.autoDeliveryMessageTemplate || '').trim(),
|
||||
),
|
||||
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
||||
apiVersion: String(config.apiVersion || '').trim(),
|
||||
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
||||
}
|
||||
}
|
||||
|
||||
export function applyOptionalStringField(target, key, source) {
|
||||
if (!source || typeof source[key] !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
const value = String(source[key] || '').trim()
|
||||
if (value) {
|
||||
target[key] = normalizeAgisoMessageTemplate(value)
|
||||
return
|
||||
}
|
||||
|
||||
delete target[key]
|
||||
}
|
||||
|
||||
export function mapAdminFulfillmentBindingConfigItem(item) {
|
||||
const match = item?.match || {}
|
||||
return {
|
||||
provider: String(item?.provider || '').trim(),
|
||||
platform: String(item?.platform || '').trim(),
|
||||
shopId: String(item?.shopId || '').trim(),
|
||||
shopName: String(item?.shopName || '').trim(),
|
||||
khhaoShopId: String(item?.khhaoShopId || '').trim(),
|
||||
skuCode: String(item?.skuCode || '').trim(),
|
||||
skuName: String(item?.skuName || '').trim(),
|
||||
profileKey: String(item?.profileKey || '').trim(),
|
||||
enabled: item?.enabled !== false,
|
||||
priority: Number(item?.priority || 100),
|
||||
config: item?.config || {},
|
||||
match: {
|
||||
externalSkuCode: String(match.externalSkuCode || '').trim(),
|
||||
externalItemId: String(match.externalItemId || '').trim(),
|
||||
externalSkuName: String(match.externalSkuName || '').trim(),
|
||||
config: match.config || {},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveFulfillmentBindingMatchShopId({
|
||||
provider = '',
|
||||
platform = '',
|
||||
shopId = '',
|
||||
khhaoShopId = '',
|
||||
} = {}) {
|
||||
if (String(provider || '').trim() === 'khhao' && String(platform || '').trim() === 'kuaishou') {
|
||||
return String(khhaoShopId || shopId || '').trim()
|
||||
}
|
||||
|
||||
return String(shopId || '').trim()
|
||||
}
|
||||
|
||||
export function matchesObservedProduct(binding, observed) {
|
||||
const provider = String(binding?.provider || '').trim()
|
||||
const platform = String(binding?.platform || '').trim()
|
||||
const shopId = String(binding?.shopId || '').trim()
|
||||
const match = binding?.match || {}
|
||||
const externalSkuCode = String(match.externalSkuCode || '').trim()
|
||||
const externalItemId = String(match.externalItemId || '').trim()
|
||||
const externalSkuName = String(match.externalSkuName || '').trim()
|
||||
|
||||
if (provider && provider !== String(observed?.provider || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (platform && platform !== String(observed?.platform || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (shopId && shopId !== String(observed?.shopId || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
(externalSkuCode && externalSkuCode === String(observed?.externalSkuCode || '').trim())
|
||||
|| (externalItemId && externalItemId === String(observed?.externalItemId || '').trim())
|
||||
|| (externalSkuName && externalSkuName === String(observed?.externalSkuName || '').trim())
|
||||
)
|
||||
}
|
||||
|
||||
export function findMatchingObservedBinding(bindings, observed) {
|
||||
return (Array.isArray(bindings) ? bindings : []).find((binding) => matchesObservedProduct(binding, observed)) || null
|
||||
}
|
||||
|
||||
export function mapAdminObservedProductItem(item, bindings = []) {
|
||||
const matchedBinding = findMatchingObservedBinding(bindings, item)
|
||||
|
||||
return {
|
||||
provider: String(item?.provider || '').trim(),
|
||||
platform: String(item?.platform || '').trim(),
|
||||
shopId: String(item?.shopId || '').trim(),
|
||||
shopName: String(item?.shopName || '').trim(),
|
||||
externalItemId: String(item?.externalItemId || '').trim(),
|
||||
externalSkuCode: String(item?.externalSkuCode || '').trim(),
|
||||
externalSkuName: String(item?.externalSkuName || '').trim(),
|
||||
latestSeenAt: item?.latestSeenAt || null,
|
||||
orderItemCount: Number(item?.orderItemCount || 0),
|
||||
configured: Boolean(matchedBinding),
|
||||
matchedBinding: matchedBinding
|
||||
? {
|
||||
skuCode: String(matchedBinding.skuCode || '').trim(),
|
||||
skuName: String(matchedBinding.skuName || '').trim(),
|
||||
profileKey: String(matchedBinding.profileKey || '').trim(),
|
||||
}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
applyOptionalStringField,
|
||||
findMatchingObservedBinding,
|
||||
mapAdminAgisoMessagingDefaults,
|
||||
mapAdminAgisoShopConfigItem,
|
||||
mapAdminFulfillmentBindingConfigItem,
|
||||
mapAdminObservedProductItem,
|
||||
matchesObservedProduct,
|
||||
resolveFulfillmentBindingMatchShopId,
|
||||
} from './admin-platform-config-domain.js'
|
||||
|
||||
test('mapAdminAgisoMessagingDefaults normalizes escaped newlines', () => {
|
||||
assert.deepEqual(
|
||||
mapAdminAgisoMessagingDefaults({
|
||||
messageTemplate: ' hello\\nworld ',
|
||||
autoDeliveryMessageTemplate: ' done\\nnow ',
|
||||
}),
|
||||
{
|
||||
messageTemplate: 'hello\nworld',
|
||||
autoDeliveryMessageTemplate: 'done\nnow',
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
test('mapAdminAgisoShopConfigItem masks secrets and reports configured flags', () => {
|
||||
assert.deepEqual(
|
||||
mapAdminAgisoShopConfigItem('1001', {
|
||||
shopName: ' 店铺A ',
|
||||
accessToken: 'abcdef1234567890',
|
||||
enabled: true,
|
||||
messageTemplate: ' hi\\nall ',
|
||||
autoDeliveryMessageTemplate: ' ok ',
|
||||
appSecret: 'secret-1',
|
||||
apiVersion: ' v2 ',
|
||||
sendMessageEndpoint: ' /send ',
|
||||
}),
|
||||
{
|
||||
shopId: '1001',
|
||||
shopName: '店铺A',
|
||||
accessToken: 'abcdef1234567890',
|
||||
accessTokenMasked: 'abcdef****567890',
|
||||
enabled: true,
|
||||
messageTemplate: 'hi\nall',
|
||||
autoDeliveryMessageTemplate: 'ok',
|
||||
appSecretConfigured: true,
|
||||
apiVersion: 'v2',
|
||||
sendMessageEndpoint: '/send',
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
test('applyOptionalStringField updates and clears normalized template fields', () => {
|
||||
const target = { messageTemplate: 'old' }
|
||||
applyOptionalStringField(target, 'messageTemplate', { messageTemplate: ' next\\nline ' })
|
||||
assert.deepEqual(target, { messageTemplate: 'next\nline' })
|
||||
|
||||
applyOptionalStringField(target, 'messageTemplate', { messageTemplate: ' ' })
|
||||
assert.deepEqual(target, {})
|
||||
})
|
||||
|
||||
test('mapAdminFulfillmentBindingConfigItem normalizes binding shape', () => {
|
||||
assert.deepEqual(
|
||||
mapAdminFulfillmentBindingConfigItem({
|
||||
provider: ' agiso ',
|
||||
platform: ' xianyu ',
|
||||
shopId: ' shop-1 ',
|
||||
skuCode: ' sku-1 ',
|
||||
priority: '80',
|
||||
match: {
|
||||
externalSkuCode: ' ext-1 ',
|
||||
},
|
||||
}),
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
shopName: '',
|
||||
khhaoShopId: '',
|
||||
skuCode: 'sku-1',
|
||||
skuName: '',
|
||||
profileKey: '',
|
||||
enabled: true,
|
||||
priority: 80,
|
||||
config: {},
|
||||
match: {
|
||||
externalSkuCode: 'ext-1',
|
||||
externalItemId: '',
|
||||
externalSkuName: '',
|
||||
config: {},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
test('resolveFulfillmentBindingMatchShopId prefers khhaoShopId for khhao kuaishou bindings', () => {
|
||||
assert.equal(
|
||||
resolveFulfillmentBindingMatchShopId({
|
||||
provider: 'khhao',
|
||||
platform: 'kuaishou',
|
||||
shopId: 'shop-a',
|
||||
khhaoShopId: 'khhao-1',
|
||||
}),
|
||||
'khhao-1',
|
||||
)
|
||||
|
||||
assert.equal(
|
||||
resolveFulfillmentBindingMatchShopId({
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-a',
|
||||
khhaoShopId: 'khhao-1',
|
||||
}),
|
||||
'shop-a',
|
||||
)
|
||||
})
|
||||
|
||||
test('matchesObservedProduct honors provider platform shop and external fields', () => {
|
||||
const binding = {
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
match: {
|
||||
externalSkuCode: 'sku-ext-1',
|
||||
externalItemId: '',
|
||||
externalSkuName: '',
|
||||
},
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
matchesObservedProduct(binding, {
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
externalSkuCode: 'sku-ext-1',
|
||||
}),
|
||||
true,
|
||||
)
|
||||
|
||||
assert.equal(
|
||||
matchesObservedProduct(binding, {
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-2',
|
||||
externalSkuCode: 'sku-ext-1',
|
||||
}),
|
||||
false,
|
||||
)
|
||||
})
|
||||
|
||||
test('mapAdminObservedProductItem attaches matched binding summary', () => {
|
||||
const bindings = [
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
skuCode: 'sku-1',
|
||||
skuName: 'SKU 1',
|
||||
profileKey: 'profile-1',
|
||||
match: {
|
||||
externalSkuCode: 'ext-1',
|
||||
},
|
||||
},
|
||||
]
|
||||
const observed = {
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
shopName: '店铺1',
|
||||
externalItemId: '',
|
||||
externalSkuCode: 'ext-1',
|
||||
externalSkuName: '礼包1',
|
||||
latestSeenAt: '2026-05-04T10:00:00.000Z',
|
||||
orderItemCount: 2,
|
||||
}
|
||||
|
||||
assert.deepEqual(findMatchingObservedBinding(bindings, observed), bindings[0])
|
||||
assert.deepEqual(mapAdminObservedProductItem(observed, bindings), {
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
shopId: 'shop-1',
|
||||
shopName: '店铺1',
|
||||
externalItemId: '',
|
||||
externalSkuCode: 'ext-1',
|
||||
externalSkuName: '礼包1',
|
||||
latestSeenAt: '2026-05-04T10:00:00.000Z',
|
||||
orderItemCount: 2,
|
||||
configured: true,
|
||||
matchedBinding: {
|
||||
skuCode: 'sku-1',
|
||||
skuName: 'SKU 1',
|
||||
profileKey: 'profile-1',
|
||||
},
|
||||
})
|
||||
})
|
||||
@@ -63,7 +63,6 @@ import {
|
||||
verifyCloudtentaclesLoginCode,
|
||||
} from '../platforms/cloudtentacles/virtual-number-service.js'
|
||||
import { runCloudtentaclesFullDebugFlow } from '../platforms/cloudtentacles/debug-flow-service.js'
|
||||
import { normalizeAgisoMessageTemplate } from '../platforms/agiso/xianyu/message-service.js'
|
||||
import {
|
||||
getOrderFulfillmentBindingConfigs,
|
||||
getOrderFulfillmentBindingsFilePath,
|
||||
@@ -87,6 +86,14 @@ import {
|
||||
resolveCloudtentaclesAdminContext,
|
||||
resolveKuaishouEticketAdminContext,
|
||||
} from './admin-platform-config-context.js'
|
||||
import {
|
||||
applyOptionalStringField,
|
||||
mapAdminAgisoMessagingDefaults,
|
||||
mapAdminAgisoShopConfigItem,
|
||||
mapAdminFulfillmentBindingConfigItem,
|
||||
mapAdminObservedProductItem,
|
||||
resolveFulfillmentBindingMatchShopId,
|
||||
} from './admin-platform-config-domain.js'
|
||||
import {
|
||||
mapAdminCloudtentaclesSession,
|
||||
mapAdminCloudtentaclesSourceConfig,
|
||||
@@ -233,42 +240,6 @@ export function updateAdminAgisoShopConfigs(payload = /** @type {AdminAgisoShopC
|
||||
}
|
||||
}
|
||||
|
||||
function mapAdminAgisoMessagingDefaults(defaults = {}) {
|
||||
return {
|
||||
messageTemplate: normalizeAgisoMessageTemplate(String(defaults.messageTemplate || '').trim()),
|
||||
autoDeliveryMessageTemplate: normalizeAgisoMessageTemplate(String(defaults.autoDeliveryMessageTemplate || '').trim()),
|
||||
}
|
||||
}
|
||||
|
||||
function mapAdminAgisoShopConfigItem(shopId, config = {}) {
|
||||
return {
|
||||
shopId,
|
||||
shopName: String(config.shopName || '').trim(),
|
||||
accessToken: String(config.accessToken || '').trim(),
|
||||
accessTokenMasked: maskSecret(config.accessToken),
|
||||
enabled: typeof config.enabled === 'boolean' ? config.enabled : null,
|
||||
messageTemplate: normalizeAgisoMessageTemplate(String(config.messageTemplate || '').trim()),
|
||||
autoDeliveryMessageTemplate: normalizeAgisoMessageTemplate(String(config.autoDeliveryMessageTemplate || '').trim()),
|
||||
appSecretConfigured: Boolean(String(config.appSecret || '').trim()),
|
||||
apiVersion: String(config.apiVersion || '').trim(),
|
||||
sendMessageEndpoint: String(config.sendMessageEndpoint || '').trim(),
|
||||
}
|
||||
}
|
||||
|
||||
function applyOptionalStringField(target, key, source) {
|
||||
if (!source || typeof source[key] !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
const value = String(source[key] || '').trim()
|
||||
if (value) {
|
||||
target[key] = normalizeAgisoMessageTemplate(value)
|
||||
return
|
||||
}
|
||||
|
||||
delete target[key]
|
||||
}
|
||||
|
||||
export function getAdminKhhaoSourceConfig() {
|
||||
const config = getKhhaoSourceConfig()
|
||||
const syncState = getKhhaoSyncState()
|
||||
@@ -1094,95 +1065,3 @@ async function validateAdminFulfillmentBindingConfigs(bindings = []) {
|
||||
|
||||
return normalizedBindings
|
||||
}
|
||||
|
||||
function mapAdminFulfillmentBindingConfigItem(item) {
|
||||
const match = item?.match || {}
|
||||
return {
|
||||
provider: String(item?.provider || '').trim(),
|
||||
platform: String(item?.platform || '').trim(),
|
||||
shopId: String(item?.shopId || '').trim(),
|
||||
shopName: String(item?.shopName || '').trim(),
|
||||
khhaoShopId: String(item?.khhaoShopId || '').trim(),
|
||||
skuCode: String(item?.skuCode || '').trim(),
|
||||
skuName: String(item?.skuName || '').trim(),
|
||||
profileKey: String(item?.profileKey || '').trim(),
|
||||
enabled: item?.enabled !== false,
|
||||
priority: Number(item?.priority || 100),
|
||||
config: item?.config || {},
|
||||
match: {
|
||||
externalSkuCode: String(match.externalSkuCode || '').trim(),
|
||||
externalItemId: String(match.externalItemId || '').trim(),
|
||||
externalSkuName: String(match.externalSkuName || '').trim(),
|
||||
config: match.config || {},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function resolveFulfillmentBindingMatchShopId({
|
||||
provider = '',
|
||||
platform = '',
|
||||
shopId = '',
|
||||
khhaoShopId = '',
|
||||
} = {}) {
|
||||
if (String(provider || '').trim() === 'khhao' && String(platform || '').trim() === 'kuaishou') {
|
||||
return String(khhaoShopId || shopId || '').trim()
|
||||
}
|
||||
|
||||
return String(shopId || '').trim()
|
||||
}
|
||||
|
||||
function matchesObservedProduct(binding, observed) {
|
||||
const provider = String(binding?.provider || '').trim()
|
||||
const platform = String(binding?.platform || '').trim()
|
||||
const shopId = String(binding?.shopId || '').trim()
|
||||
const match = binding?.match || {}
|
||||
const externalSkuCode = String(match.externalSkuCode || '').trim()
|
||||
const externalItemId = String(match.externalItemId || '').trim()
|
||||
const externalSkuName = String(match.externalSkuName || '').trim()
|
||||
|
||||
if (provider && provider !== String(observed?.provider || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (platform && platform !== String(observed?.platform || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (shopId && shopId !== String(observed?.shopId || '').trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
return (
|
||||
(externalSkuCode && externalSkuCode === String(observed?.externalSkuCode || '').trim())
|
||||
|| (externalItemId && externalItemId === String(observed?.externalItemId || '').trim())
|
||||
|| (externalSkuName && externalSkuName === String(observed?.externalSkuName || '').trim())
|
||||
)
|
||||
}
|
||||
|
||||
function mapAdminObservedProductItem(item, bindings = []) {
|
||||
const matchedBinding = findMatchingObservedBinding(bindings, item)
|
||||
|
||||
return {
|
||||
provider: String(item?.provider || '').trim(),
|
||||
platform: String(item?.platform || '').trim(),
|
||||
shopId: String(item?.shopId || '').trim(),
|
||||
shopName: String(item?.shopName || '').trim(),
|
||||
externalItemId: String(item?.externalItemId || '').trim(),
|
||||
externalSkuCode: String(item?.externalSkuCode || '').trim(),
|
||||
externalSkuName: String(item?.externalSkuName || '').trim(),
|
||||
latestSeenAt: item?.latestSeenAt || null,
|
||||
orderItemCount: Number(item?.orderItemCount || 0),
|
||||
configured: Boolean(matchedBinding),
|
||||
matchedBinding: matchedBinding
|
||||
? {
|
||||
skuCode: String(matchedBinding.skuCode || '').trim(),
|
||||
skuName: String(matchedBinding.skuName || '').trim(),
|
||||
profileKey: String(matchedBinding.profileKey || '').trim(),
|
||||
}
|
||||
: null,
|
||||
}
|
||||
}
|
||||
|
||||
function findMatchingObservedBinding(bindings, observed) {
|
||||
return (Array.isArray(bindings) ? bindings : []).find((binding) => matchesObservedProduct(binding, observed)) || null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user