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%)
438 lines
13 KiB
Markdown
438 lines
13 KiB
Markdown
# <20>唳旿摨栞挽霈⊥<E99C88>獢?- 撌亙<E6928C>B嚗<42><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>箏膥鈭綽<E988AD>
|
||
|
||
> **璅∪<E79285>**: DC<44>唳旿皜<E697BF><E79A9C><EFBFBD>渡<EFBFBD> - 撌亙<E6928C>B
|
||
> **<2A><>𧋦**: V2.0 (MVP)
|
||
> **Schema**: `dc_schema`
|
||
> **<2A>湔鰵<E6B994>交<EFBFBD>**: 2025-12-03
|
||
> **<2A>嗆<EFBFBD>?*: <20>?MVP摰峕<E691B0>嚗<EFBFBD>歇撉諹<E69289><E8ABB9>舐鍂嚗𣬚<E59A97>摰墧㺭<E5A2A7>格<EFBFBD>霂閖<E99C82>朞<EFBFBD>嚗?
|
||
---
|
||
|
||
## <20><> <20>桀<EFBFBD>
|
||
|
||
- [銝<><E98A9D><EFBFBD><EFBFBD>餈財(#銝<EFBFBD>璁<EFBFBD>膩)
|
||
- [鈭䎚<EFBFBD><EFBFBD>chema霈曇恣<EFBFBD>笔<EFBFBD>](#鈭众chema霈曇恣<E69B87>笔<EFBFBD>)
|
||
- [銝剹<EFBFBD><EFBFBD>㺭<EFBFBD>株”霈曇恣](#銝㗇㺭<E39787>株”霈曇恣)
|
||
- [<5B>䜘<EFBFBD><E49C98>揣撘閗挽霈((#<23>𤤿揣撘閗挽霈?
|
||
- [鈭𢛵<E988AD><F0A29BB5><EFBFBD><EFBFBD>桃漲<E6A183>篏(#鈭𥪜<EFBFBD><EFBFBD>桃漲<EFBFBD>?
|
||
- [<5B>准<EFBFBD><E58786>㺭<EFBFBD>桃<EFBFBD><E6A183>賢𪂹<E8B3A2>篏(#<23>剜㺭<E5899C>桃<EFBFBD><E6A183>賢𪂹<E8B3A2>?
|
||
|
||
---
|
||
|
||
## 銝<><E98A9D><EFBFBD><EFBFBD>餈?
|
||
### 1.1 霈曇恣<E69B87>格<EFBFBD>
|
||
|
||
撌亙<EFBFBD>B<EFBFBD><EFBFBD>㺭<EFBFBD>桀<EFBFBD>霈曇恣<EFBFBD>典銁<EFBFBD>舀<EFBFBD>嚗?- <20>?<3F><>之璅∪<E79285>鈭文<E988AD>撉諹<E69289><E8ABB9><EFBFBD><EFBFBD><EFBFBD>祉<EFBFBD><E7A589><EFBFBD><EFBFBD>
|
||
- <20>?憭扯<E686AD>璅∪<E79285>甇乩遙<E4B9A9>∪<EFBFBD><E288AA><EFBFBD><EFBFBD>1000+<2B>∟扇敶𤏪<E695B6>
|
||
- <20>?<3F>脩<EFBFBD>璉<EFBFBD>瘚衤<E7989A>鈭箏極鋆<E6A5B5><E98B86>
|
||
- <20>?憸<>挽璅⊥踎蝞∠<E89D9E>銝𤾸<E98A9D><F0A4BEB8>?- <20>?<3F>亙熒璉<E78692><E79289>亦<EFBFBD>摮䀝<E691AE><E4809D>?
|
||
### 1.2 銵典<E98AB5>蝟餅<E89D9F>餉<EFBFBD>
|
||
|
||
```
|
||
dc_schema <20>?撌脣<E6928C>撱箏僎餈鞱<E9A488>銝?<3F>鎿<EFBFBD><E98EBF><EFBFBD> dc_health_checks [<5B>亙熒璉<E78692><E79289>亦<EFBFBD>摮𤊓 <20>?餈鞱<E9A488>甇<EFBFBD>虜
|
||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> dc_templates [憸<>挽璅⊥踎] <20>?3銝芷<E98A9D>霈暹芋<E69AB9>踹虾<E8B8B9>?<3F>鎿<EFBFBD><E98EBF><EFBFBD> dc_extraction_tasks [<5B>𣂼<EFBFBD>隞餃𦛚] <20>?撌脣<E6928C><E884A3>𣂼<EFBFBD>銝芯遙<E88AAF>?<3F>? <20>婙<EFBFBD><E5A999><EFBFBD> dc_extraction_items [<5B>𣂼<EFBFBD>霈啣<E99C88>] (1:N) <20>?<3F>峕芋<E5B395>讠<EFBFBD><E8AEA0>𨀣迤撣訾<E692A3>摮?```
|
||
|
||
**<2A>?MVP摰峕<E691B0><E5B395>嗆<EFBFBD><E59786><EFBFBD>2025-12-03嚗?*嚗?- <20><><EFBFBD>㕑”甇<E2809D>虜撌乩<E6928C>嚗<EFBFBD>歇憭<E6AD87><E686AD>憭帋葵<E5B88B>笔<EFBFBD>隞餃𦛚
|
||
- 3銝芷<E98A9D>霈暹芋<E69AB9>選<EFBFBD><E981B8>箇<EFBFBD><E7AE87><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD><E4BA99><EFBFBD><EFBFBD>撠輻<E692A0><E8BCBB>仿堺霈啣<E99C88><E595A3><EFBFBD><EFBFBD>銵<EFBFBD><E98AB5>钅秄霂羓<E99C82><E7BE93>?- <20>笔<EFBFBD>瘚贝<E7989A>嚗?<3F>∠<EFBFBD><E288A0><EFBFBD>㺭<EFBFBD>格<EFBFBD><E6A0BC>𡝗<EFBFBD><F0A19D97><EFBFBD><EFBFBD>100%<25>𣂼<EFBFBD><F0A382BC>?- <20>峕芋<E5B395>讠<EFBFBD><E8AEA0>頣<EFBFBD>resultA<74><41>esultB<74><42>inalResult摮埈挾甇<E68CBE>虜靽嘥<E99DBD>
|
||
- Token蝏蠘恣嚗魩otalTokens摮埈挾甇<E68CBE>虜蝝臬<E89D9D>
|
||
- <20>脩<EFBFBD>璉<EFBFBD>瘚页<E7989A>conflictFields<64>啁<EFBFBD>甇<EFBFBD>虜撌乩<E6928C>
|
||
- 撉諹<E69289><E8ABB9>𡁏𧋦嚗䫤backend/scripts/check-task-progress.mjs`
|
||
|
||
### 1.3 <20><><EFBFBD>舀<EFBFBD>
|
||
|
||
- **<2A>唳旿摨?*: PostgreSQL 15
|
||
- **ORM**: Prisma 6
|
||
- **Schema<6D>𠉛氖**: `dc_schema`嚗<>𡠺蝡见𦶢<E8A781>滨征<E6BBA8>湛<EFBFBD>
|
||
- **JSON摮埈挾**: 雿輻鍂JSONB蝐餃<E89D90>嚗<EFBFBD><E59A97><EFBFBD>扯<EFBFBD><E689AF>亥砭嚗?
|
||
---
|
||
|
||
## 鈭䎚<E988AD><E48E9A>chema霈曇恣<E69B87>笔<EFBFBD>
|
||
|
||
### 2.1 Schema<6D>𠉛氖
|
||
|
||
```sql
|
||
-- <20><><EFBFBD>㕑”雿輻鍂dc_schema<6D>賢<EFBFBD>蝛粹𡢿
|
||
CREATE TABLE "dc_schema"."dc_health_checks" (...);
|
||
CREATE TABLE "dc_schema"."dc_extraction_tasks" (...);
|
||
```
|
||
|
||
**隡睃飵**嚗?- <20>?銝𤾸<E98A9D>隞𡝗芋<F0A19D97>堒<EFBFBD><E5A092>券<EFBFBD>蝳鳴<E89DB3>platform_schema<6D><61>sl_schema蝑㚁<E89D91>
|
||
- <20>?<3F>唳旿摰匧<E691B0>嚗屸<E59A97><E5B1B8>滩秤<E6BBA9>滢<EFBFBD>
|
||
- <20>?靘蹂<E99D98>璅∪<E79285><E288AA>𣇉恣<F0A38789><E681A3><EFBFBD>餈<EFBFBD>宏
|
||
|
||
### 2.2 <20>賢<EFBFBD>閫<EFBFBD><E996AB>
|
||
|
||
| 閫<><E996AB> | 霂湔<E99C82> | 蝷箔<E89DB7> |
|
||
|------|------|------|
|
||
| **銵典<E98AB5><E585B8>滨<EFBFBD>** | `dc_` | `dc_extraction_tasks` |
|
||
| **摮埈挾<E59F88>賢<EFBFBD>** | snake_case | `user_id`, `source_file_key` |
|
||
| **<EFBFBD>園𡢿<EFBFBD>?* | 蝏煺<E89D8F><E785BA>𡒊<EFBFBD> | `created_at`, `started_at` |
|
||
| **憭㚚睸** | 摰硺<E691B0><E7A1BA>䇭id | `task_id`, `user_id` |
|
||
|
||
### 2.3 JSONB摮埈挾雿輻鍂<E8BCBB>箸艶
|
||
|
||
| 摮埈挾 | 蝐餃<E89D90> | <20>笔<EFBFBD> |
|
||
|------|------|------|
|
||
| `target_fields` | JSONB | <20>菜暑<E88F9C><E69A91><EFBFBD>畾菟<E795BE>蝵?|
|
||
| `result_a/result_b` | JSONB | <20>冽<EFBFBD><E586BD><EFBFBD><EFBFBD>𣇉<EFBFBD><F0A38789>?|
|
||
| `final_result` | JSONB | <20><>蝏<EFBFBD><E89D8F><EFBFBD>喟<EFBFBD><E5969F>?|
|
||
|
||
---
|
||
|
||
## 銝剹<E98A9D><E589B9>㺭<EFBFBD>株”霈曇恣
|
||
|
||
### 3.1 dc_health_checks嚗<73><E59A97>摨瑟<E691A8><E7919F>亦<EFBFBD>摮䁅”嚗?
|
||
**<2A>券<EFBFBD>?*: 蝻枏<E89DBB><E69E8F>亙熒璉<E78692><E79289>亦<EFBFBD><E4BAA6>頣<EFBFBD><E9A0A3>踹<EFBFBD><E8B8B9>滚<EFBFBD>霈∠<E99C88>
|
||
|
||
```sql
|
||
CREATE TABLE "dc_schema"."dc_health_checks" (
|
||
"id" TEXT NOT NULL PRIMARY KEY,
|
||
"user_id" TEXT NOT NULL,
|
||
"file_name" TEXT NOT NULL,
|
||
"column_name" TEXT NOT NULL,
|
||
|
||
-- 蝏蠘恣<E8A098><E681A3><EFBFBD>
|
||
"empty_rate" DOUBLE PRECISION NOT NULL,
|
||
"avg_length" DOUBLE PRECISION NOT NULL,
|
||
"total_rows" INTEGER NOT NULL,
|
||
"estimated_tokens" INTEGER NOT NULL,
|
||
|
||
-- 璉<><E79289>亦<EFBFBD><E4BAA6>? "status" TEXT NOT NULL, -- 'good' | 'bad'
|
||
"message" TEXT NOT NULL,
|
||
|
||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
```
|
||
|
||
**摮埈挾霂湔<E99C82>**嚗?
|
||
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> | 蝷箔<E89DB7> |
|
||
|------|------|------|------|
|
||
| `id` | TEXT | UUID銝駁睸 | `uuid()` |
|
||
| `user_id` | TEXT | <20>冽<EFBFBD>ID | `user-123` |
|
||
| `file_name` | TEXT | <20><>辣<EFBFBD>?| `<60><><EFBFBD><EFBFBD>㺭<EFBFBD>?xlsx` |
|
||
| `column_name` | TEXT | 璉<><E79289>亦<EFBFBD><E4BAA6>堒<EFBFBD> | `<60><><EFBFBD><EFBFBD><EFBFBD>𧋦` |
|
||
| `empty_rate` | DOUBLE | 蝛箏<E89D9B>潛<EFBFBD> (0-1) | 0.15 (15%) |
|
||
| `avg_length` | DOUBLE | 撟喳<E6929F><E596B3><EFBFBD>𧋦<EFBFBD>踹漲 | 256.8 |
|
||
| `total_rows` | INT | <20>餉<EFBFBD><E9A489>?| 500 |
|
||
| `estimated_tokens` | INT | 憸<>摯Token<65>?| 150000 |
|
||
| `status` | TEXT | <20>亙熒<E4BA99>嗆<EFBFBD>?| `good` / `bad` |
|
||
| `message` | TEXT | <20>鞟內靽⊥<E99DBD> | `<60>亙熒摨西<E691A8>憟窯 |
|
||
|
||
**蝝W<E89D9D>**嚗?```sql
|
||
CREATE INDEX "dc_health_checks_user_id_file_name_idx"
|
||
ON "dc_schema"."dc_health_checks"("user_id", "file_name");
|
||
```
|
||
|
||
**銝𡁜𦛚閫<F0A69B9A><E996AB>**嚗?- 蝛箏<E89D9B>潛<EFBFBD> > 80% <20>?`status = 'bad'`
|
||
- 撟喳<E6929F><E596B3>踹漲 < 10 <20>?`status = 'bad'`
|
||
- 蝻枏<E89DBB><E69E8F>㗇<EFBFBD><E39787><EFBFBD><EFBFBD>24撠𤩺𧒄嚗<F0A79284><E59A97><EFBFBD>典<EFBFBD>摰䂿緵嚗?
|
||
---
|
||
|
||
### 3.2 dc_templates嚗<73><E59A97>霈暹芋<E69AB9>輯”嚗?
|
||
**<2A>券<EFBFBD>?*: 摮睃<E691AE><E79D83>曄<EFBFBD>蝐餃<E89D90><E9A483><EFBFBD><EFBFBD>霈暹<E99C88><E69AB9>𡝗芋<F0A19D97>?
|
||
```sql
|
||
CREATE TABLE "dc_schema"."dc_templates" (
|
||
"id" TEXT NOT NULL PRIMARY KEY,
|
||
"disease_type" TEXT NOT NULL, -- 'lung_cancer', 'diabetes', 'hypertension'
|
||
"report_type" TEXT NOT NULL, -- 'pathology', 'admission', 'outpatient'
|
||
"display_name" TEXT NOT NULL, -- '<27>箇<EFBFBD><E7AE87><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD>'
|
||
"fields" JSONB NOT NULL, -- [{name, desc, width}]
|
||
"prompt_template" TEXT NOT NULL,
|
||
|
||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
"updated_at" TIMESTAMP(3) NOT NULL,
|
||
|
||
CONSTRAINT "dc_templates_disease_type_report_type_key"
|
||
UNIQUE ("disease_type", "report_type")
|
||
);
|
||
```
|
||
|
||
**摮埈挾霂湔<E99C82>**嚗?
|
||
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> | 蝷箔<E89DB7> |
|
||
|------|------|------|------|
|
||
| `disease_type` | TEXT | <20>曄<EFBFBD>蝐餃<E89D90> | `lung_cancer` |
|
||
| `report_type` | TEXT | <20>亙<EFBFBD>蝐餃<E89D90> | `pathology` |
|
||
| `display_name` | TEXT | <20>曄內<E69B84>滨妍 | `<EFBFBD>箇<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD>` |
|
||
| `fields` | JSONB | <20>𣂼<EFBFBD>摮埈挾<E59F88>滨蔭 | 閫<><E996AB><EFBFBD>寧內靘?|
|
||
| `prompt_template` | TEXT | Prompt璅⊥踎 | `霂瑚<EFBFBD>隞乩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD>銝剜<EFBFBD><EFBFBD>?..` |
|
||
|
||
**fields摮埈挾蝏𤘪<E89D8F>**嚗?```json
|
||
[
|
||
{
|
||
"name": "<22><><EFBFBD>蝐餃<E89D90>",
|
||
"desc": "憒<><E68692>瘚豢隋<E8B1A2>扯<EFBFBD><E689AF>䎚<EFBFBD><E48E9A><EFBFBD><EFBFBD>嗥<EFBFBD><E597A5>䂿<EFBFBD>",
|
||
"width": "w-40"
|
||
},
|
||
{
|
||
"name": "<22><><EFBFBD>蝔见漲",
|
||
"desc": "擃?銝?雿𤾸<E99BBF><F0A4BEB8>?,
|
||
"width": "w-32"
|
||
}
|
||
]
|
||
```
|
||
|
||
**<2A>臭<EFBFBD>蝥行<E89DA5>**嚗?```sql
|
||
UNIQUE ("disease_type", "report_type")
|
||
```
|
||
<EFBFBD>䔶<EFBFBD><EFBFBD>曄<EFBFBD>+<2B>亙<EFBFBD>蝐餃<E89D90>蝏<EFBFBD><E89D8F><EFBFBD>芾<EFBFBD><E88ABE>劐<EFBFBD>銝芣芋<E88AA3>?
|
||
---
|
||
|
||
### 3.3 dc_extraction_tasks嚗<73><E59A97><EFBFBD>碶遙<E7A2B6>∟”嚗?
|
||
**<2A>券<EFBFBD>?*: 蝞∠<E89D9E><E288A0>寥<EFBFBD><E5AFA5>𣂼<EFBFBD>隞餃𦛚嚗諹蕭頦芾<E9A0A6>摨血<E691A8><E8A180>鞉𧋦
|
||
|
||
```sql
|
||
CREATE TABLE "dc_schema"."dc_extraction_tasks" (
|
||
"id" TEXT NOT NULL PRIMARY KEY,
|
||
"user_id" TEXT NOT NULL,
|
||
"project_name" TEXT NOT NULL,
|
||
"source_file_key" TEXT NOT NULL, -- Storage銝剔<E98A9D>頝臬<E9A09D>
|
||
"text_column" TEXT NOT NULL,
|
||
|
||
-- 璅⊥踎<E28AA5>滨蔭
|
||
"disease_type" TEXT NOT NULL,
|
||
"report_type" TEXT NOT NULL,
|
||
"target_fields" JSONB NOT NULL,
|
||
|
||
-- <20>峕芋<E5B395>钅<EFBFBD>蝵? "model_a" TEXT NOT NULL DEFAULT 'deepseek-v3',
|
||
"model_b" TEXT NOT NULL DEFAULT 'qwen3-72b',
|
||
|
||
-- 隞餃𦛚<E9A483>嗆<EFBFBD>? "status" TEXT NOT NULL DEFAULT 'pending',
|
||
"total_count" INTEGER NOT NULL DEFAULT 0,
|
||
"processed_count" INTEGER NOT NULL DEFAULT 0,
|
||
"clean_count" INTEGER NOT NULL DEFAULT 0,
|
||
"conflict_count" INTEGER NOT NULL DEFAULT 0,
|
||
"failed_count" INTEGER NOT NULL DEFAULT 0,
|
||
|
||
-- <20>鞉𧋦蝏蠘恣
|
||
"total_tokens" INTEGER NOT NULL DEFAULT 0,
|
||
"total_cost" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||
|
||
-- <20>躰秤靽⊥<E99DBD>
|
||
"error" TEXT,
|
||
|
||
-- <20>園𡢿<E59C92>? "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
"started_at" TIMESTAMP(3),
|
||
"completed_at" TIMESTAMP(3)
|
||
);
|
||
```
|
||
|
||
**摮埈挾霂湔<E99C82>**嚗?
|
||
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> | 蝷箔<E89DB7> |
|
||
|------|------|------|------|
|
||
| `source_file_key` | TEXT | Storage頝臬<E9A09D> | `uploads/user123/data.xlsx` |
|
||
| `text_column` | TEXT | <20><>𧋦<EFBFBD>堒<EFBFBD> | `<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦` |
|
||
| `target_fields` | JSONB | <20>𣂼<EFBFBD>摮埈挾 | `[{name, desc}]` |
|
||
| `status` | TEXT | 隞餃𦛚<E9A483>嗆<EFBFBD>?| `pending/processing/completed/failed` |
|
||
| `total_count` | INT | <20>餉扇敶閙㺭 | 500 |
|
||
| `processed_count` | INT | 撌脣<E6928C><E884A3><EFBFBD>㺭 | 250 |
|
||
| `clean_count` | INT | 銝<><E98A9D>湔㺭 | 200 |
|
||
| `conflict_count` | INT | <20>脩<EFBFBD><E884A9>?| 45 |
|
||
| `failed_count` | INT | 憭梯揖<E6A2AF>?| 5 |
|
||
| `total_tokens` | INT | <20>蓉oken<65>?| 150000 |
|
||
| `total_cost` | DOUBLE | <20>餅<EFBFBD><E9A485>?$) | 0.27 |
|
||
|
||
**<2A>嗆<EFBFBD><E59786><EFBFBD>頧?*嚗?```
|
||
pending <20>?processing <20>?completed
|
||
<20>?failed
|
||
```
|
||
|
||
**蝝W<E89D9D>**嚗?```sql
|
||
CREATE INDEX "dc_extraction_tasks_user_id_status_idx"
|
||
ON "dc_schema"."dc_extraction_tasks"("user_id", "status");
|
||
```
|
||
|
||
---
|
||
|
||
### 3.4 dc_extraction_items嚗<73><E59A97><EFBFBD>𤥁扇敶閗”嚗?
|
||
**<2A>券<EFBFBD>?*: 摮睃<E691AE>瘥𤩺辺霈啣<E99C88><E595A3><EFBFBD><EFBFBD>璅∪<E79285><E288AA>𣂼<EFBFBD>蝏𤘪<E89D8F><F0A498AA><EFBFBD><EFBFBD>蝒<EFBFBD>𠶖<EFBFBD>?
|
||
```sql
|
||
CREATE TABLE "dc_schema"."dc_extraction_items" (
|
||
"id" TEXT NOT NULL PRIMARY KEY,
|
||
"task_id" TEXT NOT NULL,
|
||
|
||
-- <20>笔<EFBFBD><E7AC94>唳旿
|
||
"row_index" INTEGER NOT NULL,
|
||
"original_text" TEXT NOT NULL,
|
||
|
||
-- <20>峕芋<E5B395>讠<EFBFBD><E8AEA0>? "result_a" JSONB,
|
||
"result_b" JSONB,
|
||
|
||
-- <20>脩<EFBFBD>璉<EFBFBD>瘚? "status" TEXT NOT NULL DEFAULT 'pending',
|
||
"conflict_fields" TEXT[] DEFAULT ARRAY[]::TEXT[],
|
||
|
||
-- <20><>蝏<EFBFBD><E89D8F><EFBFBD>? "final_result" JSONB,
|
||
|
||
-- Token蝏蠘恣
|
||
"tokens_a" INTEGER NOT NULL DEFAULT 0,
|
||
"tokens_b" INTEGER NOT NULL DEFAULT 0,
|
||
|
||
-- <20>躰秤靽⊥<E99DBD>
|
||
"error" TEXT,
|
||
|
||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
"resolved_at" TIMESTAMP(3),
|
||
|
||
CONSTRAINT "dc_extraction_items_task_id_fkey"
|
||
FOREIGN KEY ("task_id")
|
||
REFERENCES "dc_schema"."dc_extraction_tasks"("id")
|
||
ON DELETE CASCADE
|
||
);
|
||
```
|
||
|
||
**摮埈挾霂湔<E99C82>**嚗?
|
||
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> | 蝷箔<E89DB7> |
|
||
|------|------|------|------|
|
||
| `row_index` | INT | Excel銵<6C>噡 | 5 |
|
||
| `original_text` | TEXT | <20>笔<EFBFBD><E7AC94><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦 | `<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘀<EFBFBD>45撗?..` |
|
||
| `result_a` | JSONB | DeepSeek蝏𤘪<E89D8F> | `{"<22>輻𠈔憭批<E686AD>": "3cm"}` |
|
||
| `result_b` | JSONB | Qwen蝏𤘪<E89D8F> | `{"<22>輻𠈔憭批<E686AD>": "3.0cm"}` |
|
||
| `status` | TEXT | 憭<><E686AD><EFBFBD>嗆<EFBFBD>?| `clean/conflict/resolved/failed` |
|
||
| `conflict_fields` | TEXT[] | <20>脩<EFBFBD>摮埈挾<E59F88>𡑒” | `["<22>輻𠈔憭批<E686AD>"]` |
|
||
| `final_result` | JSONB | <20><>蝏<EFBFBD><E89D8F><EFBFBD>喟<EFBFBD><E5969F>?| `{"<22>輻𠈔憭批<E686AD>": "3cm"}` |
|
||
|
||
**result_a/result_b蝏𤘪<E89D8F>蝷箔<E89DB7>**嚗?```json
|
||
{
|
||
"<22><><EFBFBD>蝐餃<E89D90>": "瘚豢隋<E8B1A2>扯<EFBFBD><E689AF>?,
|
||
"<22><><EFBFBD>蝔见漲": "銝剖<E98A9D><E58996>?,
|
||
"<22>輻𠈔憭批<E686AD>": "3cm",
|
||
"瘛见毀蝏栞蓮蝘?: "<22>?
|
||
}
|
||
```
|
||
|
||
**<2A>嗆<EFBFBD><E59786>秩<EFBFBD>?*嚗?- `pending`: 蝑匧<E89D91>憭<EFBFBD><E686AD>
|
||
- `clean`: <20>峕芋<E5B395>讠<EFBFBD><E8AEA0>靝<EFBFBD><E99D9D>?- `conflict`: 摮睃銁<E79D83>脩<EFBFBD>嚗屸<E59A97>鈭箏極鋆<E6A5B5><E98B86>
|
||
- `resolved`: <20>脩<EFBFBD>撌脰圾<E884B0>?- `failed`: <20>𣂼<EFBFBD>憭梯揖
|
||
|
||
**蝝W<E89D9D>**嚗?```sql
|
||
CREATE INDEX "dc_extraction_items_task_id_status_idx"
|
||
ON "dc_schema"."dc_extraction_items"("task_id", "status");
|
||
```
|
||
|
||
**憭㚚睸蝥行<E89DA5>**嚗?- `ON DELETE CASCADE`: <20>𣳇膄隞餃𦛚<E9A483>嗉䌊<E59789>典<EFBFBD><E585B8>斗<EFBFBD><E69697>㕑扇敶?
|
||
---
|
||
|
||
## <20>䜘<EFBFBD><E49C98>揣撘閗挽霈?
|
||
### 4.1 蝝W<E89D9D><EFBCB7>𡑒”
|
||
|
||
| 銵典<E98AB5> | 蝝W<E89D9D>摮埈挾 | 蝐餃<E89D90> | <20>券<EFBFBD>?|
|
||
|------|---------|------|------|
|
||
| `dc_health_checks` | `(user_id, file_name)` | 憭滚<E686AD> | <20>亥砭<E4BAA5>冽<EFBFBD><E586BD><EFBFBD><EFBFBD><EFBFBD>脫<EFBFBD><E884AB>?|
|
||
| `dc_templates` | `(disease_type, report_type)` | <20>臭<EFBFBD> | <20>脫迫<E884AB>滚<EFBFBD>璅⊥踎 |
|
||
| `dc_extraction_tasks` | `(user_id, status)` | 憭滚<E686AD> | <20>亥砭<E4BAA5>冽<EFBFBD><E586BD><EFBFBD>遙<EFBFBD>∪<EFBFBD>銵?|
|
||
| `dc_extraction_items` | `(task_id, status)` | 憭滚<E686AD> | <20>亥砭隞餃𦛚<E9A483><F0A69B9A>扇敶訫<E695B6>銵?|
|
||
|
||
### 4.2 <20>扯<EFBFBD><E689AF><EFBFBD><EFBFBD>
|
||
|
||
**<2A>亥砭隡睃<E99AA1>**嚗?```sql
|
||
-- 擃䀹<E69383><E480B9>亥砭嚗𡁜⏚<F0A1819C>函揣撘?SELECT * FROM dc_extraction_tasks
|
||
WHERE user_id = 'user123' AND status = 'processing';
|
||
|
||
-- 擃䀹<E69383><E480B9>亥砭嚗𡁜⏚<F0A1819C>函揣撘?SELECT * FROM dc_extraction_items
|
||
WHERE task_id = 'task456' AND status = 'conflict';
|
||
```
|
||
|
||
**<2A>踹<EFBFBD><E8B8B9>刻”<E588BB>急<EFBFBD>**嚗?- <20>?憪讠<E686AA><E8AEA0>汾HERE摮𣂼蘂銝剖<E98A9D><E58996>怎揣撘訫<E69298>畾?- <20>?雿輻鍂`status`摮埈挾餈<E68CBE>誘<EFBFBD>臭誑<E887AD>曇<EFBFBD><E69B87>誩<EFBFBD><E8AAA9>急<EFBFBD>銵峕㺭
|
||
|
||
---
|
||
|
||
## 鈭𢛵<E988AD><F0A29BB5><EFBFBD><EFBFBD>桃漲<E6A183>?
|
||
### 5.1 蝥扯<E89DA5><E689AF>𣳇膄
|
||
|
||
```sql
|
||
ALTER TABLE "dc_schema"."dc_extraction_items"
|
||
ADD CONSTRAINT "dc_extraction_items_task_id_fkey"
|
||
FOREIGN KEY ("task_id")
|
||
REFERENCES "dc_schema"."dc_extraction_tasks"("id")
|
||
ON DELETE CASCADE;
|
||
```
|
||
|
||
**銵䔶蛹**嚗?- <20>𣳇膄隞餃𦛚 <20>?<3F>芸𢆡<E88AB8>𣳇膄<F0A3B387><E88684><EFBFBD>匧<EFBFBD><E58CA7>𠉛<EFBFBD><F0A0899B>𣂼<EFBFBD>霈啣<E99C88>
|
||
- 靽肽<E99DBD><E882BD>唳旿銝<E697BF><E98A9D>湔<EFBFBD>?
|
||
### 5.2 <20>惩<EFBFBD><E683A9>桃<EFBFBD>銵?
|
||
- `dc_health_checks`: <20>祉<EFBFBD>銵剁<E98AB5><E58981>惩<EFBFBD><E683A9>?- `dc_templates`: <20>祉<EFBFBD>銵剁<E98AB5><E58981>惩<EFBFBD><E683A9>?- `dc_extraction_tasks`: <20>惩<EFBFBD><E683A9>殷<EFBFBD>user_id隞<64>蛹<EFBFBD><E89BB9><EFBFBD>嚗䔶<E59A97>撘箏<E69298><E7AE8F>唾<EFBFBD>嚗?
|
||
**<2A>笔<EFBFBD>**嚗?- <20>?<3F>誩<EFBFBD>頝沒chema靘肽<E99D98>
|
||
- <20>?<3F>鞾<EFBFBD>璅∪<E79285><E288AA>祉<EFBFBD><E7A589>?- <20>?蝞<><E89D9E>𤥁<EFBFBD>蝘餃<E89D98><E9A483>墧<EFBFBD>
|
||
|
||
---
|
||
|
||
## <20>准<EFBFBD><E58786>㺭<EFBFBD>桃<EFBFBD><E6A183>賢𪂹<E8B3A2>?
|
||
### 6.1 <20>唳旿靽萘<E99DBD>蝑𣇉裦
|
||
|
||
| 銵典<E98AB5> | 靽萘<E99DBD><E89098>園𡢿 | 皜<><E79A9C>蝑𣇉裦 |
|
||
|------|---------|---------|
|
||
| `dc_health_checks` | 7憭?| 摰𡁏<E691B0>皜<EFBFBD><E79A9C><EFBFBD>扯扇敶?|
|
||
| `dc_templates` | 瘞訾<E7989E> | <20>见𢆡蝞∠<E89D9E> |
|
||
| `dc_extraction_tasks` | 90憭?| 敶埝﹝<E59F9D>𤾸<EFBFBD><F0A4BEB8>?|
|
||
| `dc_extraction_items` | 90憭?| <20>譍遙<E8AD8D>∪<EFBFBD><E288AA>?|
|
||
|
||
### 6.2 敶埝﹝蝑𣇉裦
|
||
|
||
**憭找遙<E689BE>∪<EFBFBD>獢?* (> 1000<30>∟扇敶?嚗?1. 隞餃𦛚摰峕<E691B0><E5B395>𠬍<EFBFBD>撖澆枂蝏𤘪<E89D8F><F0A498AA>蚓SV/Excel
|
||
2. 銝𠹺<E98A9D><F0A0B9BA>訕torage嚗<65>偶銋<E581B6><E98A8B>摮矋<E691AE>
|
||
3. <20>𣳇膄<F0A3B387>唳旿摨栞扇敶𤏪<E695B6><F0A48FAA>𦠜𦆮蝛粹𡢿嚗?
|
||
### 6.3 皜<><E79A9C><EFBFBD>𡁏𧋦嚗<F0A78BA6>內靘页<E99D98>
|
||
|
||
```typescript
|
||
// 皜<><E79A9C>7憭拙<E686AD><E68B99><EFBFBD><EFBFBD>摨瑟<E691A8><E7919F>亥扇敶?await prisma.dCHealthCheck.deleteMany({
|
||
where: {
|
||
createdAt: {
|
||
lt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||
}
|
||
}
|
||
});
|
||
|
||
// 敶埝﹝90憭拙<E686AD><E68B99><EFBFBD>歇摰峕<E691B0>隞餃𦛚
|
||
const oldTasks = await prisma.dCExtractionTask.findMany({
|
||
where: {
|
||
status: 'completed',
|
||
completedAt: {
|
||
lt: new Date(Date.now() - 90 * 24 * 60 * 60 * 1000)
|
||
}
|
||
},
|
||
include: { items: true }
|
||
});
|
||
|
||
// 撖澆枂<E6BE86>𤾸<EFBFBD><F0A4BEB8>?for (const task of oldTasks) {
|
||
await exportTaskToStorage(task);
|
||
await prisma.dCExtractionTask.delete({ where: { id: task.id } });
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 銝<><E98A9D><EFBFBD>㺭<EFBFBD>桀<EFBFBD><E6A180>?
|
||
### 7.1 PII靽脲擪
|
||
|
||
**<2A>𤩺<EFBFBD>摮埈挾**嚗?- `original_text`: <20>航<EFBFBD><E888AA><EFBFBD>鉄<EFBFBD><E98984><EFBFBD><EFBFBD><EFBFBD><EFBFBD>溻<EFBFBD><E6BABB>澈隞質<E99A9E><E8B3AA>?- `result_a/result_b/final_result`: <20>航<EFBFBD><E888AA><EFBFBD>鉄蝏𤘪<E89D8F><F0A498AA>𣇉<EFBFBD><F0A38789>𤩺<EFBFBD>靽⊥<E99DBD>
|
||
|
||
**靽脲擪<E884B2>芣鴌**嚗?- <20>?<3F>煾<EFBFBD><E785BE>LM<4C>滩䌊<E6BBA9>刻<EFBFBD><E588BB>𧶏<EFBFBD>PIIMaskUtil嚗?- <20>?<3F>唳旿摨枏<E691A8>撖<EFBFBD><E69296>PostgreSQL SSL嚗?- <20>?摰𡁏<E691B0>皜<EFBFBD><E79A9C><EFBFBD><EFBFBD>蟮<EFBFBD>唳旿
|
||
|
||
### 7.2 <20>冽<EFBFBD><E586BD>𠉛氖
|
||
|
||
**<2A>箏<EFBFBD>**嚗?- <20><><EFBFBD>㕑”<E39591><E2809D>鉄`user_id`摮埈挾
|
||
- 摨𠉛鍂撅<E98D82>撩<EFBFBD>嗉<EFBFBD>皛歹<E79A9B>`WHERE user_id = currentUserId`
|
||
- 瘞訾<E7989E>頝函鍂<E587BD>瑟䰻霂?
|
||
---
|
||
|
||
## <20>怒<EFBFBD><E68092><EFBFBD>敶?
|
||
### 8.1 摰峕㟲Schema DDL
|
||
|
||
摰峕㟲<EFBFBD><EFBFBD>chema<EFBFBD>𥕦遣<EFBFBD>𡁏𧋦雿滢<EFBFBD>嚗?```
|
||
backend/prisma/migrations/20251127_add_dc_tool_b_tables/migration.sql
|
||
```
|
||
|
||
### 8.2 Prisma璅∪<E79285>摰帋<E691B0>
|
||
|
||
摰峕㟲<EFBFBD><EFBFBD>risma璅∪<EFBFBD>摰帋<EFBFBD>雿滢<EFBFBD>嚗?```
|
||
backend/prisma/schema.prisma
|
||
```
|
||
<EFBFBD>𦦵揣 `dc_schema` <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>㗇芋<E39787>卝<EFBFBD>?
|
||
### 8.3 <20>䀹凒<E480B9><E58792>蟮
|
||
|
||
| <20><>𧋦 | <20>交<EFBFBD> | <20>䀹凒<E480B9><E58792>捆 |
|
||
|------|------|---------|
|
||
| V1.0 | 2025-11-27 | <20>嘥<EFBFBD><E598A5><EFBFBD>𧋦嚗?銝芾” |
|
||
|
||
---
|
||
|
||
**<EFBFBD><EFBFBD>﹝蝏𤘪<EFBFBD>** <20>?
|