/** * IIT 质控驾驶舱路由 * * API: * - GET /api/v1/admin/iit-projects/:projectId/qc-cockpit 获取驾驶舱数据 * - GET /api/v1/admin/iit-projects/:projectId/qc-cockpit/records/:recordId 获取记录详情 * - GET /api/v1/admin/iit-projects/:projectId/qc-cockpit/report 获取质控报告 * - POST /api/v1/admin/iit-projects/:projectId/qc-cockpit/report/refresh 刷新质控报告 */ import { FastifyInstance } from 'fastify'; import { iitQcCockpitController } from './iitQcCockpitController.js'; export async function iitQcCockpitRoutes(fastify: FastifyInstance) { // 获取质控驾驶舱数据 fastify.get('/:projectId/qc-cockpit', { schema: { description: '获取质控驾驶舱数据(统计 + 热力图)', tags: ['IIT Admin - 质控驾驶舱'], params: { type: 'object', properties: { projectId: { type: 'string', description: 'IIT 项目 ID' }, }, required: ['projectId'], }, response: { 200: { type: 'object', properties: { success: { type: 'boolean' }, data: { type: 'object', properties: { stats: { type: 'object', properties: { qualityScore: { type: 'number' }, totalRecords: { type: 'number' }, passedRecords: { type: 'number' }, failedRecords: { type: 'number' }, warningRecords: { type: 'number' }, pendingRecords: { type: 'number' }, criticalCount: { type: 'number' }, queryCount: { type: 'number' }, deviationCount: { type: 'number' }, passRate: { type: 'number' }, topIssues: { type: 'array', items: { type: 'object', properties: { issue: { type: 'string' }, count: { type: 'number' }, severity: { type: 'string' }, }, }, }, }, }, heatmap: { type: 'object', properties: { columns: { type: 'array', items: { type: 'string' } }, rows: { type: 'array', items: { type: 'object', properties: { recordId: { type: 'string' }, status: { type: 'string' }, cells: { type: 'array', items: { type: 'object', properties: { formName: { type: 'string' }, status: { type: 'string' }, issueCount: { type: 'number' }, recordId: { type: 'string' }, }, }, }, }, }, }, }, }, lastUpdatedAt: { type: 'string' }, }, }, }, }, }, }, }, iitQcCockpitController.getCockpitData.bind(iitQcCockpitController)); // 获取记录质控详情 fastify.get('/:projectId/qc-cockpit/records/:recordId', { schema: { description: '获取单条记录的质控详情(含 LLM Trace)', tags: ['IIT Admin - 质控驾驶舱'], params: { type: 'object', properties: { projectId: { type: 'string', description: 'IIT 项目 ID' }, recordId: { type: 'string', description: '记录 ID' }, }, required: ['projectId', 'recordId'], }, querystring: { type: 'object', properties: { formName: { type: 'string', description: '表单名称' }, }, }, response: { 200: { type: 'object', properties: { success: { type: 'boolean' }, data: { type: 'object', properties: { recordId: { type: 'string' }, formName: { type: 'string' }, status: { type: 'string' }, data: { type: 'object', additionalProperties: true }, fieldMetadata: { type: 'object', additionalProperties: true }, issues: { type: 'array', items: { type: 'object', properties: { field: { type: 'string' }, ruleName: { type: 'string' }, message: { type: 'string' }, severity: { type: 'string' }, actualValue: {}, expectedValue: { type: 'string' }, confidence: { type: 'string' }, }, }, }, llmTrace: { type: 'object', properties: { promptSent: { type: 'string' }, responseReceived: { type: 'string' }, model: { type: 'string' }, latencyMs: { type: 'number' }, }, }, entryTime: { type: 'string' }, }, }, }, }, }, }, }, iitQcCockpitController.getRecordDetail.bind(iitQcCockpitController)); // 获取质控报告 fastify.get('/:projectId/qc-cockpit/report', { schema: { description: '获取质控报告(支持 JSON 和 XML 格式)', tags: ['IIT Admin - 质控驾驶舱'], params: { type: 'object', properties: { projectId: { type: 'string', description: 'IIT 项目 ID' }, }, required: ['projectId'], }, querystring: { type: 'object', properties: { format: { type: 'string', enum: ['json', 'xml'], default: 'json', description: '响应格式:json(默认)或 xml(LLM 友好格式)', }, }, }, response: { 200: { type: 'object', properties: { success: { type: 'boolean' }, data: { type: 'object', properties: { projectId: { type: 'string' }, reportType: { type: 'string' }, generatedAt: { type: 'string' }, expiresAt: { type: 'string' }, summary: { type: 'object', properties: { totalRecords: { type: 'number' }, completedRecords: { type: 'number' }, criticalIssues: { type: 'number' }, warningIssues: { type: 'number' }, pendingQueries: { type: 'number' }, passRate: { type: 'number' }, lastQcTime: { type: 'string' }, }, }, criticalIssues: { type: 'array' }, warningIssues: { type: 'array' }, formStats: { type: 'array' }, llmFriendlyXml: { type: 'string' }, }, }, }, }, }, }, }, iitQcCockpitController.getReport.bind(iitQcCockpitController)); // 刷新质控报告 fastify.post('/:projectId/qc-cockpit/report/refresh', { schema: { description: '强制刷新质控报告(忽略缓存)', tags: ['IIT Admin - 质控驾驶舱'], params: { type: 'object', properties: { projectId: { type: 'string', description: 'IIT 项目 ID' }, }, required: ['projectId'], }, response: { 200: { type: 'object', properties: { success: { type: 'boolean' }, data: { type: 'object' }, }, }, }, }, }, iitQcCockpitController.refreshReport.bind(iitQcCockpitController)); // AI 工作时间线 fastify.get('/:projectId/qc-cockpit/timeline', iitQcCockpitController.getTimeline.bind(iitQcCockpitController)); // 重大事件列表 fastify.get('/:projectId/qc-cockpit/critical-events', iitQcCockpitController.getCriticalEvents.bind(iitQcCockpitController)); // 质控趋势(近N天通过率折线) fastify.get('/:projectId/qc-cockpit/trend', iitQcCockpitController.getTrend.bind(iitQcCockpitController)); }