Files
ln-bi/src/server/app.ts
T
dsh-agent 795fb207cb refactor(stage9): 后端业务域目录形状统一
- 每个域现在都是 src/server/routes/<domain>/ 目录:
  vehicles/routes.ts(原 routes/vehicles.ts)、vehicle-heatmap/{routes,model}.ts、
  hydrogen-heatmap/{routes,model}.ts、ele/routes.ts、feedback/routes.ts。
- 命名约定:index.ts 是聚合器(挂子路由),routes.ts 是叶子路由。mileage/energy/
  scheduling 保持 index.ts 聚合,其余统一为 routes.ts。
- 纯移动与改名,未改动任何 SQL、参数顺序、路由挂载前缀或处理器逻辑。
  import 改写由一次性 codemod 完成;vehicles/repository.test.ts 读取的源码路径同步更新。
- docs/ARCHITECTURE.md 补充"后端业务域形状"表,并如实标注 ele / feedback 尚未拆出
  repository(这两个域缺 SQL 指纹测试,建议先补测试再拆)。

lint / test(139) / build 全绿,可达性 0 未引用文件。
2026-09-11 10:30:54 +08:00

61 lines
2.5 KiB
TypeScript

import { serveStatic } from '@hono/node-server/serve-static';
import { Hono } from 'hono';
import { readOnlyMiddleware } from './middleware/read-only.js';
import { cors } from 'hono/cors';
import authRouter from './auth/login.js';
import { authMiddleware } from './middleware/auth.js';
import eleRouter from './routes/ele/routes.js';
import energyRouter from './routes/energy/index.js';
import feedbackRouter from './routes/feedback/routes.js';
import hydrogenHeatmapRouter from './routes/hydrogen-heatmap/routes.js';
import mileageRouter from './routes/mileage/index.js';
import schedulingRouter from './routes/scheduling/index.js';
import vehicleHeatmapRouter from './routes/vehicle-heatmap/routes.js';
import vehiclesRouter from './routes/vehicles/routes.js';
/**
* 创建 HTTP 应用,但不监听端口、不访问数据库,也不启动后台任务。
* 保持应用装配无副作用后,测试可以安全导入路由而不会挂住进程。
*/
export function createApp(): Hono {
const app = new Hono();
app.use('/api/*', cors());
app.use('/api/*', readOnlyMiddleware);
// 登录接口公开,其余 API 统一经过认证与数据权限检查。
app.route('/api/auth', authRouter);
app.use('/api/*', authMiddleware);
app.route('/api/vehicles', vehiclesRouter);
app.route('/api/mileage', mileageRouter);
app.route('/api/scheduling', schedulingRouter);
app.route('/api/energy', energyRouter);
app.route('/api/ele', eleRouter);
app.route('/api/feedback', feedbackRouter);
app.route('/api/vehicle-heatmap', vehicleHeatmapRouter);
app.route('/api/hydrogen-heatmap', hydrogenHeatmapRouter);
app.get('/api/health', (context) => context.json({
status: 'ok',
time: new Date().toISOString(),
}));
// 未匹配的 /api/* 必须返回 JSON 404。若落到下面的静态回退,会返回
// 200 + index.html,让前端 res.ok 为真、再在 res.json() 处抛解析错误,
// 把"路由不存在"伪装成数据问题。
app.all('/api/*', (context) => context.json({ error: 'Not Found' }, 404));
// 兜底错误处理:统一返回 JSON,避免把栈信息或 HTML 暴露给调用方。
app.onError((error, context) => {
console.error(`[server] unhandled error on ${context.req.method} ${context.req.path}:`, error);
return context.json({ error: 'Internal Server Error' }, 500);
});
// 生产环境由同一进程托管 Vite 构建产物,并回退到单页应用入口。
app.use('/*', serveStatic({ root: './dist' }));
app.use('/*', serveStatic({ root: './dist', path: 'index.html' }));
return app;
}