Files
AIclinicalresearch/docs/09-架构实施/02-数据库连接配置.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

17 KiB
Raw Blame History

<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>仿<EFBFBD>蝵?

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗? v1.0
*<EFBFBD>𥕦遣<EFBFBD><EFBFBD>嚗? 2025-11-09
蝏湔擪<EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E59786><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD> 2025-11-09


<EFBFBD><EFBFBD> <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>滨蔭

  • <EFBFBD>宏餈<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交䲮撘?- 撉諹<E69289><E8ABB9><EFBFBD><EFBFBD>皛𡁏䲮獢?

<EFBFBD><EFBFBD>儭?敶枏<E695B6><E69E8F>唳旿摨梶𠶖<E6A2B6>?

<EFBFBD>唳旿摨枏抅<EFBFBD>砌縑<EFBFBD>?

*餈墧𦻖靽⊥<EFBFBD>嚗?

<EFBFBD>唳旿摨梶掩<EFBFBD><EFBFBD>PostgreSQL 15+
<0A>唳旿摨枏<E691A8>蝘堆<E89D98>ai_clinical_research
銝餅㦤<E9A485><EFBFBD>嚗? localhost
蝡臬藁嚗?     5432
<0A><EFBFBD><E586BD><EFBFBD>    postgres
撖<><E69296>嚗?     postgres

摰峕㟲餈墧𦻖摮㛖泵銝莎<EFBFBD>

DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research

敶枏<EFBFBD>Schema蝏𤘪<EFBFBD>

*<EFBFBD><EFBFBD>Schema嚗?

  • <EFBFBD>?public - <20><><EFBFBD>?3銝芾”<E88ABE>賢銁餈䠷<E9A488>

*銵冽<EFBFBD><EFBFBD>𤏪<EFBFBD>13銝迎<EFBFBD>嚗?

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銝? 
**蝝<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>

-- <20>啣遣銵剁<E98AB5>
common_schema.llm_usage         -- LLM雿輻鍂霈啣<E99C88>
common_schema.feature_flags     -- Feature Flags

*3. asl_schema嚗㇁I<E38781><EFBFBD><E7AE84><EFBFBD>讃嚗?

-- <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>嚗?

-- 餈<>宏銵剁<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>嚗?

-- 餈<>宏銵剁<E98AB5>
public.knowledge_bases <EFBFBD>?pkb_schema.knowledge_bases
public.documents       <EFBFBD>?pkb_schema.documents

<EFBFBD><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>?

<EFBFBD><EFBFBD><>宏餈<E5AE8F><E9A488>餈墧𦻖<E5A2A7>滨蔭

<EFBFBD><EFBFBD><EFBFBD>憭?

*1. 憭<>遢敶枏<E695B6><E69E8F>唳旿摨?

# 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>

# 璉<><E79289><EFBFBD>隞賣<E99A9E>隞嗅之撠?ls -lh backup_*.dump

# 撉諹<E69289><EFBFBD><EFBFBD><E981A2>捆嚗𠄎QL<51><EFBFBD>嚗?head -n 50 backup_*.sql

<EFBFBD>宏餈<EFBFBD><EFBFBD>餈墧𦻖<EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>1嚗帋蝙<EFBFBD>沌risma Migrate嚗<65><EFBFBD><EFBFBD>

*餈墧𦻖<EFBFBD>滨蔭嚗?

# backend/.env
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research

*<EFBFBD><EFBFBD><EFBFBD>宏嚗?

cd backend

# <20>𥕦遣<F0A595A6><EFBFBD><EFBFBD>
npx prisma migrate dev --name schema_isolation_10_schemas

# <20><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?npx prisma migrate status

<EFBFBD><EFBFBD>2嚗𡁶凒<EFBFBD><EFBFBD>銵玺QL<EFBFBD>𡁏𧋦

*餈墧𦻖<EFBFBD><EFBFBD>嚗?

# 雿輻鍂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>𡁏𧋦嚗?

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>𡁏𧋦

<EFBFBD><EFBFBD>3嚗帋蝙<EFBFBD>典虾閫<EFBFBD><EFBFBD>撌亙<EFBFBD>

*pgAdmin 4嚗?

  1. 餈墧𦻖靽⊥<EFBFBD>嚗? - 銝餅㦤嚗饝ocalhost

    • 蝡臬藁嚗?432
    • <EFBFBD>唳旿摨橒<EFBFBD>ai_clinical_research
    • <EFBFBD><EFBFBD>嚗䮝ostgres
    • <EFBFBD><EFBFBD>嚗䮝ostgres
  2. <EFBFBD><EFBFBD><EFBFBD>宏嚗? - <20><EFBFBD>Query Tool

    • <EFBFBD>㰘蝸SQL<EFBFBD>𡁏𧋦
    • <EFBFBD><EFBFBD>

*DataGrip / DBeaver嚗?

  • <EFBFBD>峕甅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>乩縑<EFBFBD>?- <20><EFBFBD>鈭见𦛚蝞∠<E89D9E>
  • <EFBFBD>嫣噶<EFBFBD><EFBFBD>

<EFBFBD>?餈<>宏撉諹<E69289>

1. 璉<><E79289>兄chema<6D>𥕦遣

*SQL撉諹<EFBFBD>嚗?

-- <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>

*撉諹<EFBFBD>platform_schema嚗?

-- <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;

*撉諹<EFBFBD>pkb_schema嚗?

SELECT COUNT(*) FROM pkb_schema.knowledge_bases;
SELECT COUNT(*) FROM pkb_schema.documents;

3. 撉諹<E69289>憭㚚睸<E39A9A>喟頂

*<EFBFBD><EFBFBD>亥楊Schema憭㚚睸嚗?

-- <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><E89D9D>

<EFBFBD><EFBFBD>亦揣撘閙糓<EFBFBD>行迤蝖株<EFBFBD>蝘鳴<EFBFBD>

-- <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>

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)"

<EFBFBD><EFBFBD> <20><EFBFBD><E5A2A7><EFBFBD>

<EFBFBD>箸艶1嚗朞<EFBFBD>蝘餉<EFBFBD>蝔衤葉<EFBFBD>𤑳緵<EFBFBD><EFBFBD>

*蝡见朖<EFBFBD><EFBFBD>嚗?

# 憒<><E68692>雿輻鍂Prisma Migrate
npx prisma migrate reset

# <20><EFBFBD><EFBFBD>
psql -h localhost -U postgres -d ai_clinical_research < backup_before_schema_migration_YYYYMMDD_HHMMSS.sql

<EFBFBD>箸艶2嚗朞<EFBFBD>蝘餃<EFBFBD><EFBFBD>𣂼<EFBFBD><EFBFBD>𤑳緵<EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>A嚗帋<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

# 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><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

-- <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><EFBFBD>

<EFBFBD><EFBFBD><>宏璉<E5AE8F><E79289><EFBFBD><E4BAA4>?

<EFBFBD><EFBFBD>齿<EFBFBD><EFBFBD>?

  • <EFBFBD>?<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>蝘餅郊撉?

<EFBFBD>宏銝剜<EFBFBD><EFBFBD>?

  • <EFBFBD>?10銝杵chema<6D>𥕦遣<F0A595A6>𣂼<EFBFBD>
  • <EFBFBD>?銵刻<E98AB5>蝘餅<E89D98><E9A485>躰秤嚗?銝芣<E98A9D><E88AA3>唳旿<E594B3><E697BF>chema嚗?- [ ] <20>?<3F>唳旿摰峕㟲<E5B395><EFBFBD><EFBFBD><E99C82><EFBFBD>
  • <EFBFBD>?憭㚚睸蝥行<E89DA5><EFBFBD>
  • <EFBFBD>?蝝<E89D9D><EFBFBD><EFBFBD>𥕦遣

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

  • <EFBFBD>?Prisma Client<6E><74><EFBFBD><EFBFBD>𣂼<EFBFBD>
  • <EFBFBD>?<3F>𡒊垢<F0A1928A>滚𦛚<E6BB9A>臬𢆡甇<F0A286A1>
  • <EFBFBD>?<3F><EFBFBD><E594B3><EFBFBD>瘚贝<E7989A><E8B49D><EFBFBD>嚗㇁IA<49><41>KB嚗?- [ ] <20>?API靚<49>鍂甇<E98D82>
  • <EFBFBD>?<3F>滨垢<E6BBA8><EFBFBD><EFBFBD>

<EFBFBD>圲 撣貉<E692A3><E8B289><EFBFBD>

<EFBFBD><EFBFBD>1嚗锭chema<EFBFBD>𥕦遣憭梯揖

*<EFBFBD>躰秤嚗?

ERROR: schema "platform_schema" already exists

*<EFBFBD><EFBFBD>嚗?

-- 璉<><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;

<EFBFBD><EFBFBD>2嚗𡁏㺭<EFBFBD><EFBFBD>蝘餃仃韐?

*<EFBFBD>躰秤嚗?

ERROR: duplicate key value violates unique constraint

*<EFBFBD><EFBFBD>嚗?

  1. <EFBFBD><EFBFBD>交㺭<EFBFBD>格糓<EFBFBD>血歇<EFBFBD><EFBFBD><EFBFBD>
  2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Schema
  3. <EFBFBD>齿鰵<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>3嚗𡁜<EFBFBD><EFBFBD>桃漲<EFBFBD><EFBFBD>霂?

*<EFBFBD>躰秤嚗?

ERROR: foreign key constraint "fk_user_id" cannot be implemented

*<EFBFBD><EFBFBD>嚗?

  1. 蝖桐<EFBFBD>鋡怠<EFBFBD><EFBFBD><EFBFBD>銵典歇<EFBFBD><EFBFBD><EFBFBD>蝘?2. 璉<><E79289><EFBFBD><E4BA99><EFBFBD>畾萇掩<E89087>见龪<E8A781>?3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E585B8><EFBFBD><EFBFBD><EFBFBD>𡡞<EFBFBD>撱?

<EFBFBD>圲 鈭穃<E988AD><E7A983><EFBFBD><E8A098><EFBFBD><E4BAA4>滨蔭嚗?025-11-16 <20><EFBFBD>嚗?

潃?<3F><EFBFBD><E6BBA9>湔鰵嚗帋蛹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鈭?Serverless <20>函蔡嚗峕鰵憓噼<E68693><E599BC><EFBFBD><E4BAA4>滨蔭
**霂衣<E99C82><E8A1A3><EFBFBD>﹝**嚗靀撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>](./04-撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md)

<EFBFBD>峕艶嚗帋蛹隞<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

<EFBFBD><EFBFBD><EFBFBD>箸艶嚗? <20><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>嚗? 蝏𤘪<E89D8F>嚗𡁏㺭<F0A1818F><EFBFBD>餈墧𦻖<E5A2A7>堒偷嚗<E581B7><E59A97><EFBFBD>典援皞?

**閫<><E996AB><EFBFBD><EFBFBD>**嚗𡁜𢆡<F0A1819C><F0A286A1>恣蝞埈<E89D9E>摰硺<E691B0>餈墧𦻖<E5A2A7>?

瘥誩<EFBFBD>靘贝<EFBFBD><EFBFBD>交㺭 = RDS<EFBFBD><EFBFBD>憭扯<EFBFBD><EFBFBD>交㺭 / SAE<EFBFBD><EFBFBD>憭批<EFBFBD>靘𧢲㺭
蝷箔<EFBFBD>?00餈墧𦻖 / 20摰硺<EFBFBD> = 20餈墧𦻖/摰硺<EFBFBD>

Prisma餈墧𦻖瘙𣳇<EFBFBD>蝵?

<EFBFBD><EFBFBD>辣雿滨蔭嚗䫤backend/src/config/database.ts`

**<2A>滨蔭隞<E894AD><E99A9E>**嚗?

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(`<60><> <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)
  })

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨蔭

**<2A>砍𧑐撘<F0A79190><E69298>𤑳㴓憓?*嚗?

# 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>**嚗?

# 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>靘𧢲㺭

銝滚<EFBFBD>RDS閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交㺭嚗?

RDS閫<EFBFBD> <EFBFBD><EFBFBD>憭扯<EFBFBD><EFBFBD>交㺭 撱箄悅SAE摰硺<EFBFBD><EFBFBD>? 瘥誩<EFBFBD>靘贝<EFBFBD><EFBFBD>交㺭
2<EFBFBD>?GB 200 10 20
4<EFBFBD>?GB 400 20 20
8<EFBFBD>?6GB 800 40 20

<EFBFBD>烐綉<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交㺭

**摰墧𧒄<E5A2A7>亥砭餈墧𦻖<E5A2A7>?*嚗?

// 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 }
  }
}

摰𡁏𧒄<EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD>嚗?

// backend/src/index.ts
import { DatabaseMetrics } from '@/common/monitoring/metrics'

// 瘥?<3F><><EFBFBD><EFBFBD>烐綉銝<E7B689>甈?setInterval(async () => {
  await DatabaseMetrics.monitorConnections()
}, 5 * 60 * 1000)

<EFBFBD><EFBFBD><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()
}

<EFBFBD><EFBFBD>雿喳<EFBFBD>頝?

**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()


<EFBFBD><EFBFBD> <20><EFBFBD><E8A9A8><EFBFBD>


<EFBFBD><EFBFBD> <20>湔鰵霈啣<E99C88>

<EFBFBD><EFBFBD> <EFBFBD>湔鰵<EFBFBD><EFBFBD> <EFBFBD>湔鰵鈭?
2025-11-09 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𥕦遣 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-11-16 <EFBFBD><EFBFBD>鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨蔭蝡㰘<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗? v1.0
<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD> 2025-11-09
蝏湔擪<EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><E59786><EFBFBD>