Major Changes: - Add StreamingService with OpenAI Compatible format - Upgrade Chat component V2 with Ant Design X integration - Implement AIA module with 12 intelligent agents - Update API routes to unified /api/v1 prefix - Update system documentation Backend (~1300 lines): - common/streaming: OpenAI Compatible adapter - modules/aia: 12 agents, conversation service, streaming integration - Update route versions (RVW, PKB to v1) Frontend (~3500 lines): - modules/aia: AgentHub + ChatWorkspace (100% prototype restoration) - shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook - Update API endpoints to v1 Documentation: - AIA module status guide - Universal capabilities catalog - System overview updates - All module documentation sync Tested: Stream response verified, authentication working Status: AIA V2.0 core completed (85%)
118 lines
4.8 KiB
Markdown
118 lines
4.8 KiB
Markdown
# **技术设计文档:工具 A \- 医疗数æ<C2B0>®è¶…级å<C2A7>ˆå¹¶å™?(The Super Merger)**
|
||
|
||
| 文档类型 | Technical Design Document (TDD) |
|
||
| :---- | :---- |
|
||
| **对应 PRD** | **PRD\_工具A\_超级å<C2A7>ˆå¹¶å™¨\_V2.md** |
|
||
| **版本** | **V2.0** (æž¶æž„å<E2809E>‡çº§ï¼šè®¿è§†åŸºå‡?\+ æ—¶é—´çª? |
|
||
| **状�* | Draft |
|
||
| **æ ¸å¿ƒç›®æ ‡** | 构建一个基äº?Web çš?ETL å·¥å…·ï¼Œè§£å†³ä¸´åºŠç§‘ç ”ä¸â€œä¸€å¯¹å¤šâ€<C3A2>æ•°æ<C2B0>®å¯¹é½<C3A9>难题,实现基于时间窗的精准å<E280A0>ˆå¹¶ã€?|
|
||
|
||
## **1\. 总体架构设计 (Architecture Overview)**
|
||
|
||
鉴于处ç<EFBFBD>† Excel 文件(解æž<C3A6>ã€<C3A3>å<EFBFBD>ˆå¹¶ã€<C3A3>写入)æ˜?CPU å¯†é›†åž‹å’Œå†…å˜æ•<C3A6>感型æ“<C3A6>作,为了é<E280A0>¿å…<C3A5>阻塞 Node.js 主线程,我们采用 **“异æ¥ä»»åŠ¡é˜Ÿåˆ?\+ æµ<C3A6>å¼<C3A5>处ç<E2809E>†â€?* 的架构模å¼<C3A5>ã€?
|
||
### **1.1 系统架构�*
|
||
|
||
graph TD
|
||
Client\[React å‰<C3A5>端 (Wizard UI)\]
|
||
|
||
subgraph API\_Server \[Fastify API æœ<C3A6>务\]
|
||
UploadAPI\[ä¸Šä¼ æŽ¥å<C2A5>£\]
|
||
TaskAPI\[任务状æ€<C3A6>接å<C2A5>£\]
|
||
ConfigAPI\[é…<C3A9>置接å<C2A5>£\]
|
||
end
|
||
|
||
subgraph Async\_Worker \[å<>Žå<C5BD>°å¤„ç<E2809E>† Worker\]
|
||
BullMQ\[BullMQ 队列\]
|
||
Merger\[智能å<C2BD>ˆå¹¶å¼•擎 (Time-Window Joiner)\]
|
||
ExcelParser\[ExcelJS è§£æž<C3A6>器\]
|
||
DateEngine\[日期归一化引擎\]
|
||
end
|
||
|
||
subgraph Storage \[æ•°æ<C2B0>®å˜å‚¨\]
|
||
PG\[(PostgreSQL 业务�\]
|
||
FileSys\[临时文件å˜å‚¨ (Local/S3)\]
|
||
Redis\[(Redis 缓å˜/队列)\]
|
||
end
|
||
|
||
Client \--1.ä¸Šä¼ æ–‡ä»¶--\> UploadAPI
|
||
UploadAPI \--ä¿<C3A4>å˜ä¸´æ—¶æ–‡ä»¶--\> FileSys
|
||
Client \--2.æ<><C3A6>交基准与时间窗é…<C3A9>ç½®--\> ConfigAPI
|
||
ConfigAPI \--创建任务--\> PG
|
||
ConfigAPI \--推入队列--\> BullMQ
|
||
BullMQ \--消费任务--\> Merger
|
||
Merger \--读å<C2BB>–辅表(å…¨é‡<C3A9>)--\> FileSys
|
||
Merger \--读å<C2BB>–主表(æµ<C3A6>å¼<C3A5>)--\> FileSys
|
||
Merger \--æµ<C3A6>å¼<C3A5>å<EFBFBD>ˆå¹¶ä¸Žå†™å…?-\> FileSys
|
||
Merger \--更新状�-\> PG
|
||
Client \--3.轮询/WS 进度--\> TaskAPI
|
||
Client \--4.下载结果--\> API\_Server
|
||
|
||
## **2\. 技术选型 (Tech Stack)**
|
||
|
||
åŸºäºŽçŽ°æœ‰æŠ€æœ¯æ ˆçš„é’ˆå¯¹æ€§é€‰æ‹©ï¼?
|
||
| 层级 | 技术组ä»?| 选型ç<E280B9>†ç”± |
|
||
| :---- | :---- | :---- |
|
||
| **å‰<C3A5>端** | **React 19 \+ Ant Design 5** | 利用 AntD çš?Steps, Upload, Tree (æ ‘çŠ¶é€‰æ‹©å™? 快速构å»?UIã€?|
|
||
| **å<>Žç«¯æ¡†æž¶** | **Fastify 5.x** | 高性能 HTTP 框架,适å<E2809A>ˆé«˜å¹¶å<C2B6>?I/Oã€?|
|
||
| **Excel 处ç<E2809E>†** | **ExcelJS** | **æ ¸å¿ƒç»„ä»¶**。支æŒ<C3A6>æµ<C3A6>å¼<C3A5>读å†?(Streaming I/O),这是处ç<E2809E>†å¤§æ•°æ<C2B0>®é‡<C3A9>ä¸<C3A4>崩的关键ã€?|
|
||
| **日期处ç<E2809E>†** | **Day.js \+ CustomParseFormat** | **新增**。处ç<E2809E>†â€œæ—¶é—´åœ°ç‹±â€<C3A2>çš„æ ¸å¿ƒåº“ï¼Œéœ€è¦<C3A8>æž<C3A6>强的容错解æž<C3A6>能力ã€?|
|
||
| **任务队列** | **BullMQ \+ Redis** | 必须异æ¥å¤„ç<E2809E>†ã€‚å<E2809A>ˆå¹¶é€»è¾‘å¤<C3A5>æ<EFBFBD>‚,耗时较长,必须用队列ã€?|
|
||
| **æ•°æ<C2B0>®åº?* | **PostgreSQL 15 \+ Prisma** | å˜å‚¨ä»»åŠ¡çŠ¶æ€<C3A6>ã€<C3A3>文件元数æ<C2B0>®ã€?*ä¸<C3A4>建议将原始 Excel æ•°æ<C2B0>®å˜å…¥ PG**ã€?|
|
||
| **验è¯<C3A8>åº?* | **Zod** | ç”¨äºŽæ ¡éªŒå‰<C3A5>端æ<C2AF><C3A6>交的å¤<C3A5>æ<EFBFBD>‚æ˜ å°„é…<C3A9>置结构ã€?|
|
||
|
||
### **2.1 关键技术决ç?(ADR): 为什么ä¸<C3A4>ç”?Python (Pandas)?**
|
||
|
||
虽然 Python Pandas 在数æ<C2B0>®å<C2AE>ˆå¹¶ä¸Šä»£ç <C3A7>更简æ´<C3A6>,但针å¯?*本工å…?*的场景,我们决定å<C5A1>šæŒ<C3A6>使用 **Node.js**,ç<C592>†ç”±å¦‚下:
|
||
|
||
1. **æµ<C3A6>å¼<C3A5>处ç<E2809E>†ä¼˜åŠ¿ï¼?* Pandas 倾å<C2BE>‘于全é‡<C3A9>åŠ è½½å†…å˜ï¼Œå®¹æ˜“ OOM。Node.js çš?Stream API 天然支æŒ<C3A6>背压,能稳定处ç<E2809E>†â€œæ•°æ<C2B0>®è†¨èƒ€â€<C3A2>问题ã€?
|
||
2. **架构一致性:** é<>¿å…<C3A5>引入 Python Runtime 带æ<C2A6>¥çš„è¿<C3A8>ç»´æˆ<C3A6>本和 IPC 开销ã€?
|
||
3. **结论ï¼?* 对于精确匹é…<C3A9>和逻辑清洗,Node.js 性能足够且更å<C2B4>¯æŽ§ã€?
|
||
## **3\. æ•°æ<C2B0>®åº“设è®?(Database Schema)**
|
||
|
||
### **Prisma Schema 定义**
|
||
|
||
// 任务状æ€<C3A6>æžšä¸?
|
||
enum TaskStatus {
|
||
PENDING
|
||
PROCESSING
|
||
COMPLETED
|
||
FAILED
|
||
}
|
||
|
||
// å<>ˆå¹¶ä»»åŠ¡è¡?
|
||
model MergeTask {
|
||
id String @id @default(uuid())
|
||
userId String
|
||
status TaskStatus @default(PENDING)
|
||
progress Int @default(0)
|
||
|
||
// æ ¸å¿ƒé…<C3A9>ç½®å—æ®µ (V2 æ›´æ–°)
|
||
// 结构: {
|
||
// anchorFileId: string,
|
||
// anchorKeys: { id: "ä½<C3A4>院å<C2A2>?, time: "入院日期" },
|
||
// window: { daysBefore: 7, daysAfter: 7 },
|
||
// files: \[{ id: "f2", timeCol: "报告时间", columns: \["白细�\] }\]
|
||
// }
|
||
config Json?
|
||
|
||
resultUrl String?
|
||
report Json? // è´¨é‡<C3A9>报告 { totalRows: 1000, dropped: 50, matchRate: "95%" }
|
||
errorMsg String?
|
||
createdAt DateTime @default(now())
|
||
|
||
files SourceFile\[\]
|
||
}
|
||
|
||
// æº<C3A6>文件表
|
||
model SourceFile {
|
||
id String @id @default(uuid())
|
||
taskId String
|
||
task MergeTask @relation(fields: \[taskId\], references: \[id\])
|
||
filename String
|
||
filepath String
|
||
headers Json // \["ä½<C3A4>院å<C2A2>?, "å§“å<E2809C><C3A5>", "入院日期"\]
|
||
rowCount Int
|
||
fileSize Int
|
||
uploadedAt DateTime @default(now())
|
||
}
|