Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/02-技术设计/数据库设计文档-DC模块(完整版).md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
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%)
2026-01-14 19:15:01 +08:00

438 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# <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>憟窯 |
**蝝<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
```
**蝝<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>憭梯揖
**蝝<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 蝝<E89D9D><EFBCB7>𡑒”
| 銵典<E98AB5> | 蝝<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>?