import process from 'node:process' import { closeDb, query } from '../src/db/client.js' import { getFulfillmentModeCounts, reconcilePendingFulfillmentModes, } from '../src/services/fulfillment/fulfillment-mode-service.js' const options = parseOptions(process.argv.slice(2)) const batchSize = normalizeInteger(options.batchSize, 5000, 1, 50_000) const maxBatches = normalizeInteger(options.maxBatches, 1000, 1, 10_000) async function main() { const column = await query<{ exists: boolean }>( ` SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'order_items' AND column_name = 'fulfillment_mode' ) AS exists `, ) if (!column.rows[0]?.exists) { throw new Error('order_items.fulfillment_mode 不存在,请先执行 npm run db:migrate(迁移 105)') } const startedAt = Date.now() const result = await reconcilePendingFulfillmentModes({ batchSize, maxBatches, reason: 'backfill_2026_10_23', }) const counts = await getFulfillmentModeCounts() console.log( JSON.stringify( { ...result, batchSize, maxBatches, counts, durationMs: Date.now() - startedAt, }, null, 2, ), ) if (result.remainingCount > 0) { console.error(`仍有 ${result.remainingCount} 个订单项未回填;请增大 --max-batches 或检查数据。`) process.exitCode = 2 } } main() .catch((error) => { console.error(error instanceof Error ? error.message : error) process.exitCode = 1 }) .finally(async () => { await closeDb() }) function parseOptions(args: string[]) { const result: Record = {} for (const arg of args) { if (!arg.startsWith('--')) continue const body = arg.slice(2) const index = body.indexOf('=') if (index === -1) { result[body] = 'true' } else { result[body.slice(0, index)] = body.slice(index + 1) } } return result } function normalizeInteger(value: unknown, fallback: number, min: number, max: number) { const parsed = Number(value) if (!Number.isInteger(parsed)) return fallback return Math.min(max, Math.max(min, parsed)) }