refactor(cleaner): batch query and controlled parallel order processing

This commit is contained in:
test
2026-03-16 21:47:13 +08:00
parent 9248be6310
commit 6a2fba0e57
8 changed files with 484 additions and 236 deletions

View File

@@ -1,5 +1,9 @@
import { describe, it, expect } from 'vitest'
import { CleanerService } from '../../src/main/services/erp/cleaner'
import {
createBatches,
getMissingOrders,
runWithConcurrency
} from '../../src/main/services/erp/cleaner'
import type { ShouldDeleteParams } from '../../src/main/services/erp/cleaner'
describe('Cleaner Service (Unit)', () => {
@@ -132,4 +136,35 @@ describe('Cleaner Service (Unit)', () => {
).toBe(false)
})
})
describe('batch and concurrency helpers', () => {
it('should split orders into batches', () => {
const batches = createBatches(['A', 'B', 'C', 'D', 'E'], 2)
expect(batches).toEqual([
['A', 'B'],
['C', 'D'],
['E']
])
})
it('should identify missing orders', () => {
const missing = getMissingOrders(['SC1', 'SC2', 'SC3'], new Set(['SC1', 'SC3']))
expect(missing).toEqual(['SC2'])
})
it('should respect concurrency limit', async () => {
const items = [1, 2, 3, 4, 5, 6]
let running = 0
let peak = 0
await runWithConcurrency(items, 2, async () => {
running += 1
peak = Math.max(peak, running)
await new Promise((resolve) => setTimeout(resolve, 10))
running -= 1
return true
})
expect(peak).toBeLessThanOrEqual(2)
})
})
})

View File

@@ -138,6 +138,34 @@ describe('Cleaner Schema', () => {
expect(result.success).toBe(false)
})
it('should apply defaults for queryBatchSize and processConcurrency', () => {
const input = {
orderNumbers: ['SC12345678901234'],
materialCodes: ['MAT001'],
dryRun: false
}
const result = CleanerInputSchema.safeParse(input)
expect(result.success).toBe(true)
if (result.success) {
expect(result.data.queryBatchSize).toBe(100)
expect(result.data.processConcurrency).toBe(1)
}
})
it('should reject out-of-range processConcurrency', () => {
const input = {
orderNumbers: ['SC12345678901234'],
materialCodes: ['MAT001'],
dryRun: false,
processConcurrency: 21
}
const result = CleanerInputSchema.safeParse(input)
expect(result.success).toBe(false)
})
})
describe('validateCleanerInput', () => {