feat(iit): QC deep fix + V3.1 architecture plan + project member management

QC System Deep Fix:
- HardRuleEngine: add null tolerance + field availability pre-check (skipped status)
- SkillRunner: baseline data merge for follow-up events + field availability check
- QcReportService: record-level pass rate calculation + accurate LLM XML report
- iitBatchController: legacy log cleanup (eventId=null) + upsert RecordSummary
- seed-iit-qc-rules: null/empty string tolerance + applicableEvents config

V3.1 Architecture Design (docs only, no code changes):
- QC engine V3.1 plan: 5-level data structure (CDISC ODM) + D1-D7 dimensions
- Three-batch implementation strategy (A: foundation, B: bubbling, C: new engines)
- Architecture team review: 4 whitepapers reviewed + feedback doc + 4 critical suggestions
- CRA Agent strategy roadmap + CRA 4-tool explanation doc for clinical experts

Project Member Management:
- Cross-tenant member search and assignment (remove tenant restriction)
- IIT project detail page enhancement with tabbed layout (KB + members)
- IitProjectContext for business-side project selection
- System-KB route access control adjustment for project operators

Frontend:
- AdminLayout sidebar menu restructure
- IitLayout with project context provider
- IitMemberManagePage new component
- Business-side pages adapt to project context

Prisma:
- 2 new migrations (user-project RBAC + is_demo flag)
- Schema updates for project member management

Made-with: Cursor
This commit is contained in:
2026-03-01 15:27:05 +08:00
parent c3f7d54fdf
commit 0b29fe88b5
61 changed files with 6877 additions and 524 deletions

View File

@@ -19,8 +19,8 @@ import {
import { authenticate, requireRoles } from '../../../common/auth/auth.middleware.js';
export async function systemKbRoutes(fastify: FastifyInstance) {
// 所有路由都需要认证 + SUPER_ADMIN ADMIN 角色
const preHandler = [authenticate, requireRoles('SUPER_ADMIN', 'ADMIN')];
// 认证 + 角色守卫:SUPER_ADMIN / ADMIN / IIT_OPERATOR 均可完整操作知识库
const preHandler = [authenticate, requireRoles('SUPER_ADMIN', 'ADMIN', 'IIT_OPERATOR')];
// ==================== 知识库 CRUD ====================

View File

@@ -298,7 +298,7 @@ export class SystemKbService {
try {
// 3. 生成 OSS 存储路径并上传
const ossKey = this.generateOssKey(kbId, doc.id, filename);
const ossKey = this.generateOssKey(kbId, doc.id, filename, kb.category);
const ossUrl = await storage.upload(ossKey, fileBuffer);
// 4. 更新 file_path
@@ -473,15 +473,15 @@ export class SystemKbService {
/**
* 生成 OSS 存储路径
*
* 格式:system/knowledge-bases/{kbId}/{docId}.{ext}
*
* @param kbId - 知识库 ID
* @param docId - 文档 ID
* @param filename - 原始文件名(用于获取扩展名)
* 系统知识库: system/knowledge-bases/{kbId}/{docId}.{ext}
* IIT 项目知识库: system/iit-knowledge-bases/{kbId}/{docId}.{ext}
*/
private generateOssKey(kbId: string, docId: string, filename: string): string {
private generateOssKey(kbId: string, docId: string, filename: string, category?: string | null): string {
const ext = path.extname(filename).toLowerCase();
return `system/knowledge-bases/${kbId}/${docId}${ext}`;
const prefix = category === 'iit_project'
? 'system/iit-knowledge-bases'
: 'system/knowledge-bases';
return `${prefix}/${kbId}/${docId}${ext}`;
}
/**