import { runDatabaseMigrations } from '../db/migrate.js' import { ensureAdminUsersBootstrapped } from '../services/admin/admin-auth-service.js' import { ensureFulfillmentCatalogBootstrapped } from '../services/bootstrap/fulfillment-bootstrap-service.js' import { migrateJsonConfigFilesToDatabase } from '../services/config/json-config-migration-service.js' import { startKuaishouIndustrySendCallbackRetryWorker } from '../services/platforms/kuaishou-industry/send-code-service.js' import { startScheduledJobs } from '../services/scheduler/scheduler-service.js' import { logError, logInfo } from '../utils/logger.js' import { formatStartupError, type StartupState } from './state.js' const CORE_BOOT_RETRY_DELAY_MS = 5_000 export async function bootstrapCoreServices( startupState: StartupState, isShutdownStarted: () => boolean, ) { if (startupState.core.running || isShutdownStarted()) { return } startupState.core.running = true while (!isShutdownStarted() && !startupState.core.ready) { startupState.phase = startupState.core.attemptCount === 0 ? 'starting' : 'retrying' startupState.core.attemptCount += 1 startupState.core.lastAttemptAt = new Date().toISOString() try { logInfo('[startup]', '开始执行快手核心启动步骤', { attempt: startupState.core.attemptCount, }) await runDatabaseMigrations() await migrateJsonConfigFilesToDatabase() await ensureFulfillmentCatalogBootstrapped() await ensureAdminUsersBootstrapped() startupState.core.ready = true startupState.core.lastError = '' startupState.phase = 'ready' startupState.core.readyAt = new Date().toISOString() logInfo('[startup]', '快手核心启动步骤完成,服务已就绪', { attempt: startupState.core.attemptCount, }) startScheduledJobs() startKuaishouIndustrySendCallbackRetryWorker() break } catch (error) { const message = formatStartupError(error) startupState.phase = 'retrying' startupState.core.lastError = message logError('[startup]', '快手核心启动步骤失败,将自动重试', { attempt: startupState.core.attemptCount, retryDelayMs: CORE_BOOT_RETRY_DELAY_MS, error, }) await sleep(CORE_BOOT_RETRY_DELAY_MS) } } startupState.core.running = false } function sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms) }) }