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%)
693 lines
17 KiB
Markdown
693 lines
17 KiB
Markdown
# <20>唳旿摨栞<E691A8><E6A09E>仿<EFBFBD>蝵?
|
||
> **<2A><>﹝<EFBFBD><EFB99D>𧋦嚗?* v1.0
|
||
> **<2A>𥕦遣<F0A595A6>交<EFBFBD>嚗?* 2025-11-09
|
||
> **蝏湔擪<E6B994><E693AA><EFBFBD>** <20>嗆<EFBFBD><E59786>a<EFBFBD>
|
||
> **<2A><><EFBFBD>擧凒<E693A7>堆<EFBFBD>** 2025-11-09
|
||
|
||
---
|
||
|
||
## <20><> <20><>﹝霂湔<E99C82>
|
||
|
||
<EFBFBD>祆<EFBFBD>獢<EFBFBD>扇敶笌chema<EFBFBD>𠉛氖<EFBFBD>嗆<EFBFBD>摰墧鴌<EFBFBD>詨<EFBFBD><EFBFBD><EFBFBD>㺭<EFBFBD>桀<EFBFBD>餈墧𦻖<EFBFBD>屸<EFBFBD>蝵桐縑<EFBFBD>荔<EFBFBD><EFBFBD><EFBFBD>𡠺嚗?- 敶枏<E695B6><E69E8F>唳旿摨梶𠶖<E6A2B6>?- Schema<6D>𠉛氖餈<E6B096>宏<EFBFBD>滨蔭
|
||
- 餈<>宏餈<E5AE8F><E9A488><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交䲮撘?- 撉諹<E69289><E8ABB9><EFBFBD><EFBFBD>皛𡁏䲮獢?
|
||
---
|
||
|
||
## <20><>儭?敶枏<E695B6><E69E8F>唳旿摨梶𠶖<E6A2B6>?
|
||
### <20>唳旿摨枏抅<E69E8F>砌縑<E7A08C>?
|
||
**餈墧𦻖靽⊥<E99DBD>嚗?*
|
||
```
|
||
<EFBFBD>唳旿摨梶掩<EFBFBD>页<EFBFBD>PostgreSQL 15+
|
||
<EFBFBD>唳旿摨枏<EFBFBD>蝘堆<EFBFBD>ai_clinical_research
|
||
銝餅㦤<EFBFBD>啣<EFBFBD>嚗? localhost
|
||
蝡臬藁嚗? 5432
|
||
<EFBFBD>冽<EFBFBD><EFBFBD>㵪<EFBFBD> postgres
|
||
撖<EFBFBD><EFBFBD>嚗? postgres
|
||
```
|
||
|
||
**摰峕㟲餈墧𦻖摮㛖泵銝莎<E98A9D>**
|
||
```
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
```
|
||
|
||
---
|
||
|
||
### 敶枏<E695B6>Schema蝏𤘪<E89D8F>
|
||
|
||
**<EFBFBD>唳<EFBFBD>Schema嚗?*
|
||
- <20>?**public** - <20><><EFBFBD>?3銝芾”<E88ABE>賢銁餈䠷<E9A488>
|
||
|
||
**銵冽<E98AB5><E586BD>𤏪<EFBFBD>13銝迎<E98A9D>嚗?*
|
||
|
||
#### 1. 撟喳蝱<E596B3>箇<EFBFBD>嚗?銝芾”嚗?```sql
|
||
public.users -- <20>冽<EFBFBD>銵?public.admin_logs -- 蝞∠<E89D9E><E288A0>亙<EFBFBD>
|
||
```
|
||
|
||
#### 2. AI<41>箄<EFBFBD><E7AE84>桃<EFBFBD>嚗?銝芾”嚗?```sql
|
||
public.projects -- 憿寧𤌍蝞∠<E89D9E>
|
||
public.conversations -- 憿寧𤌍撖寡<E69296>
|
||
public.messages -- 撖寡<E69296>瘨<EFBFBD><E798A8>
|
||
public.general_conversations -- <20>𡁶鍂撖寡<E69296>
|
||
public.general_messages -- <20>𡁶鍂瘨<E98D82><E798A8>
|
||
```
|
||
|
||
#### 3. 銝芯犖<E88AAF>亥<EFBFBD>摨橒<E691A8>2銝芾”嚗?```sql
|
||
public.knowledge_bases -- <20>亥<EFBFBD>摨?public.documents -- <20><>﹝
|
||
```
|
||
|
||
#### 4. <20>孵<EFBFBD><E5ADB5><EFBFBD>頂蝏<E9A082><E89D8F>3銝芾”嚗?```sql
|
||
public.batch_tasks -- <20>孵<EFBFBD><E5ADB5><EFBFBD>遙<EFBFBD>?public.batch_results -- <20>孵<EFBFBD><E5ADB5><EFBFBD><EFBFBD><EFBFBD>?public.task_templates -- 隞餃𦛚璅⊥踎
|
||
```
|
||
|
||
#### 5. 蝔蹂辣摰⊥䰻嚗?銝芾”嚗?```sql
|
||
public.review_tasks -- 摰⊥䰻隞餃𦛚
|
||
```
|
||
|
||
---
|
||
|
||
### <20>唳旿摨梶<E691A8>霈∩縑<E288A9>?
|
||
**銵冽㺭<E586BD>𧶏<EFBFBD>** 13銝?
|
||
**蝝W<E89D9D><EFBCB7>圈<EFBFBD>嚗?* 蝥?0銝?
|
||
**憭㚚睸蝥行<E89DA5>嚗?* 蝥?5銝?
|
||
|
||
**敶枏<E695B6><E69E8F>唳旿<E594B3>𧶏<EFBFBD>隡啁<E99AA1>嚗㚁<E59A97>**
|
||
- users: ~10<31>?- projects: ~20<32>?- conversations: ~50<35>?- messages: ~500<30>?- knowledge_bases: ~5<>?- documents: ~30<33>?- <20>嗡<EFBFBD>銵剁<E98AB5>瘚贝<E7989A><E8B49D>唳旿
|
||
|
||
**<2A>餅㺭<E9A485>桅<EFBFBD>嚗?* < 10MB嚗<42><E59A97>霂閧㴓憓<E3B493><E68693>
|
||
|
||
---
|
||
|
||
## <20>㴓 Schema<6D>𠉛氖<F0A0899B>格<EFBFBD><E6A0BC>嗆<EFBFBD>
|
||
|
||
### 10銝芰𡠺蝡喹chema
|
||
|
||
#### <20><>閬<EFBFBD>祕蝏<E7A595>挽霈?<3F>唳旿餈<E697BF>宏嚗?銝迎<E98A9D>
|
||
|
||
**1. platform_schema嚗<61>像<EFBFBD>啣抅蝖<E68A85>撅<EFBFBD><E69285>**
|
||
```sql
|
||
-- 餈<>宏銵剁<E98AB5>
|
||
public.users <20>?platform_schema.users
|
||
public.admin_logs <20>?platform_schema.admin_logs 嚗<><E59A97>蝻橒<E89DBB>敺<EFBFBD>&霈歹<E99C88>
|
||
```
|
||
|
||
**2. common_schema嚗<61><E59A97>𡁶鍂<F0A181B6>賢<EFBFBD>撅<EFBFBD><E69285>**
|
||
```sql
|
||
-- <20>啣遣銵剁<E98AB5>
|
||
common_schema.llm_usage -- LLM雿輻鍂霈啣<E99C88>
|
||
common_schema.feature_flags -- Feature Flags
|
||
```
|
||
|
||
**3. asl_schema嚗㇁I<E38781>箄<EFBFBD><E7AE84><EFBFBD>讃嚗?*
|
||
```sql
|
||
-- <20>啣遣銵剁<E98AB5>
|
||
asl_schema.literature_projects -- <20><>讃憿寧𤌍
|
||
asl_schema.pico_configs -- PICO<43>滨蔭
|
||
asl_schema.literature_items -- <20><>讃<EFBFBD>∠𤌍
|
||
-- <20>游<EFBFBD>銵刻<E98AB5>ASL霈曇恣<E69B87><E681A3>﹝
|
||
```
|
||
|
||
**4. aia_schema嚗㇁I<E38781>箄<EFBFBD><E7AE84>桃<EFBFBD>嚗?*
|
||
```sql
|
||
-- 餈<>宏銵剁<E98AB5>
|
||
public.projects <EFBFBD>?aia_schema.projects
|
||
public.conversations <EFBFBD>?aia_schema.conversations
|
||
public.messages <EFBFBD>?aia_schema.messages
|
||
public.general_conversations <EFBFBD>?aia_schema.general_conversations
|
||
public.general_messages <EFBFBD>?aia_schema.general_messages
|
||
```
|
||
|
||
**5. pkb_schema嚗<61>葵鈭箇䰻霂<E4B0BB><E99C82>嚗?*
|
||
```sql
|
||
-- 餈<>宏銵剁<E98AB5>
|
||
public.knowledge_bases <EFBFBD>?pkb_schema.knowledge_bases
|
||
public.documents <EFBFBD>?pkb_schema.documents
|
||
```
|
||
|
||
#### <20>芸<EFBFBD>撱箇征Schema嚗?銝迎<E98A9D>
|
||
|
||
**6. dc_schema嚗<61>㺭<EFBFBD>格<EFBFBD>瘣梹<E798A3>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
|
||
**7. rvw_schema嚗<61>恣蝔輻頂蝏<E9A082><E89D8F>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
|
||
**8. admin_schema嚗<61><E59A97><EFBFBD>亦恣<E4BAA6><E681A3><EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
|
||
**9. ssa_schema嚗<61>惣<EFBFBD>賜<EFBFBD>霈∪<E99C88><E288AA>琜<EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
|
||
**10. st_schema嚗<61><E59A97>霈∪<E99C88><E288AA>𣂼極<F0A382BC>瘀<EFBFBD>** - <20><><EFBFBD>銵函<E98AB5><E587BD>?
|
||
---
|
||
|
||
## <20><> 餈<>宏餈<E5AE8F><E9A488>餈墧𦻖<E5A2A7>滨蔭
|
||
|
||
### 餈<>宏<EFBFBD>滚<EFBFBD>憭?
|
||
**1. 憭<>遢敶枏<E695B6><E69E8F>唳旿摨?*
|
||
```bash
|
||
# Windows PowerShell
|
||
cd D:\MyCursor\AIclinicalresearch\backend
|
||
|
||
# 雿輻鍂pg_dump憭<70>遢
|
||
pg_dump -h localhost -U postgres -d ai_clinical_research -F c -f backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').dump
|
||
|
||
# <20>𤥁<EFBFBD><F0A4A581>蝙<EFBFBD>沒QL<51>澆<EFBFBD>
|
||
pg_dump -h localhost -U postgres -d ai_clinical_research > backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql
|
||
```
|
||
|
||
**2. 撉諹<E69289>憭<EFBFBD>遢**
|
||
```bash
|
||
# 璉<><E79289>亙<EFBFBD>隞賣<E99A9E>隞嗅之撠?ls -lh backup_*.dump
|
||
|
||
# 撉諹<E69289>憭<EFBFBD>遢<EFBFBD><E981A2>捆嚗𠄎QL<51>澆<EFBFBD>嚗?head -n 50 backup_*.sql
|
||
```
|
||
|
||
---
|
||
|
||
### 餈<>宏餈<E5AE8F><E9A488>餈墧𦻖<E5A2A7>孵<EFBFBD>
|
||
|
||
#### <20>孵<EFBFBD>1嚗帋蝙<E5B88B>沌risma Migrate嚗<65>綫<EFBFBD>琜<EFBFBD>
|
||
|
||
**餈墧𦻖<E5A2A7>滨蔭嚗?*
|
||
```env
|
||
# backend/.env
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
```
|
||
|
||
**<EFBFBD>扯<EFBFBD>餈<EFBFBD>宏嚗?*
|
||
```bash
|
||
cd backend
|
||
|
||
# <20>𥕦遣<F0A595A6>啁<EFBFBD>餈<EFBFBD>宏
|
||
npx prisma migrate dev --name schema_isolation_10_schemas
|
||
|
||
# <20>亦<EFBFBD>餈<EFBFBD>宏<EFBFBD>嗆<EFBFBD>?npx prisma migrate status
|
||
```
|
||
|
||
---
|
||
|
||
#### <20>孵<EFBFBD>2嚗𡁶凒<F0A181B6>交<EFBFBD>銵玺QL<51>𡁏𧋦
|
||
|
||
**餈墧𦻖<E5A2A7>孵<EFBFBD>嚗?*
|
||
```bash
|
||
# 雿輻鍂psql餈墧𦻖
|
||
psql -h localhost -U postgres -d ai_clinical_research
|
||
|
||
# <20>碶蝙<E7A2B6>函㴓憓<E3B493><E68693><EFBFBD>?export PGPASSWORD=postgres
|
||
psql -h localhost -U postgres -d ai_clinical_research -f migration_script.sql
|
||
```
|
||
|
||
**<EFBFBD>扯<EFBFBD>餈<EFBFBD>宏<EFBFBD>𡁏𧋦嚗?*
|
||
```bash
|
||
cd docs/09-<2D>嗆<EFBFBD>摰墧鴌/migration-scripts
|
||
|
||
# <20>厰◇摨𤩺<E691A8>銵?psql -h localhost -U postgres -d ai_clinical_research -f 001-create-all-10-schemas.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 002-migrate-platform.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 003-migrate-aia.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 004-migrate-pkb.sql
|
||
# ... <20>游<EFBFBD><E6B8B8>𡁏𧋦
|
||
```
|
||
|
||
---
|
||
|
||
#### <20>孵<EFBFBD>3嚗帋蝙<E5B88B>典虾閫<E899BE><E996AB>撌亙<E6928C>
|
||
|
||
**pgAdmin 4嚗?*
|
||
1. 餈墧𦻖靽⊥<E99DBD>嚗? - 銝餅㦤嚗饝ocalhost
|
||
- 蝡臬藁嚗?432
|
||
- <20>唳旿摨橒<E691A8>ai_clinical_research
|
||
- <20>冽<EFBFBD>嚗䮝ostgres
|
||
- 撖<><E69296>嚗䮝ostgres
|
||
|
||
2. <20>扯<EFBFBD>餈<EFBFBD>宏嚗? - <20>枏<EFBFBD>Query Tool
|
||
- <20>㰘蝸SQL<51>𡁏𧋦
|
||
- <20>扯<EFBFBD>
|
||
|
||
**DataGrip / DBeaver嚗?*
|
||
- <20>峕甅<E5B395><E79485><EFBFBD><EFBFBD>乩縑<E4B9A9>?- <20>舀<EFBFBD>鈭见𦛚蝞∠<E89D9E>
|
||
- <20>嫣噶<E5ABA3>墧<EFBFBD>
|
||
|
||
---
|
||
|
||
## <20>?餈<>宏撉諹<E69289>
|
||
|
||
### 1. 璉<><E79289>兄chema<6D>𥕦遣
|
||
|
||
**SQL撉諹<E69289>嚗?*
|
||
```sql
|
||
-- <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>农chema
|
||
SELECT schema_name
|
||
FROM information_schema.schemata
|
||
WHERE schema_name NOT IN ('pg_catalog', 'information_schema')
|
||
ORDER BY schema_name;
|
||
|
||
-- 憸<><E686B8>蝏𤘪<E89D8F>嚗?-- admin_schema
|
||
-- aia_schema
|
||
-- asl_schema
|
||
-- common_schema
|
||
-- dc_schema
|
||
-- pkb_schema
|
||
-- platform_schema
|
||
-- public
|
||
-- rvw_schema
|
||
-- ssa_schema
|
||
-- st_schema
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 璉<><E79289>亥”餈<E2809D>宏
|
||
|
||
**撉諹<E69289>platform_schema嚗?*
|
||
```sql
|
||
-- <20>亦<EFBFBD>銵?SELECT table_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'platform_schema';
|
||
|
||
-- 撉諹<E69289><E8ABB9>唳旿
|
||
SELECT COUNT(*) FROM platform_schema.users;
|
||
-- 憸<><E686B8>嚗帋<E59A97><E5B88B>㸆ublic.users<72><73>㺭<EFBFBD>譍<EFBFBD><E8AD8D>?```
|
||
|
||
**撉諹<EFBFBD>aia_schema嚗?*
|
||
```sql
|
||
-- <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>㕑”
|
||
SELECT table_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'aia_schema';
|
||
|
||
-- 撉諹<E69289><E8ABB9>唳旿摰峕㟲<E5B395>?SELECT COUNT(*) FROM aia_schema.projects;
|
||
SELECT COUNT(*) FROM aia_schema.conversations;
|
||
SELECT COUNT(*) FROM aia_schema.messages;
|
||
```
|
||
|
||
**撉諹<E69289>pkb_schema嚗?*
|
||
```sql
|
||
SELECT COUNT(*) FROM pkb_schema.knowledge_bases;
|
||
SELECT COUNT(*) FROM pkb_schema.documents;
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 撉諹<E69289>憭㚚睸<E39A9A>喟頂
|
||
|
||
**璉<><E79289>亥楊Schema憭㚚睸嚗?*
|
||
```sql
|
||
-- <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>匧<EFBFBD><E58CA7>桃漲<E6A183>?SELECT
|
||
tc.table_schema,
|
||
tc.table_name,
|
||
kcu.column_name,
|
||
ccu.table_schema AS foreign_table_schema,
|
||
ccu.table_name AS foreign_table_name,
|
||
ccu.column_name AS foreign_column_name
|
||
FROM information_schema.table_constraints AS tc
|
||
JOIN information_schema.key_column_usage AS kcu
|
||
ON tc.constraint_name = kcu.constraint_name
|
||
JOIN information_schema.constraint_column_usage AS ccu
|
||
ON ccu.constraint_name = tc.constraint_name
|
||
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||
AND tc.table_schema IN ('platform_schema', 'aia_schema', 'pkb_schema', 'asl_schema', 'common_schema')
|
||
ORDER BY tc.table_schema, tc.table_name;
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 撉諹<E69289>蝝W<E89D9D>
|
||
|
||
**璉<><E79289>亦揣撘閙糓<E99699>行迤蝖株<E89D96>蝘鳴<E89D98>**
|
||
```sql
|
||
-- <20>亦<EFBFBD><E4BAA6>𣂷葵Schema<6D><61><EFBFBD><EFBFBD>厩揣撘?SELECT
|
||
schemaname,
|
||
tablename,
|
||
indexname,
|
||
indexdef
|
||
FROM pg_indexes
|
||
WHERE schemaname = 'aia_schema'
|
||
ORDER BY tablename, indexname;
|
||
```
|
||
|
||
---
|
||
|
||
### 5. Prisma撉諹<E69289>
|
||
|
||
**<EFBFBD>湔鰵Prisma<EFBFBD>滨蔭<EFBFBD>𡡞<EFBFBD>霂<EFBFBD><EFBFBD>**
|
||
```bash
|
||
cd backend
|
||
|
||
# <20><><EFBFBD>Prisma Client
|
||
npx prisma generate
|
||
|
||
# 撉諹<E69289>Prisma Client<6E>舐鍂
|
||
npx ts-node -e "import { PrismaClient } from '@prisma/client'; const p = new PrismaClient(); p.user.count().then(console.log)"
|
||
```
|
||
|
||
---
|
||
|
||
## <20><> <20>墧<EFBFBD><E5A2A7>寞<EFBFBD>
|
||
|
||
### <20>箸艶1嚗朞<E59A97>蝘餉<E89D98>蝔衤葉<E8A1A4>𤑳緵<F0A491B3>桅<EFBFBD>
|
||
|
||
**蝡见朖<E8A781>墧<EFBFBD>嚗?*
|
||
```bash
|
||
# 憒<><E68692>雿輻鍂Prisma Migrate
|
||
npx prisma migrate reset
|
||
|
||
# <20>W<EFBFBD>憭<EFBFBD>遢
|
||
psql -h localhost -U postgres -d ai_clinical_research < backup_before_schema_migration_YYYYMMDD_HHMMSS.sql
|
||
```
|
||
|
||
---
|
||
|
||
### <20>箸艶2嚗朞<E59A97>蝘餃<E89D98><E9A483>𣂼<EFBFBD><F0A382BC>𤑳緵<F0A491B3>桅<EFBFBD>
|
||
|
||
**<EFBFBD>寞<EFBFBD>A嚗帋<EFBFBD>憭<EFBFBD>遢<EFBFBD>W<EFBFBD>嚗<EFBFBD>綫<EFBFBD>琜<EFBFBD>**
|
||
```bash
|
||
# 1. <20>𣳇膄敶枏<E695B6><E69E8F>唳旿摨?dropdb -h localhost -U postgres ai_clinical_research
|
||
|
||
# 2. <20>齿鰵<E9BDBF>𥕦遣
|
||
createdb -h localhost -U postgres ai_clinical_research
|
||
|
||
# 3. <20>W<EFBFBD>憭<EFBFBD>遢
|
||
pg_restore -h localhost -U postgres -d ai_clinical_research backup_before_schema_migration_YYYYMMDD_HHMMSS.dump
|
||
```
|
||
|
||
**<EFBFBD>寞<EFBFBD>B嚗𡁏<EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>斗鰵Schema嚗䔶<EFBFBD><EFBFBD>炠ublic**
|
||
```sql
|
||
-- <20>𣳇膄<F0A3B387>啣遣<E595A3><E981A3>chema嚗<61><E59A97><EFBFBD>㵪<EFBFBD>嚗?DROP SCHEMA IF EXISTS platform_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS aia_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS pkb_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS asl_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS common_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS dc_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS rvw_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS admin_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS ssa_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS st_schema CASCADE;
|
||
|
||
-- public schema<6D><61>”憒<E2809D><E68692>鋡怠<E98BA1><E680A0>支<EFBFBD>嚗䔶<E59A97>憭<EFBFBD>遢<EFBFBD>W<EFBFBD>
|
||
```
|
||
|
||
---
|
||
|
||
## <20><> 餈<>宏璉<E5AE8F><E79289>交<EFBFBD><E4BAA4>?
|
||
### 餈<>宏<EFBFBD>齿<EFBFBD><E9BDBF>?
|
||
- [ ] <20>?<3F>唳旿摨枏歇憭<E6AD87>遢嚗Ê̄ackup_before_schema_migration_*.dump嚗?- [ ] <20>?憭<>遢<EFBFBD><E981A2>辣撌脤<E6928C>霂?- [ ] <20>?Prisma<6D>滨蔭撌脫凒<E884AB>堆<EFBFBD>datasource.schemas嚗?- [ ] <20>?餈<>宏<EFBFBD>𡁏𧋦撌脣<E6928C>憭<EFBFBD><E686AD>001-010.sql嚗?- [ ] <20>?瘚贝<E7989A><E8B49D>臬<EFBFBD>撌脤<E6928C>霂<EFBFBD><E99C82>蝘餅郊撉?
|
||
---
|
||
|
||
### 餈<>宏銝剜<E98A9D><E5899C>?
|
||
- [ ] <20>?10銝杵chema<6D>𥕦遣<F0A595A6>𣂼<EFBFBD>
|
||
- [ ] <20>?銵刻<E98AB5>蝘餅<E89D98><E9A485>躰秤嚗?銝芣<E98A9D><E88AA3>唳旿<E594B3><E697BF>chema嚗?- [ ] <20>?<3F>唳旿摰峕㟲<E5B395>折<EFBFBD>霂<EFBFBD><E99C82>朞<EFBFBD>
|
||
- [ ] <20>?憭㚚睸蝥行<E89DA5>甇<EFBFBD>&
|
||
- [ ] <20>?蝝W<E89D9D>甇<EFBFBD>&<EFBFBD>𥕦遣
|
||
|
||
---
|
||
|
||
### 餈<>宏<EFBFBD>擧<EFBFBD><E693A7>?
|
||
- [ ] <20>?Prisma Client<6E><74><EFBFBD><EFBFBD>𣂼<EFBFBD>
|
||
- [ ] <20>?<3F>𡒊垢<F0A1928A>滚𦛚<E6BB9A>臬𢆡甇<F0A286A1>虜
|
||
- [ ] <20>?<3F>唳<EFBFBD><E594B3>蠘<EFBFBD>瘚贝<E7989A><E8B49D>朞<EFBFBD>嚗㇁IA<49><41>KB嚗?- [ ] <20>?API靚<49>鍂甇<E98D82>虜
|
||
- [ ] <20>?<3F>滨垢<E6BBA8>蠘<EFBFBD>甇<EFBFBD>虜
|
||
|
||
---
|
||
|
||
## <20>圲 撣貉<E692A3><E8B289>桅<EFBFBD>
|
||
|
||
### <20>桅<EFBFBD>1嚗锭chema<6D>𥕦遣憭梯揖
|
||
|
||
**<EFBFBD>躰秤嚗?*
|
||
```
|
||
ERROR: schema "platform_schema" already exists
|
||
```
|
||
|
||
**閫<><E996AB>嚗?*
|
||
```sql
|
||
-- 璉<><E79289>兄chema<6D>臬炏摮睃銁
|
||
SELECT schema_name FROM information_schema.schemata
|
||
WHERE schema_name = 'platform_schema';
|
||
|
||
-- 憒<><E68692>摮睃銁雿<E98A81>蛹蝛綽<E89D9B><E7B6BD>臬<EFBFBD><E887AC>日<EFBFBD>撱?DROP SCHEMA platform_schema CASCADE;
|
||
CREATE SCHEMA platform_schema;
|
||
```
|
||
|
||
---
|
||
|
||
### <20>桅<EFBFBD>2嚗𡁏㺭<F0A1818F>株<EFBFBD>蝘餃仃韐?
|
||
**<2A>躰秤嚗?*
|
||
```
|
||
ERROR: duplicate key value violates unique constraint
|
||
```
|
||
|
||
**閫<><E996AB>嚗?*
|
||
1. 璉<><E79289>交㺭<E4BAA4>格糓<E6A0BC>血歇<E8A180>典<EFBFBD>餈<EFBFBD>宏
|
||
2. 皜<><E79A9C><EFBFBD>格<EFBFBD>Schema
|
||
3. <20>齿鰵<E9BDBF>扯<EFBFBD>餈<EFBFBD>宏
|
||
|
||
---
|
||
|
||
### <20>桅<EFBFBD>3嚗𡁜<E59A97><F0A1819C>桃漲<E6A183>罸<EFBFBD>霂?
|
||
**<2A>躰秤嚗?*
|
||
```
|
||
ERROR: foreign key constraint "fk_user_id" cannot be implemented
|
||
```
|
||
|
||
**閫<><E996AB>嚗?*
|
||
1. 蝖桐<E89D96>鋡怠<E98BA1><E680A0>函<EFBFBD>銵典歇<E585B8><E6AD87><EFBFBD>蝘?2. 璉<><E79289>亙<EFBFBD><E4BA99>桀<EFBFBD>畾萇掩<E89087>见龪<E8A781>?3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>典<EFBFBD><E585B8>殷<EFBFBD>餈<EFBFBD>宏<EFBFBD>𡡞<EFBFBD>撱?
|
||
---
|
||
|
||
## <20>圲 鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098>交<EFBFBD><E4BAA4>滨蔭嚗?025-11-16 <20>啣<EFBFBD>嚗?
|
||
> **潃?<3F>滩<EFBFBD><E6BBA9>湔鰵**嚗帋蛹<E5B88B>舀<EFBFBD><E88880>輸<EFBFBD>鈭?Serverless <20>函蔡嚗峕鰵憓噼<E68693><E599BC>交<EFBFBD><E4BAA4>滨蔭
|
||
> **霂衣<E99C82><E8A1A3><EFBFBD>﹝**嚗靀撟喳蝱<E596B3>箇<EFBFBD>霈暹鴌閫<E9B48C><E996AB>](./04-撟喳蝱<E596B3>箇<EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md)
|
||
|
||
### <20>峕艶嚗帋蛹隞<E89BB9>銋<EFBFBD><E98A8B>閬<EFBFBD><E996AC><EFBFBD>交<EFBFBD>嚗?
|
||
**<2A>桅<EFBFBD><E6A185>箸艶**嚗?```
|
||
<EFBFBD>輸<EFBFBD>鈭?SAE <20>芸𢆡<E88AB8>拙捆嚗?- <20>嘥<EFBFBD>嚗?銝芸<E98A9D>靘页<E99D98>10銝芾<E98A9D><E88ABE>?- 擃睃陸嚗?00銝芸<E98A9D>靘页<E99D98>1000銝芾<E98A9D><E88ABE>?- RDS<44><53>憭扯<E686AD><E689AF>交㺭嚗?00 <20>?頞<><E9A09E>嚗?
|
||
蝏𤘪<EFBFBD>嚗𡁏㺭<EFBFBD>桀<EFBFBD>餈墧𦻖<EFBFBD>堒偷嚗<EFBFBD><EFBFBD><EFBFBD>典援皞?```
|
||
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗𡁜𢆡<F0A1819C><F0A286A1>恣蝞埈<E89D9E>摰硺<E691B0>餈墧𦻖<E5A2A7>?
|
||
```typescript
|
||
瘥誩<EFBFBD>靘贝<EFBFBD><EFBFBD>交㺭 = RDS<44><53>憭扯<E686AD><E689AF>交㺭 / SAE<41><45>憭批<E686AD>靘𧢲㺭
|
||
蝷箔<EFBFBD>嚗?00餈墧𦻖 / 20摰硺<E691B0> = 20餈墧𦻖/摰硺<E691B0>
|
||
```
|
||
|
||
---
|
||
|
||
### Prisma餈墧𦻖瘙𣳇<E79899>蝵?
|
||
**<2A><>辣雿滨蔭**嚗䫤backend/src/config/database.ts`
|
||
|
||
**<EFBFBD>滨蔭隞<EFBFBD><EFBFBD>**嚗?
|
||
```typescript
|
||
import { PrismaClient } from '@prisma/client'
|
||
|
||
// <20>冽<EFBFBD><E586BD>恣蝞𡑒<E89D9E><F0A19192>交㺭
|
||
const dbMaxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
|
||
const maxInstances = Number(process.env.MAX_INSTANCES) || 20
|
||
const connectionLimit = Math.floor(dbMaxConnections / maxInstances)
|
||
|
||
console.log(`<EFBFBD><EFBFBD> <20>唳旿摨栞<E691A8><E6A09E>交<EFBFBD><E4BAA4>滨蔭嚗𡁏<E59A97>摰硺<E691B0><E7A1BA><EFBFBD>憭?{connectionLimit}銝芾<E98A9D><E88ABE>匝)
|
||
|
||
// <20>𥕦遣<F0A595A6>典<EFBFBD>Prisma Client
|
||
export const prisma = new PrismaClient({
|
||
datasources: {
|
||
db: {
|
||
url: process.env.DATABASE_URL,
|
||
},
|
||
},
|
||
log: process.env.NODE_ENV === 'development'
|
||
? ['query', 'error', 'warn']
|
||
: ['error'],
|
||
errorFormat: 'minimal',
|
||
})
|
||
|
||
// 隡㗛<E99AA1><E3979B>喲𡡒餈墧𦻖
|
||
process.on('SIGTERM', async () => {
|
||
console.log('<27><> 甇<>銁<EFBFBD>喲𡡒<E596B2>唳旿摨栞<E691A8><E6A09E>?..')
|
||
await prisma.$disconnect()
|
||
console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙歇<E4BA99>喲𡡒')
|
||
process.exit(0)
|
||
})
|
||
|
||
process.on('SIGINT', async () => {
|
||
console.log('<27><> 甇<>銁<EFBFBD>喲𡡒<E596B2>唳旿摨栞<E691A8><E6A09E>?..')
|
||
await prisma.$disconnect()
|
||
console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙歇<E4BA99>喲𡡒')
|
||
process.exit(0)
|
||
})
|
||
|
||
// <20>臬𢆡<E887AC>嗆<EFBFBD>霂閗<E99C82><E99697>?prisma.$connect()
|
||
.then(() => console.log('<27>?<3F>唳旿摨栞<E691A8><E6A09E>交<EFBFBD><E4BAA4>?))
|
||
.catch((err) => {
|
||
console.error('<27>?<3F>唳旿摨栞<E691A8><E6A09E>亙仃韐?', err)
|
||
process.exit(1)
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
### <20>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>滨蔭
|
||
|
||
**<EFBFBD>砍𧑐撘<EFBFBD><EFBFBD>𤑳㴓憓?*嚗?
|
||
```bash
|
||
# backend/.env.development
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
|
||
# <20>砍𧑐撘<F0A79190><E69298>烐<EFBFBD><E78390><EFBFBD><EFBFBD>滨蔭餈墧𦻖瘙𩤃<E79899><F0A9A483>訫<EFBFBD>靘页<E99D98>
|
||
# DB_MAX_CONNECTIONS=N/A
|
||
# MAX_INSTANCES=N/A
|
||
```
|
||
|
||
**鈭𤑳垢<F0A491B3>煺漣<E785BA>臬<EFBFBD>**嚗?
|
||
```bash
|
||
# SAE<41>批<EFBFBD><E689B9>?-> <20>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>滨蔭
|
||
DATABASE_URL=postgresql://user:password@rm-xxx.aliyuncs.com:5432/prod_db
|
||
DB_MAX_CONNECTIONS=400 # <20>輸<EFBFBD>鈭駵DS<44><53>憭扯<E686AD><E689AF>交㺭
|
||
MAX_INSTANCES=20 # SAE<41><45>憭批<E686AD>靘𧢲㺭
|
||
```
|
||
|
||
**銝滚<E98A9D>RDS閫<53>聢<EFBFBD><E881A2><EFBFBD><EFBFBD>交㺭**嚗?
|
||
| RDS閫<53>聢 | <20><>憭扯<E686AD><E689AF>交㺭 | 撱箄悅SAE摰硺<E691B0><E7A1BA>?| 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 |
|
||
|---------|-----------|--------------|-------------|
|
||
| 2<>?GB | 200 | 10 | 20 |
|
||
| 4<>?GB | 400 | 20 | 20 |
|
||
| 8<>?6GB | 800 | 40 | 20 |
|
||
|
||
---
|
||
|
||
### <20>烐綉<E78390>唳旿摨栞<E691A8><E6A09E>交㺭
|
||
|
||
**摰墧𧒄<E5A2A7>亥砭餈墧𦻖<E5A2A7>?*嚗?
|
||
```typescript
|
||
// backend/src/common/monitoring/metrics.ts
|
||
import { prisma } from '@/config/database'
|
||
import { logger } from '@/common/logging'
|
||
|
||
export class DatabaseMetrics {
|
||
// <20>亥砭敶枏<E695B6>餈墧𦻖<E5A2A7>? static async getConnectionCount(): Promise<number> {
|
||
const result = await prisma.$queryRaw<Array<{ count: bigint }>>`
|
||
SELECT count(*) as count
|
||
FROM pg_stat_activity
|
||
WHERE datname = current_database()
|
||
`
|
||
return Number(result[0].count)
|
||
}
|
||
|
||
// <20>烐綉撟嗅<E6929F>霅? static async monitorConnections() {
|
||
const currentConnections = await this.getConnectionCount()
|
||
const maxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
|
||
const usagePercent = (currentConnections / maxConnections) * 100
|
||
|
||
logger.info('<27>唳旿摨栞<E691A8><E6A09E>亦<EFBFBD><E4BAA6>?, {
|
||
current: currentConnections,
|
||
max: maxConnections,
|
||
usage: `${usagePercent.toFixed(1)}%`
|
||
})
|
||
|
||
// <20>𡃏郎嚗朞<E59A97><E69C9E>交㺭頞<E3BAAD><E9A09E>80%
|
||
if (usagePercent > 80) {
|
||
logger.warn('<EFBFBD>𩤃<EFBFBD> <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交㺭<EFBFBD>𡃏郎', {
|
||
current: currentConnections,
|
||
max: maxConnections,
|
||
usage: `${usagePercent.toFixed(1)}%`,
|
||
action: '撱箄悅憓𧼮<EFBFBD>RDS閫<EFBFBD>聢<EFBFBD>硋<EFBFBD>撠騌AE摰硺<EFBFBD><EFBFBD>?
|
||
})
|
||
}
|
||
|
||
return { currentConnections, maxConnections, usagePercent }
|
||
}
|
||
}
|
||
```
|
||
|
||
**摰𡁏𧒄<F0A1818F>烐綉**嚗<>虾<EFBFBD>㚁<EFBFBD>嚗?
|
||
```typescript
|
||
// backend/src/index.ts
|
||
import { DatabaseMetrics } from '@/common/monitoring/metrics'
|
||
|
||
// 瘥?<3F><><EFBFBD><EFBFBD>烐綉銝<E7B689>甈?setInterval(async () => {
|
||
await DatabaseMetrics.monitorConnections()
|
||
}, 5 * 60 * 1000)
|
||
```
|
||
|
||
---
|
||
|
||
### <20><><EFBFBD><EFBFBD>埝䰻
|
||
|
||
**<EFBFBD>桅<EFBFBD>1嚗朞<EFBFBD><EFBFBD>交㺭<EFBFBD>堒偷**
|
||
|
||
**<EFBFBD><EFBFBD>𠶖**嚗?```
|
||
Error: P1001: Can't reach database server
|
||
Error: remaining connection slots are reserved
|
||
```
|
||
|
||
**<2A>笔<EFBFBD>**嚗?- SAE摰硺<E691B0><E7A1BA>啗<EFBFBD>憭?- 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭<E4BAA4>滨蔭餈<E894AD><E9A488>
|
||
- 摮睃銁餈墧𦻖瘜<F0A6BB96><E7989C>
|
||
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?```bash
|
||
# 1. <20>亦<EFBFBD>敶枏<E695B6>餈墧𦻖<E5A2A7>?SELECT count(*) FROM pg_stat_activity
|
||
WHERE datname = 'ai_clinical_research';
|
||
|
||
# 2. <20>亦<EFBFBD>餈墧𦻖<E5A2A7>交<EFBFBD>
|
||
SELECT client_addr, count(*)
|
||
FROM pg_stat_activity
|
||
WHERE datname = 'ai_clinical_research'
|
||
GROUP BY client_addr;
|
||
|
||
# 3. 靚<>㟲<EFBFBD>滨蔭
|
||
# <20>寞<EFBFBD>A嚗𡁜<E59A97>撠騌AE<41><45>憭批<E686AD>靘𧢲㺭
|
||
MAX_INSTANCES=10 # 隞?0<>嫣蛹10
|
||
|
||
# <20>寞<EFBFBD>B嚗𡁜<E59A97>蝥刪DS閫<53>聢
|
||
# 隞?<3F>?GB嚗?00餈墧𦻖嚗匧<E59A97>蝥批<E89DA5>4<EFBFBD>?GB嚗?00餈墧𦻖嚗?```
|
||
|
||
---
|
||
|
||
**<2A>桅<EFBFBD>2嚗朞<E59A97><E69C9E>交<EFBFBD>瞍?*
|
||
|
||
**<2A><>𠶖**嚗?- 餈墧𦻖<E5A2A7>唳<EFBFBD>蝏剖<E89D8F><E58996>?- <20>喃蝙瘚<E89D99><E7989A><EFBFBD>滢<EFBFBD>嚗諹<E59A97><E8ABB9>交㺭銝滢<E98A9D><E6BBA2>?
|
||
**<2A>埝䰻**嚗?```typescript
|
||
// <20>?<3F>躰秤嚗𡁏<E59A97>甈∪<E79488>撱箸鰵摰硺<E691B0>
|
||
function getUser() {
|
||
const prisma = new PrismaClient() // 餈墧𦻖瘜<F0A6BB96><E7989C>
|
||
return prisma.user.findMany()
|
||
}
|
||
|
||
// <20>?甇<>&嚗帋蝙<E5B88B>典<EFBFBD>撅<EFBFBD>摰硺<E691B0>
|
||
import { prisma } from '@/config/database'
|
||
|
||
function getUser() {
|
||
return prisma.user.findMany()
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### <20><>雿喳<E99BBF>頝?
|
||
**DO <20>?*嚗?1. <20>?雿輻鍂<E8BCBB>典<EFBFBD> `prisma` 摰硺<E691B0>
|
||
2. <20>?<3F>滨蔭 `SIGTERM` 隡㗛<E99AA1><E3979B>喲𡡒
|
||
3. <20>?摰𡁏<E691B0><F0A1818F>烐綉餈墧𦻖<E5A2A7>?4. <20>?霈曄蔭餈墧𦻖<E5A2A7>啣<EFBFBD>霅佗<E99C85>80%<25><><EFBFBD>潘<EFBFBD>
|
||
5. <20>?雿輻鍂餈墧𦻖瘙𩤃<E79899>Prisma暺䁅恕<E48185>舐鍂嚗?
|
||
**DON'T <20>?*嚗?1. <20>?瘥𤩺活霂瑟<E99C82><E7919F>啣遣 `PrismaClient`
|
||
2. <20>?銝滚<E98A9D><E6BB9A>剛<EFBFBD><E5899B>亙停<E4BA99><E5819C><EFBFBD>箄<EFBFBD>蝔?3. <20>?敹賜裦餈墧𦻖<E5A2A7>啁<EFBFBD><E59581>?4. <20>?霈曄蔭餈<E894AD>之<EFBFBD>?`MAX_INSTANCES`
|
||
5. <20>?<3F>其<EFBFBD><E585B6>∩誨<E288A9><E8AAA8>葉<EFBFBD>湔𦻖<E6B994>扯<EFBFBD> `$disconnect()`
|
||
|
||
---
|
||
|
||
## <20><> <20>詨<EFBFBD><E8A9A8><EFBFBD>﹝
|
||
|
||
- [撟喳蝱<EFBFBD>箇<EFBFBD>霈暹鴌閫<EFBFBD><EFBFBD>](./04-撟喳蝱<E596B3>箇<EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md) - 摰峕㟲<E5B395><E39FB2><EFBFBD><EFBFBD>交<EFBFBD>霈曇恣
|
||
- [鈭穃<EFBFBD><EFBFBD>笔<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD><EFBFBD>(../04-撘<><E69298>𤏸<EFBFBD><F0A48FB8>?08-鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>𤏸<EFBFBD><F0A48FB8>?md) - <20>唳旿摨㮖蝙<E3AE96>刻<EFBFBD><E588BB>?- [<5B>臬<EFBFBD><E887AC>滨蔭<E6BBA8><E894AD><EFBFBD>](../07-餈鞟輕<E99E9F><E8BC95>﹝/01-<2D>臬<EFBFBD><E887AC>滨蔭<E6BBA8><E894AD><EFBFBD>.md) - <20>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>滨蔭
|
||
- [Schema<EFBFBD>𠉛氖<EFBFBD>嗆<EFBFBD>霈曇恣](../00-蝟餌<E89D9F><E9A48C>颱<EFBFBD>霈曇恣/03-<2D>唳旿摨𤘪沲<F0A498AA><E6B2B2>秩<EFBFBD>?md)
|
||
|
||
---
|
||
|
||
## <20><> <20>湔鰵霈啣<E99C88>
|
||
|
||
| <20>交<EFBFBD> | <20>湔鰵<E6B994><E9B0B5>捆 | <20>湔鰵鈭?|
|
||
|------|---------|--------|
|
||
| 2025-11-09 | <20>嘥<EFBFBD><E598A5><EFBFBD>﹝<EFBFBD>𥕦遣 | <20>嗆<EFBFBD><E59786>a<EFBFBD> |
|
||
| 2025-11-16 | <20>啣<EFBFBD>鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098>交<EFBFBD><E4BAA4>滨蔭蝡㰘<E89DA1> | <20>嗆<EFBFBD><E59786>a<EFBFBD> |
|
||
|
||
---
|
||
|
||
**<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD>堆<EFBFBD>** 2025-11-09
|
||
**蝏湔擪<E6B994><E693AA><EFBFBD>** <20>嗆<EFBFBD><E59786>a<EFBFBD>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|