119 lines
3.9 KiB
TypeScript
119 lines
3.9 KiB
TypeScript
import { loadEnvConfig } from '@next/env'
|
|
|
|
loadEnvConfig(process.cwd())
|
|
|
|
const CONFIRM_TOKEN = 'sync-supply-chain-product-archive-enrichment'
|
|
|
|
function readArgument(name: string) {
|
|
const prefix = `--${name}=`
|
|
return process.argv.slice(2).find((argument) => argument.startsWith(prefix))?.slice(prefix.length) ?? ''
|
|
}
|
|
|
|
function databaseIdentity(databaseUrl: string) {
|
|
const parsed = new URL(databaseUrl)
|
|
return [
|
|
parsed.protocol.replace(/:$/, ''),
|
|
decodeURIComponent(parsed.username || ''),
|
|
parsed.hostname,
|
|
parsed.port || '',
|
|
parsed.pathname.replace(/^\//, ''),
|
|
parsed.searchParams.get('schema') ?? '',
|
|
].join('|')
|
|
}
|
|
|
|
function sourceDatabaseIdentity() {
|
|
const host = process.env.JST_REPORT_DB_HOST?.trim() ?? ''
|
|
const database = process.env.JST_REPORT_DB_NAME?.trim() ?? ''
|
|
const user = process.env.JST_REPORT_DB_USER?.trim() ?? ''
|
|
if (!host || !database || !user) return ''
|
|
return [
|
|
'sqlserver',
|
|
user,
|
|
host,
|
|
process.env.JST_REPORT_DB_PORT?.trim() || '1433',
|
|
database,
|
|
process.env.JST_REPORT_DB_SCHEMA?.trim() || 'rpt',
|
|
].join('|')
|
|
}
|
|
|
|
async function main() {
|
|
if (!process.argv.includes('--apply')) {
|
|
throw new Error('This sync writes the archive. Pass --apply explicitly.')
|
|
}
|
|
if (readArgument('confirm') !== CONFIRM_TOKEN) {
|
|
throw new Error(`Pass --confirm=${CONFIRM_TOKEN}.`)
|
|
}
|
|
|
|
const databaseUrl = process.env.DATABASE_URL?.trim() ?? ''
|
|
if (!databaseUrl) throw new Error('DATABASE_URL is required.')
|
|
const actualDatabaseIdentity = databaseIdentity(databaseUrl)
|
|
if (readArgument('expected-database-identity') !== actualDatabaseIdentity) {
|
|
throw new Error(
|
|
`Pass --expected-database-identity=${actualDatabaseIdentity}.`,
|
|
)
|
|
}
|
|
|
|
const actualSourceIdentity = sourceDatabaseIdentity()
|
|
if (!actualSourceIdentity) throw new Error('JST_REPORT_DB_* is required.')
|
|
if (readArgument('expected-source-database-identity') !== actualSourceIdentity) {
|
|
throw new Error(
|
|
`Pass --expected-source-database-identity=${actualSourceIdentity}.`,
|
|
)
|
|
}
|
|
|
|
const batchSizeValue = Number(readArgument('batch-size') || '200')
|
|
if (!Number.isSafeInteger(batchSizeValue) || batchSizeValue < 1 || batchSizeValue > 200) {
|
|
throw new Error('--batch-size must be an integer between 1 and 200.')
|
|
}
|
|
|
|
const syncJstBase = process.argv.includes('--sync-jst-base')
|
|
const jstBatchSize = Number(readArgument('jst-batch-size') || '500')
|
|
if (
|
|
!Number.isSafeInteger(jstBatchSize) ||
|
|
jstBatchSize < 1 ||
|
|
jstBatchSize > 5_000
|
|
) {
|
|
throw new Error('--jst-batch-size must be an integer between 1 and 5000.')
|
|
}
|
|
const jstConcurrency = Number(readArgument('jst-concurrency') || '8')
|
|
if (
|
|
!Number.isSafeInteger(jstConcurrency) ||
|
|
jstConcurrency < 1 ||
|
|
jstConcurrency > 32
|
|
) {
|
|
throw new Error('--jst-concurrency must be an integer between 1 and 32.')
|
|
}
|
|
|
|
const [
|
|
{ prisma },
|
|
{ supplyChainProductArchiveEnrichmentSyncService },
|
|
{ jstSkuProductArchiveFullSyncService },
|
|
] = await Promise.all([
|
|
import('../src/lib/prisma'),
|
|
import('../src/server/services/supply-chain-product-archive-enrichment-sync.service'),
|
|
syncJstBase
|
|
? import('../src/server/services/jst-sku-product-archive-full-sync.service')
|
|
: Promise.resolve({ jstSkuProductArchiveFullSyncService: null }),
|
|
])
|
|
try {
|
|
const baseResult = jstSkuProductArchiveFullSyncService
|
|
? await jstSkuProductArchiveFullSyncService.syncAll({
|
|
apply: true,
|
|
batchSize: jstBatchSize,
|
|
concurrency: jstConcurrency,
|
|
})
|
|
: null
|
|
const enrichmentResult = await supplyChainProductArchiveEnrichmentSyncService.syncAll({
|
|
batchSize: batchSizeValue,
|
|
})
|
|
console.log(JSON.stringify({ baseResult, enrichmentResult }, null, 2))
|
|
} finally {
|
|
await prisma.$disconnect()
|
|
}
|
|
}
|
|
|
|
void main().catch((error) => {
|
|
console.error(error instanceof Error ? error.message : String(error))
|
|
process.exitCode = 1
|
|
})
|