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

@@ -46,6 +46,7 @@ model User {
updatedAt DateTime @updatedAt @map("updated_at")
tenant_members tenant_members[]
user_modules user_modules[]
iitUserMappings IitUserMapping[]
departments departments? @relation(fields: [department_id], references: [id])
tenants tenants @relation(fields: [tenant_id], references: [id])
@@ -950,17 +951,21 @@ model IitProject {
lastSyncAt DateTime? @map("last_sync_at")
cronEnabled Boolean @default(false) @map("cron_enabled")
cronExpression String? @map("cron_expression")
isDemo Boolean @default(false) @map("is_demo")
status String @default("active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deletedAt DateTime? @map("deleted_at")
tenantId String? @map("tenant_id")
auditLogs IitAuditLog[]
pendingActions IitPendingAction[]
taskRuns IitTaskRun[]
userMappings IitUserMapping[]
tenant tenants? @relation(fields: [tenantId], references: [id])
@@index([status, deletedAt])
@@index([knowledgeBaseId], map: "idx_iit_project_kb")
@@index([tenantId])
@@map("projects")
@@schema("iit_schema")
}
@@ -1022,6 +1027,7 @@ model IitUserMapping {
id String @id @default(uuid())
projectId String @map("project_id")
systemUserId String @map("system_user_id")
userId String? @map("user_id")
redcapUsername String @map("redcap_username")
wecomUserId String? @map("wecom_user_id")
miniProgramOpenId String? @unique @map("mini_program_open_id")
@@ -1030,11 +1036,13 @@ model IitUserMapping {
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
project IitProject @relation(fields: [projectId], references: [id])
user User? @relation(fields: [userId], references: [id])
@@unique([projectId, systemUserId])
@@unique([projectId, redcapUsername])
@@index([wecomUserId])
@@index([miniProgramOpenId])
@@index([userId])
@@map("user_mappings")
@@schema("iit_schema")
}
@@ -1763,6 +1771,7 @@ model tenants {
tenant_quotas tenant_quotas[]
users User[]
user_modules user_modules[]
iitProjects IitProject[]
@@index([code], map: "idx_tenants_code")
@@index([status], map: "idx_tenants_status")
@@ -1819,6 +1828,7 @@ enum UserRole {
HOSPITAL_ADMIN
PHARMA_ADMIN
DEPARTMENT_ADMIN
IIT_OPERATOR
USER
@@schema("platform_schema")