paper-burner/local-proxy/app.js

103 lines
3.0 KiB
JavaScript

/**
* Express 应用入口
* 处理持久化 API 路由
*/
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { prisma } from './db/client.js';
import { requireAuth } from './auth/middleware.js';
// 导入路由(稍后创建)
import documentsRouter from './routes/documents.js';
import userRouter from './routes/user.js';
import glossaryRouter from './routes/glossary.js';
import chatRouter from './routes/chat.js';
import referencesRouter from './routes/references.js';
import promptPoolRouter from './routes/prompt-pool.js';
const app = express();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const projectRoot = join(__dirname, '..');
// ==================== 中间件配置 ====================
// JSON 解析
app.use(express.json({ limit: '50mb' }));
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
// CORS
app.use((req, res, next) => {
const origin = req.headers.origin || '*';
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key');
res.header('Access-Control-Expose-Headers', 'Content-Length, Content-Range');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
// 请求日志(开发环境)
if (process.env.NODE_ENV !== 'production') {
app.use((req, res, next) => {
console.log(`[Express] ${req.method} ${req.path}`);
next();
});
}
// 开发模式下让 Vite 代理过来的 PDF.js 静态资源可用。
app.use('/pdfjs', express.static(join(projectRoot, 'pdfjs')));
// ==================== 路由注册 ====================
// 健康检查(无需认证)
app.get('/health', async (req, res) => {
try {
// 测试数据库连接
await prisma.$queryRaw`SELECT 1`;
res.json({
status: 'ok',
database: 'connected',
authDisabled: process.env.AUTH_DISABLED === 'true',
timestamp: Date.now()
});
} catch (error) {
res.json({
status: 'ok',
database: 'disconnected',
authDisabled: process.env.AUTH_DISABLED === 'true',
timestamp: Date.now()
});
}
});
// 持久化路由(需要认证)
app.use('/api/documents', requireAuth, documentsRouter);
app.use('/api/user', requireAuth, userRouter);
app.use('/api/glossary', requireAuth, glossaryRouter);
app.use('/api/chat', requireAuth, chatRouter);
app.use('/api/references', requireAuth, referencesRouter);
app.use('/api/prompt-pool', requireAuth, promptPoolRouter);
// ==================== 错误处理 ====================
// 404
app.use((req, res) => {
res.status(404).json({ error: 'Not Found' });
});
// 统一错误处理
app.use((err, req, res, next) => {
console.error('[Express] Error:', err.message);
res.status(err.status || 500).json({
error: err.message || 'Internal Server Error'
});
});
export default app;