feat(aia): Integrate PromptService for 10 AI agents

Features:
- Migrate 10 agent prompts from hardcoded to database
- Add grayscale preview support (DRAFT/ACTIVE distribution)
- Implement 3-tier fallback (DB -> Cache -> Hardcoded)
- Add version management and rollback capability

Files changed:
- backend/scripts/migrate-aia-prompts.ts (new migration script)
- backend/src/common/prompt/prompt.fallbacks.ts (add AIA fallbacks)
- backend/src/modules/aia/services/agentService.ts (integrate PromptService)
- backend/src/modules/aia/services/conversationService.ts (pass userId)
- backend/src/modules/aia/types/index.ts (fix AgentStage type)

Documentation:
- docs/03-业务模块/AIA-AI智能问答/06-开发记录/2026-01-18-Prompt管理系统集成.md
- docs/02-通用能力层/00-通用能力层清单.md (add FileCard, Prompt management)
- docs/00-系统总体设计/00-系统当前状态与开发指南.md (update to v3.6)

Prompt codes:
- AIA_SCIENTIFIC_QUESTION, AIA_PICO_ANALYSIS, AIA_TOPIC_EVALUATION
- AIA_OUTCOME_DESIGN, AIA_CRF_DESIGN, AIA_SAMPLE_SIZE
- AIA_PROTOCOL_WRITING, AIA_METHODOLOGY_REVIEW
- AIA_PAPER_POLISH, AIA_PAPER_TRANSLATE

Tested: Migration script executed, all 10 prompts inserted successfully
This commit is contained in:
2026-01-18 15:48:53 +08:00
parent 66255368b7
commit 57fdc6ef00
290 changed files with 2950 additions and 106 deletions

View File

@@ -0,0 +1,92 @@
/**
* AIA 智能问答模块 - 附件控制器
* @module aia/controllers/attachmentController
*
* API 端点:
* - POST /api/v1/aia/conversations/:id/attachments 上传附件
*/
import type { FastifyRequest, FastifyReply } from 'fastify';
import { logger } from '../../../common/logging/index.js';
import * as attachmentService from '../services/attachmentService.js';
/**
* 从 JWT Token 获取用户 ID
*/
function getUserId(request: FastifyRequest): string {
const userId = (request as any).user?.userId;
if (!userId) {
throw new Error('User not authenticated');
}
return userId;
}
/**
* 上传附件
* POST /api/v1/aia/conversations/:id/attachments
*/
export async function uploadAttachment(
request: FastifyRequest<{
Params: { id: string };
}>,
reply: FastifyReply
) {
try {
const userId = getUserId(request);
const { id: conversationId } = request.params;
// 获取上传的文件
const data = await request.file();
if (!data) {
return reply.status(400).send({
code: -1,
error: {
code: 'VALIDATION_ERROR',
message: '请上传文件',
},
});
}
const buffer = await data.toBuffer();
logger.info('[AIA:AttachmentController] 上传附件', {
userId,
conversationId,
filename: data.filename,
mimetype: data.mimetype,
size: buffer.length,
});
const attachment = await attachmentService.uploadAttachment(
userId,
conversationId,
{
filename: data.filename,
mimetype: data.mimetype,
buffer,
}
);
return reply.send({
code: 0,
data: attachment,
});
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
logger.error('[AIA:AttachmentController] 上传附件失败', {
error: errorMessage,
stack: error instanceof Error ? error.stack : undefined,
});
return reply.status(500).send({
code: -1,
error: {
code: 'INTERNAL_ERROR',
message: errorMessage,
},
});
}
}