Files
TurboHR/backend/src/app.ts
T
selfrelease 757cbc8740 fix: 增加 /api/v1/health 路由,修复 deploy.sh 验证 404
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-15 14:34:39 +08:00

128 lines
5.0 KiB
TypeScript

import express from 'express'
import cors from 'cors'
import helmet from 'helmet'
import morgan from 'morgan'
import compression from 'compression'
import { errorHandler } from './middleware/errorHandler'
import { apiLimiter } from './middleware/rateLimit'
import logger from './lib/logger'
const app = express()
app.set('trust proxy', 1)
app.use(helmet())
app.use(compression({
filter: (req, res) => {
// SSE 流式响应不压缩,避免缓冲导致前端一次性收到所有数据
if (req.headers['accept'] === 'text/event-stream' || res.getHeader('Content-Type') === 'text/event-stream') {
return false
}
return compression.filter(req, res)
},
}))
app.use(
cors({
origin: true,
credentials: true,
exposedHeaders: ['Content-Disposition'],
}),
)
app.use(express.json({ limit: '10mb' }))
app.use(morgan('dev'))
app.get('/health', (_req, res) => {
res.json({ success: true, data: { status: 'ok', timestamp: new Date().toISOString() } })
})
// deploy.sh 验证脚本检查 /api/v1/health
app.get('/api/v1/health', (_req, res) => {
res.json({ success: true, data: { status: 'ok', timestamp: new Date().toISOString() } })
})
app.use('/api/v1', apiLimiter)
// 路由挂载
import authRoutes from './routes/auth.routes'
import dashboardRoutes from './routes/dashboard.routes'
import employeeRoutes from './routes/employee.routes'
import terminationRoutes from './routes/termination.routes'
import aiRoutes from './routes/ai.routes'
import portalRoutes from './routes/portal.routes'
import settingsRoutes from './routes/settings.routes'
import payrollRoutes from './routes/payroll.routes'
import payroll2Routes from './routes/payroll2.routes'
import socialRoutes from './routes/social.routes'
import notificationRoutes from './routes/notification.routes'
import attachmentRoutes from './routes/attachment.routes'
import rosterRoutes from './routes/roster.routes'
import exportRoutes from './routes/export.routes'
import importRoutes from './routes/import.routes'
import evidenceRoutes from './routes/evidence.routes'
import policyRoutes from './routes/policy.routes'
import attendanceRoutes from './routes/attendance.routes'
import templateRoutes from './routes/template.routes'
import auditRoutes from './routes/audit.routes'
import calendarRoutes from './routes/calendar.routes'
import platformRoutes from './routes/platform.routes'
import workProcessRoutes from './routes/work-process.routes'
import departmentRoutes from './routes/department.routes'
import positionRoutes from './routes/position.routes'
import approvalRoutes from './routes/approval.routes'
import supportRoutes from './routes/support.routes'
import enterpriseTemplateRoutes from './routes/enterprise-template.routes'
import specialStatusRoutes from './routes/special-status.routes'
import companyFileRoutes from './routes/company-file.routes'
import acceptanceTestRoutes from './routes/acceptance-test.routes'
import leaveRoutes from './routes/leave.routes'
import salaryRoutes from './routes/salary.routes'
import commercialInsuranceRoutes from './routes/commercial-insurance.routes'
import benefitRoutes from './routes/benefit.routes'
import esignRoutes from './routes/esign.routes'
app.use('/api/v1/auth', authRoutes)
app.use('/api/v1/dashboard', dashboardRoutes)
app.use('/api/v1/employees', employeeRoutes)
app.use('/api/v1/termination', terminationRoutes)
app.use('/api/v1/ai', aiRoutes)
app.use('/api/v1/portal', portalRoutes)
app.use('/api/v1/settings', settingsRoutes)
app.use('/api/v1/payroll', payrollRoutes)
app.use('/api/v1/payroll2', payroll2Routes)
app.use('/api/v1/social', socialRoutes)
app.use('/api/v1/notifications', notificationRoutes)
app.use('/api/v1/attachments', attachmentRoutes)
app.use('/api/v1/roster', rosterRoutes)
app.use('/api/v1/export', exportRoutes)
app.use('/api/v1/import', importRoutes)
app.use('/api/v1/evidence', evidenceRoutes)
app.use('/api/v1/policies', policyRoutes)
app.use('/api/v1/attendance', attendanceRoutes)
app.use('/api/v1/templates', templateRoutes)
app.use('/api/v1/audit', auditRoutes)
app.use('/api/v1/calendar', calendarRoutes)
app.use('/api/v1/platform', platformRoutes)
app.use('/api/v1/work-processes', workProcessRoutes)
app.use('/api/v1/departments', departmentRoutes)
app.use('/api/v1/positions', positionRoutes)
app.use('/api/v1/approvals', approvalRoutes)
app.use('/api/v1/support', supportRoutes)
app.use('/api/v1/enterprise-templates', enterpriseTemplateRoutes)
app.use('/api/v1/special-statuses', specialStatusRoutes)
app.use('/api/v1/company-files', companyFileRoutes)
app.use('/api/v1/acceptance-tests', acceptanceTestRoutes)
app.use('/api/v1/leaves', leaveRoutes)
app.use('/api/v1/salary', salaryRoutes)
app.use('/api/v1/commercial-insurance', commercialInsuranceRoutes)
app.use('/api/v1/benefits', benefitRoutes)
app.use('/api/v1/esign', esignRoutes)
app.use(errorHandler)
// RAG 知识库自动初始化(异步,不阻塞启动)
import { seedKnowledgeBase } from './services/rag.service'
seedKnowledgeBase().catch((err) => {
logger.warn({ err }, 'RAG 知识库初始化失败,AI 问答将不使用 RAG 检索')
})
export default app