重构:统一商品渠道投影并收敛权威文档

This commit is contained in:
yml2213
2026-11-08 19:44:27 +08:00
parent 0a595acfa9
commit 1634502363
67 changed files with 2147 additions and 444 deletions
@@ -2146,15 +2146,6 @@ async function ensureDraftProductForChannel(
const productId = Number(product?.id || 0)
if (!productId || product?.status !== 'active') return null
await query(
`
INSERT INTO product_channel_capabilities (
product_id, channel, priority, is_fallback, enabled, source
) VALUES ($1, $2, 10, FALSE, TRUE, 'auto')
ON CONFLICT (product_id, channel) DO NOTHING
`,
[productId, channel],
)
return productId
}
@@ -0,0 +1,145 @@
/**
* 内部 SKU 与渠道路由兼容层集成测试(需要真实 PostgreSQL)。
*
* INTERNAL_SKU_ROUTING_TEST_DATABASE_URL=postgres://... \
* npx tsx --test src/services/fulfillment/internal-sku-routing.integration.test.ts
*/
import assert from 'node:assert/strict'
import test from 'node:test'
const TEST_DATABASE_URL = String(process.env.INTERNAL_SKU_ROUTING_TEST_DATABASE_URL || '').trim()
test(
'旧 internal_sku_channels 写入会同步路由,商品来源与主渠道投影保持分离',
{ skip: !TEST_DATABASE_URL ? '未设置 INTERNAL_SKU_ROUTING_TEST_DATABASE_URL' : false },
async () => {
process.env.DATABASE_URL = TEST_DATABASE_URL
const { closeDb, query } = await import('../../db/client.js')
const suffix = `${Date.now()}_${Math.floor(Math.random() * 1_000_000)}`
const internalSku = `路由集成测试-${suffix}`
const canonicalSku = `man:${internalSku}`
let internalSkuId = 0
let productId = 0
try {
const createdSku = await query<{ id: string }>(
'SELECT ensure_canonical_internal_sku($1) AS id',
[internalSku],
)
internalSkuId = Number(createdSku.rows[0]?.id || 0)
assert.ok(internalSkuId > 0)
const createdProduct = await query<{ id: string; source_kind: string }>(
`
INSERT INTO product_catalog (
canonical_sku, canonical_name, category, unit_name, status, attributes_json,
created_at, updated_at
) VALUES ($1, $2, '集成测试', '件', 'active', '{}'::jsonb, NOW(), NOW())
RETURNING id, source_kind
`,
[canonicalSku, internalSku],
)
productId = Number(createdProduct.rows[0]?.id || 0)
assert.ok(productId > 0)
assert.equal(createdProduct.rows[0]?.source_kind, 'manual')
const beforeRoute = await query<{ active_primary_channel: string | null }>(
'SELECT active_primary_channel FROM v_product_current WHERE id = $1',
[productId],
)
assert.equal(
beforeRoute.rows[0]?.active_primary_channel,
null,
'man: 来源没有主路由时必须显示未路由',
)
await query(
`
INSERT INTO internal_sku_channels (
internal_sku, channel, priority, is_fallback, enabled, canonical_product_id, source
) VALUES ($1, 'manual', 10, FALSE, TRUE, $2, 'integration_test')
`,
[internalSku, productId],
)
const primary = await query<{ route_role: string; channel: string }>(
`
SELECT route_role, channel
FROM sku_channel_routes
WHERE internal_sku_id = $1 AND enabled = TRUE
`,
[internalSkuId],
)
assert.deepEqual(primary.rows, [{ route_role: 'primary', channel: 'manual' }])
const projection = await query<{
source_kind: string
active_primary_channel: string
internal_sku_id: string
}>(
`
SELECT source_kind, active_primary_channel, internal_sku_id
FROM v_product_current
WHERE id = $1
`,
[productId],
)
assert.equal(projection.rows[0]?.source_kind, 'manual')
assert.equal(projection.rows[0]?.active_primary_channel, 'manual')
assert.equal(Number(projection.rows[0]?.internal_sku_id), internalSkuId)
const { getAdminCostCenterOverview } =
await import('../cost-center/cost-center-overview-service.js')
const { listAdminProducts } = await import('../cost-center/product-catalog-service.js')
const overview = await getAdminCostCenterOverview({ scope: 'manual' })
const products = await listAdminProducts({ channel: 'manual', page: 1, pageSize: 100 })
assert.equal(products.pagination.total, overview.productCount)
assert.ok(products.items.every((product) => product.activePrimaryChannel === 'manual'))
await query(
`
UPDATE internal_sku_channels
SET is_fallback = TRUE, updated_at = NOW()
WHERE internal_sku = $1 AND channel = 'manual'
`,
[internalSku],
)
const fallback = await query<{ route_role: string }>(
'SELECT route_role FROM sku_channel_routes WHERE internal_sku_id = $1',
[internalSkuId],
)
assert.deepEqual(fallback.rows, [{ route_role: 'fallback' }])
await query(
`
UPDATE internal_sku_channels
SET is_fallback = FALSE, updated_at = NOW()
WHERE internal_sku = $1 AND channel = 'manual'
`,
[internalSku],
)
await assert.rejects(
() =>
query(
`
INSERT INTO sku_channel_routes (
internal_sku_id, channel, route_role, priority, enabled
) VALUES ($1, 'work_order', 'primary', 1, TRUE)
`,
[internalSkuId],
),
/uq_sku_channel_routes_primary|duplicate key/,
)
} finally {
if (productId > 0) {
await query('DELETE FROM product_catalog WHERE id = $1', [productId])
}
if (internalSkuId > 0) {
await query('DELETE FROM internal_sku_channels WHERE internal_sku = $1', [internalSku])
await query('DELETE FROM internal_skus WHERE id = $1', [internalSkuId])
}
await closeDb()
}
},
)