docs(finance): 履约与财务分流统一方案与只读审计脚本
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* 履约载体 ↔ 财务渠道 对齐审计(只读)。
|
||||
*
|
||||
* 用法:npx tsx scripts/audit-fulfillment-finance-alignment.ts
|
||||
*/
|
||||
import { closeDb, query } from '../src/db/client.js'
|
||||
|
||||
async function main() {
|
||||
const pending = await query<{
|
||||
total: number
|
||||
with_work_order: number
|
||||
with_affiliate_task: number
|
||||
with_manual_task: number
|
||||
no_carrier: number
|
||||
}>(
|
||||
`
|
||||
SELECT
|
||||
count(*)::int AS total,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM work_orders wo WHERE wo.order_item_id = oi.id))::int AS with_work_order,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id AND ft.executor_key = 'affiliate_dash'))::int AS with_affiliate_task,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id AND ft.executor_key = 'manual_dispatch'))::int AS with_manual_task,
|
||||
count(*) FILTER (
|
||||
WHERE NOT EXISTS (SELECT 1 FROM work_orders wo WHERE wo.order_item_id = oi.id)
|
||||
AND NOT EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id)
|
||||
)::int AS no_carrier
|
||||
FROM order_items oi
|
||||
WHERE oi.fulfillment_status = 'pending'
|
||||
`,
|
||||
)
|
||||
|
||||
const channelCarrier = await query<{
|
||||
channel: string
|
||||
total: number
|
||||
work_orders: number
|
||||
affiliate_tasks: number
|
||||
manual_tasks: number
|
||||
no_carrier: number
|
||||
}>(
|
||||
`
|
||||
SELECT
|
||||
COALESCE(NULLIF(oi.fulfillment_channel, ''), '(pending)') AS channel,
|
||||
count(*)::int AS total,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM work_orders wo WHERE wo.order_item_id = oi.id))::int AS work_orders,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id AND ft.executor_key = 'affiliate_dash'))::int AS affiliate_tasks,
|
||||
count(*) FILTER (WHERE EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id AND ft.executor_key = 'manual_dispatch'))::int AS manual_tasks,
|
||||
count(*) FILTER (
|
||||
WHERE NOT EXISTS (SELECT 1 FROM work_orders wo WHERE wo.order_item_id = oi.id)
|
||||
AND NOT EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id)
|
||||
)::int AS no_carrier
|
||||
FROM order_items oi
|
||||
WHERE oi.fulfillment_status = 'assigned'
|
||||
GROUP BY 1
|
||||
ORDER BY 2 DESC
|
||||
`,
|
||||
)
|
||||
|
||||
const internalSku = await query<{
|
||||
total: number
|
||||
null_or_blank: number
|
||||
numeric_only: number
|
||||
with_cjk: number
|
||||
}>(
|
||||
`
|
||||
SELECT
|
||||
count(*)::int AS total,
|
||||
count(*) FILTER (WHERE btrim(COALESCE(manual_sku_key, '')) = '')::int AS null_or_blank,
|
||||
count(*) FILTER (WHERE btrim(COALESCE(manual_sku_key, '')) ~ '^[0-9]+$')::int AS numeric_only,
|
||||
count(*) FILTER (WHERE btrim(COALESCE(manual_sku_key, '')) ~ '[一-龥]')::int AS with_cjk
|
||||
FROM order_items
|
||||
WHERE fulfillment_status = 'assigned'
|
||||
`,
|
||||
)
|
||||
|
||||
const rules = await query<{
|
||||
match_key_type: string
|
||||
channel: string
|
||||
scope: string
|
||||
total: number
|
||||
}>(
|
||||
`
|
||||
SELECT match_key_type, channel,
|
||||
CASE WHEN provider = '' AND shop_id = '' THEN 'global' ELSE 'scoped' END AS scope,
|
||||
count(*)::int AS total
|
||||
FROM sku_channel_rules
|
||||
GROUP BY 1, 2, 3
|
||||
ORDER BY 1, 2, 3
|
||||
`,
|
||||
)
|
||||
|
||||
const duplicateProducts = await query<{ duplicate_names: number; duplicate_rows: number }>(
|
||||
`
|
||||
SELECT count(*)::int AS duplicate_names, COALESCE(sum(total), 0)::int AS duplicate_rows
|
||||
FROM (
|
||||
SELECT canonical_name, count(*) AS total
|
||||
FROM product_catalog
|
||||
WHERE status = 'active'
|
||||
GROUP BY canonical_name
|
||||
HAVING count(*) > 1
|
||||
) grouped
|
||||
`,
|
||||
)
|
||||
|
||||
const capabilities = await query<{ channel: string; total: number }>(
|
||||
`SELECT channel, count(*)::int AS total FROM product_channel_capabilities WHERE enabled GROUP BY 1 ORDER BY 2 DESC`,
|
||||
)
|
||||
|
||||
const byProvider = await query<{
|
||||
provider: string
|
||||
total: number
|
||||
pending: number
|
||||
with_carrier: number
|
||||
}>(
|
||||
`
|
||||
SELECT o.provider,
|
||||
count(*)::int AS total,
|
||||
count(*) FILTER (WHERE oi.fulfillment_status = 'pending')::int AS pending,
|
||||
count(*) FILTER (
|
||||
WHERE EXISTS (SELECT 1 FROM work_orders wo WHERE wo.order_item_id = oi.id)
|
||||
OR EXISTS (SELECT 1 FROM fulfillment_tasks ft WHERE ft.order_item_id = oi.id)
|
||||
)::int AS with_carrier
|
||||
FROM order_items oi
|
||||
JOIN orders o ON o.id = oi.order_id
|
||||
WHERE COALESCE(o.paid_at, o.created_at) >= '2026-10-31 00:00:00+08'
|
||||
GROUP BY 1
|
||||
ORDER BY 2 DESC
|
||||
`,
|
||||
)
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
pending: pending.rows[0],
|
||||
channelCarrier: channelCarrier.rows,
|
||||
internalSku: internalSku.rows[0],
|
||||
rules: rules.rows,
|
||||
duplicateProducts: duplicateProducts.rows[0],
|
||||
capabilities: capabilities.rows,
|
||||
byProvider: byProvider.rows,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
.finally(() => closeDb())
|
||||
Reference in New Issue
Block a user