57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
import { serve } from '@hono/node-server'
|
|
import { logger } from './lib/logger.js'
|
|
import { app } from './app.js'
|
|
import { runMigrations } from './db/startup.js'
|
|
import { seedMockBots, seedClassicBots } from './engine/mock.js'
|
|
import { startBackgroundFights } from './engine/background.js'
|
|
import { getActiveFighterCount } from './engine/orchestrator.js'
|
|
import { clearAllPending } from './engine/human-responses.js'
|
|
import { seedDevTournament, seedFightCard } from './engine/dev-seed.js'
|
|
|
|
// Production env validation — warn but don't crash (wallet features degrade gracefully)
|
|
if (process.env.NODE_ENV === 'production') {
|
|
const walletVars = ['BOTFIGHTS_NWC_URL', 'BOTFIGHTS_WALLET_ENCRYPTION_KEY']
|
|
const missing = walletVars.filter(k => !process.env[k])
|
|
if (missing.length > 0) {
|
|
logger.warn('env', `Missing env vars: ${missing.join(', ')} — wallet/payment features disabled`)
|
|
}
|
|
if (!process.env.CORS_ORIGIN || process.env.CORS_ORIGIN === '*') {
|
|
logger.warn('env', 'CORS_ORIGIN not set — allowing all origins')
|
|
}
|
|
}
|
|
|
|
// Run migrations and seed mock bots before starting the server
|
|
runMigrations()
|
|
await seedMockBots()
|
|
await seedClassicBots()
|
|
|
|
// Dev mode: seed tournament + betting data + fight card for testing
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
await seedDevTournament()
|
|
await seedFightCard()
|
|
}
|
|
|
|
const port = Number(process.env.PORT) || 9100
|
|
|
|
serve({ fetch: app.fetch, port }, () => {
|
|
logger.info('server', `listening on http://localhost:${port}`)
|
|
|
|
// Start background fight loop so the site always has fresh activity
|
|
startBackgroundFights()
|
|
})
|
|
|
|
// Graceful shutdown — drain in-flight fights before exiting
|
|
const shutdown = async (signal: string) => {
|
|
logger.info('server', `${signal} received, shutting down...`)
|
|
const active = getActiveFighterCount()
|
|
if (active > 0) {
|
|
logger.info('server', `${active} fighters still active, waiting 10s...`)
|
|
}
|
|
await new Promise(r => setTimeout(r, active > 0 ? 10_000 : 500))
|
|
clearAllPending()
|
|
logger.info('server', 'shutdown complete')
|
|
process.exit(0)
|
|
}
|
|
process.on('SIGTERM', () => shutdown('SIGTERM'))
|
|
process.on('SIGINT', () => shutdown('SIGINT'))
|