31 lines
1.7 KiB
TypeScript
31 lines
1.7 KiB
TypeScript
import { Hono } from 'hono';
|
|
import type { AuthUser } from '../../auth/types.js';
|
|
import pool from '../../db.js';
|
|
import { vehicleRepository } from '../vehicles/repository.js';
|
|
import { MysqlHistoryStore } from './store.js';
|
|
import { HistoryService, HistoryInputError, HistoryPeriodUnavailable } from './service.js';
|
|
|
|
export const historyStore = new MysqlHistoryStore(pool);
|
|
// Published routes expose live data and verified snapshots only.
|
|
// The retired handover reconstruction remains an offline audit artifact.
|
|
export const historyService = new HistoryService(historyStore, () => vehicleRepository.getVehicles());
|
|
export function createHistoryRouter(service: Pick<HistoryService, 'trend' | 'details' | 'livePoint'> = historyService) {
|
|
const router = new Hono<{ Variables: { user: AuthUser } }>();
|
|
router.use('*', async (c, next) => {
|
|
c.header('Cache-Control', 'private, no-store');
|
|
if (!c.get('user')) return c.json({ error: 'Unauthorized' }, 401);
|
|
await next();
|
|
});
|
|
router.get('/trend', async c => c.json(await service.trend(c.get('user'), c.req.query())));
|
|
router.get('/live', async c => c.json(await service.livePoint(c.get('user'), c.req.query())));
|
|
router.get('/details', async c => c.json(await service.details(c.get('user'), c.req.query())));
|
|
router.onError((error, c) => {
|
|
if (error instanceof HistoryInputError) return c.json({ error: error.message }, 400);
|
|
if (error instanceof HistoryPeriodUnavailable) return c.json({ error: error.message }, 409);
|
|
console.error('[asset-history] read failed');
|
|
return c.json({ error: '资产历史数据暂不可用,请稍后重试' }, 503);
|
|
});
|
|
return router;
|
|
}
|
|
export default createHistoryRouter();
|