// server/api/records.get.ts - 最近问答记录接口,供 Nuxt Dashboard 表格展示 import { getQuery, setResponseStatus } from "h3"; import { invalidAccessTokenResponse, verifyAccessToken } from "~~/server/utils/auth"; import { createApiLogger } from "~~/server/utils/logging"; import { getQaRecords } from "~~/server/utils/runtimeState"; /** * 最近问答记录接口 * * 旧 Python Dashboard 直接在服务端模板里读取内存 records;迁移到 Nuxt 后, * 前端表格需要一个 JSON 数据源,所以这里暴露同样的内存记录副本。 * * 安全边界: * - 配置 ACCESS_TOKEN 时必须携带 `X-Access-Token` 或 query `token` * - 这里只返回题目、选项和最终答案,不包含 OpenAI 响应体、API Key 或内部错误 * - 记录仅存在当前进程内,重启或多实例部署不会共享 */ export default defineEventHandler((event) => { const logger = createApiLogger(event, "api.records"); if (!verifyAccessToken(event)) { setResponseStatus(event, 403); logger.warn("invalid_access_token"); return { success: false, message: invalidAccessTokenResponse().msg, records: [], page: 1, size: 10, total: 0 }; } const query = getQuery(event); const rawPage = Number.parseInt(query.page?.toString() || "1", 10); const rawSize = Number.parseInt(query.size?.toString() || "10", 10); const size = Number.isFinite(rawSize) ? Math.min(Math.max(rawSize, 1), 100) : 10; const records = getQaRecords(); const total = records.length; const maxPage = Math.max(1, Math.ceil(total / size)); const page = Number.isFinite(rawPage) ? Math.min(Math.max(rawPage, 1), maxPage) : 1; const start = (page - 1) * size; const pageRecords = records.slice(start, start + size); logger.info("finish_success", { page, size, total, count: pageRecords.length }); return { success: true, records: pageRecords, page, size, total }; });