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%)
55 KiB
Node.js <20>𡒊垢 - SAE 摰孵膥<E5ADB5>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦: v1.1 (靽桀<E99DBD> Prisma <20><>遣<EFBFBD>峕㺭<E5B395>桀<EFBFBD><E6A180>峕郊<E5B395>桅<EFBFBD>)
<EFBFBD>𥕦遣<EFBFBD>園𡢿: 2025-12-13
**<2A><><EFBFBD>𦒘耨霈?: 2025-12-13
<EFBFBD><EFBFBD>鍂<EFBFBD><EFBFBD>凒: AIclinicalresearch 撟喳蝱 - Node.js <20>𡒊垢<F0A1928A>滚𦛚
**<2A>格<EFBFBD>霂餉<E99C82>?: 餈鞟輕撌亦<E6928C>撣<EFBFBD><E692A3><EFBFBD><EFBFBD>蝡臬<E89DA1><E887AC>穃極蝔见<E89D94>
<EFBFBD>函蔡<EFBFBD>格<EFBFBD>: <20>輸<EFBFBD>鈭?SAE嚗𠄎erverless 摨𠉛鍂撘閙<E69298>嚗匧捆<E58CA7>券<EFBFBD>蝵?
v1.1 <20>湔鰵<E6B994>亙<EFBFBD>:
- <EFBFBD><EFBFBD> 靽桀<E99DBD>嚗䥪risma <20>桀<EFBFBD><E6A180><EFBFBD>遣銝𠹺<E98A9D><F0A0B9BA><EFBFBD>䔮憸矋<E686B8>憓𧼮<E68693>憸<EFBFBD><E686B8><EFBFBD><EFBFBD>郊撉歹<E69289>
- <EFBFBD><EFBFBD> 靽桀<E99DBD>嚗𡁶<E59A97>鈭抒㴓憓<E3B493>撩撠?Prisma CLI 撖潸稲餈<E7A8B2>宏憭梯揖
- <EFBFBD>𤣳 <20>啣<EFBFBD>嚗𡁻<E59A97>撖孵<E69296><E5ADB5>穃<EFBFBD><E7A983>脖<EFBFBD>閫<EFBFBD><E996AB><EFBFBD>?<3F>滚<EFBFBD><E6BB9A>峕郊"瘚<><E7989A>嚗<EFBFBD><E59A97><EFBFBD>殷<EFBFBD>
- <EFBFBD>?隡睃<E99AA1>嚗𡁏㺭<F0A1818F>桀<EFBFBD>餈<EFBFBD>宏蝑𣇉裦嚗īg_dump 撖澆<E69296><E6BE86>𦒘<EFBFBD><F0A69298>扯<EFBFBD> migrate嚗?- <20>?蝞<><E89D9E>吔<EFBFBD>蝘駁膄 Init Container <20>寞<EFBFBD>嚗峕㺿<E5B395>典鍳<E585B8>典𦶢隞?
<EFBFBD><EFBFBD> <20>桀<EFBFBD>
- 銝箔<EFBFBD>銋<EFBFBD><EFBFBD>㗇𥋘 SAE 摰孵膥<E5ADB5>函蔡
- [<5B>函蔡<E587BD>滚<EFBFBD>憭䚡(#2-<2D>函蔡<E587BD>滚<EFBFBD>憭?
- <EFBFBD>𡒊垢<EFBFBD>滚𦛚<EFBFBD><EFBFBD><EFBFBD>
- <EFBFBD>𤣳 Prisma <20>滚<EFBFBD><E6BB9A>峕郊嚗<E9838A><E59A97>霂鳴<E99C82>
- <EFBFBD><EFBFBD>遣 Docker <20>𨅯<EFBFBD>
- <EFBFBD>砍𧑐瘚贝<EFBFBD>撉諹<EFBFBD>
- <EFBFBD>券<EFBFBD><EFBFBD><EFBFBD> ACR
- SAE 摨𠉛鍂<F0A0899B>滨蔭
- [<5B>唳旿摨㯄<E691A8>蝵脩<E89DB5><E884A9>包(#9-<2D>唳旿摨㯄<E691A8>蝵脩<E89DB5><E884A9>?
- [蝡臬<E89DA1>蝡舀<E89DA1>霂騟(#10-蝡臬<E89DA1>蝡舀<E89DA1>霂?
- [<5B>烐綉銝𡒊輕<F0A1928A>也(#11-<2D>烐綉銝𡒊輕<F0A1928A>?
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD>埝䰻
- [瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹䀉(#13-瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹?
1. 銝箔<E98A9D>銋<EFBFBD><E98A8B>㗇𥋘 SAE 摰孵膥<E5ADB5>函蔡
<EFBFBD>?<3F>詨<EFBFBD>隡睃飵
| 隡睃飵 | 霂湔<EFBFBD> | 撖寞<EFBFBD><EFBFBD><EFBFBD>遠<EFBFBD>? |
|---|---|---|
| *<EFBFBD>臬<EFBFBD>銝<EFBFBD><EFBFBD>湔<EFBFBD>? | Docker <20>𨅯<EFBFBD>靽肽<E99DBD><E882BD>砍𧑐撘<F0A79190><E69298>𡢅<EFBFBD>Node 22 + Prisma嚗劐<E59A97>蝥蹂<E89DA5><E8B982>臬<EFBFBD>摰<EFBFBD><E691B0>銝<EFBFBD><E98A9D>? | <EFBFBD>𦦵<EFBFBD>"<22>烐𧋦<E78390>唳<EFBFBD><E594B3>舘<EFBFBD>頝?<3F><>䔮憸? |
| *撘寞<EFBFBD>找撓蝻? | SAE <20>寞旿 CPU/<2F><><EFBFBD>雿輻鍂<E8BCBB><E98D82>䌊<EFBFBD>典<EFBFBD><E585B8>誩<EFBFBD>靘𧢲㺭<F0A7A2B2>? | 憭折<EFBFBD><EFBFBD>冽<EFBFBD> AI 撖寡<E69296><E5AFA1>嗉䌊<E59789>冽<EFBFBD>摰? |
| *<EFBFBD>滩<EFBFBD>蝏? | <EFBFBD>𣳇<EFBFBD>蝞∠<EFBFBD><EFBFBD>滚𦛚<EFBFBD>?OS<4F><53><EFBFBD><EFBFBD>刻‘銝<E28098><E98A9D>SAE <20>冽<EFBFBD>蝞? | 1-2 鈭箏𣪧<E7AE8F>蠘<EFBFBD><E8A098><EFBFBD><EFBFBD>蝏渡移<E6B8A1>? |
| *<EFBFBD><EFBFBD><EFBFBD>鈭㘾<EFBFBD>? | 銝?SAE <20>?Python <20>滚𦛚<E6BB9A>?ECS <20>?Dify <20>朞<EFBFBD> VPC <20><><EFBFBD>擃㗛<E69383>罸<EFBFBD>帋縑 | 瘥怎<EFBFBD>蝥批辣餈<EFBFBD><EFBFBD><EFBFBD>惩<EFBFBD>蝵烐<EFBFBD><EFBFBD>讛晶 |
| *蝘<EFBFBD><EFBFBD><EFBFBD>硋停蝏? | Docker <20>𨅯<EFBFBD><F0A885AF>舐凒<E88890>乩漱隞条<E99A9E><E69DA1>駁堺嚗屸<E59A97>蝵脣<E89DB5><E884A3><EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD> | 皛∟雲<EFBFBD>餌<EFBFBD><EFBFBD>唳旿<EFBFBD><EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD> |
| 蝏煺<EFBFBD><EFBFBD>嗆<EFBFBD> | <EFBFBD>滨垢嚗𠃊ginx嚗剹<EFBFBD><EFBFBD><EFBFBD>蝡荔<EFBFBD>Node.js嚗剹<E59A97><E589B9>ython 敺格<E695BA><E6A0BC>⊿<EFBFBD><E28ABF>?Docker | 銝<EFBFBD>憟烾<EFBFBD>蝵脫<EFBFBD>蝔页<EFBFBD><EFBFBD>滢<EFBFBD>摮虫<EFBFBD><EFBFBD>鞉𧋦 |
<EFBFBD>㴓 銝箔<E98A9D>銋<EFBFBD><E98A8B><EFBFBD>?Code Package <20>函蔡嚗?
| 撖寞<EFBFBD>憿? | Code Package | 摰孵膥<EFBFBD>函蔡嚗<EFBFBD>綫<EFBFBD>琜<EFBFBD> |
|---|---|---|
| <EFBFBD>臬<EFBFBD>銝<EFBFBD><EFBFBD>湔<EFBFBD>? | <EFBFBD>𩤃<EFBFBD> 鈭𤑳垢 Node <20><>𧋦<EFBFBD>航<EFBFBD>銝滚<E98A9D> | <EFBFBD>?<3F>𨅯<EFBFBD><F0A885AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦 |
| 蝘<EFBFBD><EFBFBD><EFBFBD>碶漱隞? | <EFBFBD>?<3F>䭾<EFBFBD><E4ADBE>湔𦻖鈭支<E988AD> | <EFBFBD>?<3F>枏<EFBFBD><E69E8F>喳虾鈭支<E988AD> |
| 蝟餌<EFBFBD>靘肽<EFBFBD> | <EFBFBD>𩤃<EFBFBD> <20>䭾<EFBFBD><E4ADBE>芸<EFBFBD>銋? | <EFBFBD>?Dockerfile 摰<><E691B0><EFBFBD>批<EFBFBD> |
| <EFBFBD><EFBFBD>遣<EFBFBD>笔漲 | <EFBFBD>?敹恬<E695B9>銝𠹺<E98A9D><F0A0B9BA>喳虾嚗? | <EFBFBD>𩤃<EFBFBD> <20>g<EFBFBD><EFBD87><EFBFBD><EFBFBD><EFBFBD>遣<EFBFBD>𨅯<EFBFBD>嚗车 |
| <EFBFBD><EFBFBD>鍂<EFBFBD>箸艶 | 敹恍<EFBFBD>笔<EFBFBD><EFBFBD>钅<EFBFBD>霂? | <EFBFBD>煺漣<EFBFBD>臬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>匧<EFBFBD> |
蝏栞捏嚗𡁜笆鈭𡡞<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>匧<EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD>龫<EFBFBD>㛖<EFBFBD><EFBFBD>𥪯漣<EFBFBD><EFBFBD><EFBFBD>摰孵膥<EFBFBD>函蔡<EFBFBD>臬𣈲銝<EFBFBD><EFBFBD>㗇𥋘<EFBFBD>?
2. <20>函蔡<E587BD>滚<EFBFBD>憭?
<EFBFBD>?<3F>滨蔭<E6BBA8>∩辣璉<E8BEA3><E79289>交<EFBFBD><E4BAA4>?
<EFBFBD>砍𧑐撘<EFBFBD><EFBFBD>𤑳㴓憓?
- Docker Desktop 撌脣<E6928C>鋆<EFBFBD>僎餈鞱<E9A488>嚗<EFBFBD><E59A97><EFBFBD>?20.10+嚗?- [ ] Node.js 撌脣<E6928C>鋆<EFBFBD><E98B86><EFBFBD><EFBFBD>𧋦 22+嚗?- [ ] <20>𡒊垢隞<E59EA2><E99A9E>撌脫<E6928C><E884AB>硋<EFBFBD><E7A18B>砍𧑐
- <EFBFBD>𡒊垢<EFBFBD>冽𧋦<EFBFBD>啗<EFBFBD>甇<EFBFBD>虜<EFBFBD>臬𢆡嚗Ǒnpm run dev`嚗? 撉諹<E69289><E8ABB9>賭誘嚗?
# 璉<><E79289>?Docker
docker --version
# 颲枏枂蝷箔<E89DB7>嚗鋽ocker version 24.0.6
# 璉<><E79289>?Node.js
node --version
# 颲枏枂蝷箔<E89DB7>嚗鯝22.11.0
# 璉<><E79289>?npm
npm --version
# 颲枏枂蝷箔<E89DB7>嚗?0.9.0
<EFBFBD>輸<EFBFBD>鈭𤏸<EFBFBD>皞?
- RDS PostgreSQL 15 摰硺<E691B0>撌脣<E6928C>撱箏僎餈鞱<E9A488>
- <EFBFBD>唳旿摨枏<EFBFBD>蝘堆<EFBFBD>
ai_clinical嚗<EFBFBD><EFBFBD><EFBFBD>芸<EFBFBD>銋㚁<EFBFBD> - <EFBFBD>冽<EFBFBD><EFBFBD>滚<EFBFBD>撖<EFBFBD><EFBFBD>撌脣<EFBFBD>憭? - <20><><EFBFBD><EFBFBD>啣<EFBFBD>撌脰繮<E884B0>吔<EFBFBD>憒?
pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432嚗? - <20>賢<EFBFBD><E8B3A2>訫歇<E8A8AB>滨蔭嚗<E894AD><E59A97>霈?SAE VPC 霈輸䔮嚗?
- <EFBFBD>唳旿摨枏<EFBFBD>蝘堆<EFBFBD>
- <EFBFBD>輸<EFBFBD>鈭穃捆<EFBFBD>券<EFBFBD><EFBFBD>𤩺<EFBFBD><EFBFBD>?ACR 撌脣<E6928C><E884A3>? - <20>賢<EFBFBD>蝛粹𡢿撌脣<E6928C>撱綽<E692B1>憒?
clinical-research嚗? - <20>餃<EFBFBD>撖<EFBFBD><E69296>撌脰挽蝵? - SAE 摨𠉛鍂 撌脣<E6928C>撱綽<E692B1><E7B6BD>硋<EFBFBD>憭<EFBFBD><E686AD>撱綽<E692B1>
- VPC <20>䔶漱<E494B6>X㦤撌脤<E6928C>㗇𥋘嚗<F0A58B98><E59A97> RDS <20>典<EFBFBD>銝<EFBFBD> VPC嚗?
- **靘肽<E99D98><E882BD>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>蝵穃𧑐<E7A983><F0A79190>撌脰繮<E884B0>?*嚗? - Python 敺格<E695BA><E6A0BC>∴<EFBFBD>SAE嚗㚁<E59A97>
http://172.17.x.x:8000- Dify <20>滚𦛚嚗𠄌CS嚗㚁<E59A97>
http://172.17.x.x:80
- Dify <20>滚𦛚嚗𠄌CS嚗㚁<E59A97>
<EFBFBD>𤩺<EFBFBD>靽⊥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>隞乩<EFBFBD><EFBFBD>滨蔭靽⊥<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>𡡞<EFBFBD>蝵桀<EFBFBD> SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>嚗㚁<E59A97>
# <20>唳旿摨?DATABASE_URL=postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical?connection_limit=18&pool_timeout=10
# LLM API Keys嚗<73>秐撠煾<E692A0>蝵桐<E89DB5>銝迎<E98A9D>
DEEPSEEK_API_KEY=sk-xxxxx
DASHSCOPE_API_KEY=sk-xxxxx
CLOSEAI_API_KEY=sk-xxxxx
# Dify
DIFY_API_KEY=app-xxxxx
DIFY_API_URL=http://172.17.x.x:80/v1
# <20>輸<EFBFBD>鈭?OSS
OSS_REGION=oss-cn-beijing
OSS_BUCKET=clinical-research-files
OSS_ACCESS_KEY_ID=LTAI5t...
OSS_ACCESS_KEY_SECRET=xxx...
# JWT 摰匧<E691B0>撖<EFBFBD>𤨎嚗<F0A4A88E><E59A97>鈭抒㴓憓<E3B493><E68693>憿颱耨<E9A2B1>對<EFBFBD>
JWT_SECRET=your-strong-random-secret-min-32-chars
3. <20>𡒊垢<F0A1928A>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>
<EFBFBD>𣑐 <20><><EFBFBD>舀<EFBFBD>
| <EFBFBD><EFBFBD><EFBFBD>? | <EFBFBD><EFBFBD>𧋦 | <EFBFBD>券<EFBFBD>? |
|---|---|---|
| Node.js | 22+ | 餈鞱<EFBFBD><EFBFBD>嗥㴓憓? |
| Fastify | 5.6+ | Web 獢<>沲嚗<E6B2B2><E59A97><EFBFBD>扯<EFBFBD>嚗? |
| TypeScript | 5.9+ | 蝐餃<EFBFBD>摰匧<EFBFBD> |
| Prisma | 6.17+ | ORM嚗<EFBFBD>㺭<EFBFBD>桀<EFBFBD>霈輸䔮嚗? |
| pg-boss | 12.5+ | <EFBFBD>笔<EFBFBD>嚗㇊ostgres-Only嚗? |
| winston | 3.18+ | <EFBFBD>亙<EFBFBD>蝟餌<EFBFBD> |
<EFBFBD><EFBFBD> 靘肽<E99D98><E882BD>滚𦛚
Node.js <20>𡒊垢嚗𠄎AE嚗? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD><EFBFBD>?RDS PostgreSQL 15嚗<35>㺭<EFBFBD>桀<EFBFBD>嚗? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD><EFBFBD>?Python 敺格<E695BA><E6A0BC>∴<EFBFBD>SAE嚗? - <20><>﹝<EFBFBD>𣂼<EFBFBD>
<20>? <20>婙<EFBFBD> http://172.17.x.x:8000
<20>? <20>鎿<EFBFBD><E98EBF><EFBFBD><EFBFBD>?Dify <20>滚𦛚嚗𠄌CS嚗? - RAG <20>亥<EFBFBD>摨? <20>? <20>婙<EFBFBD> http://172.17.x.x:80/v1
<20>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD>?<3F>輸<EFBFBD>鈭?OSS - <20><>辣摮睃<E691AE>
<20>婙<EFBFBD> clinical-research-files
<EFBFBD>圲 <20>詨<EFBFBD><E8A9A8>蠘<EFBFBD>璅∪<E79285>
| 璅∪<EFBFBD> | 頝臬<EFBFBD> | <EFBFBD>蠘<EFBFBD> | 靘肽<EFBFBD><EFBFBD>滚𦛚 |
|---|---|---|---|
| AIA | /api/chat |
AI <20>箄<EFBFBD><E7AE84>拍<EFBFBD> | DeepSeek/<2F><>䔮/Claude |
| PKB | /api/knowledge-bases |
銝芯犖<EFBFBD>亥<EFBFBD>摨? | Dify + OSS |
| ASL | /api/asl/* |
<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃 | Python 敺格<E695BA><E6A0BC>?+ OSS |
| DC | /api/dc/* |
<EFBFBD>唳旿皜<EFBFBD><EFBFBD> | Python 敺格<E695BA><E6A0BC>?+ OSS |
| RVW | /api/review |
蝔蹂辣摰⊥䰻 | DeepSeek/<2F><>䔮 |
| Health | /health |
<EFBFBD>亙熒璉<EFBFBD><EFBFBD>? | RDS |
<EFBFBD><EFBFBD> <20>臬𢆡瘚<F0A286A1><E7989A>
# 1. 摰㕑<E691B0>靘肽<E99D98>
npm install
# 2. <20><><EFBFBD> Prisma Client
npm run prisma:generate
# 3. <20>唳旿摨栞<E691A8>蝘鳴<E89D98>隞<EFBFBD><E99A9E>甈⊥<E79488><E28AA5>湔鰵<E6B994>塚<EFBFBD>
npx prisma migrate deploy
# 4. 蝻𤥁<E89DBB> TypeScript
npm run build
# 5. <20>臬𢆡摨𠉛鍂
npm start
4. <20>𤣳 Prisma <20>滚<EFBFBD><E6BB9A>峕郊嚗<E9838A><E59A97>霂鳴<E99C82>
<EFBFBD>𩤃<EFBFBD> <20>滩<EFBFBD>霅血<E99C85>嚗帋蛹隞<E89BB9>銋<EFBFBD><E98A8B>閬<EFBFBD><E996AC>銝<EFBFBD>甇伐<E79487>
**<2A>函<EFBFBD>撘<EFBFBD><E69298>穃<EFBFBD><E7A983>?*嚗?- <20>?雿輻鍂 pg_dump 撖澆枂鈭<E69E82>𧋦<EFBFBD>?PostgreSQL <20>唳旿摨橒<E691A8><E6A992><EFBFBD>鉄銵函<E98AB5><E587BD><EFBFBD><EFBFBD><EFBFBD>唳旿嚗?- <20>?撌脩<E6928C>撖澆<E69296><E6BE86>圈燵<E59C88>䔶<EFBFBD> RDS PostgreSQL
- <EFBFBD>𩤃<EFBFBD> 雿<EFBFBD>糓嚗𡁜<EFBFBD><EFBFBD>𤏸<EFBFBD>蝔衤葉嚗𣬚<EFBFBD>撣貊凒<EFBFBD>亦鍂 SQL <20>?Navicat 靽格㺿<E6A0BC>唳旿摨橒<E691A8>瘝⊥<EFBFBD><EFBFBD>峕郊<EFBFBD>湔鰵
schema.prisma<20><>辣
**<2A>擧<EFBFBD>**嚗?```typescript // schema.prisma 銝剖<E98A9D>銋㚁<E98A8B> model User { id String email String name String // <20>?蝻箏<E89DBB> phone 摮埈挾 }
// 雿<>㺭<EFBFBD>桀<EFBFBD><E6A180><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?CREATE TABLE "User" ( id VARCHAR(255), email VARCHAR(255), name VARCHAR(255), phone VARCHAR(50) -- <20>?餈嗘葵摮埈挾摮睃銁嚗䔶<E59A97> Prisma 銝滨䰻<E6BBA8>?);
// 隞<><E99A9E><EFBFBD><EFBFBD><EFBFBD>霂閗挪<E99697>殷<EFBFBD> const user = await prisma.user.findUnique({ where: { id: '123' } }); console.log(user.phone); // <20>?TypeScript <20>仿<EFBFBD>嚗䥪roperty 'phone' does not exist on type 'User'
**<2A>港艇<E6B8AF>滨<EFBFBD><E6BBA8>擧<EFBFBD>**嚗?- Prisma Client <20><><EFBFBD><EFBFBD><EFBFBD>掩<EFBFBD>衤<EFBFBD><E8A1A4>唳旿摨㮖<E691A8>銝<EFBFBD><E98A9D>?- 餈鞱<E9A488><E99EB1>嗅虾<E59785>質粉銝滚<E98A9D><E6BB9A>唳旿<E594B3>𡝗𥁒<F0A19D97>?- 憒<><E68692>撘箄<E69298>餈鞱<E9A488> `prisma migrate deploy`嚗<>虾<EFBFBD>賢<EFBFBD>銝箄”撌脣<E6928C><E884A3>刻<EFBFBD><E588BB>仃韐?
### <20>?閫<><E996AB><EFBFBD>寞<EFBFBD>嚗𡁜<E59A97><F0A1819C>穃<EFBFBD>甇伐<E79487>Introspection嚗?
#### 甇仿炊 1嚗朞<E59A97><E69C9E>亙<EFBFBD> RDS <20>唳旿摨?
<0A>冽𧋦<E586BD>啣<EFBFBD><E595A3>𤑳㴓憓<E3B493><E68693>銝湔𧒄餈墧𦻖<E5A2A7>?RDS嚗?
```bash
# 1. 憭<>遢敶枏<E695B6><E69E8F>?.env <20><>辣
cp backend/.env backend/.env.backup
# 2. <20>𥕦遣銝湔𧒄 RDS 餈墧𦻖<E5A2A7>滨蔭
cat > backend/.env.rds <<EOF
DATABASE_URL="postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical?connection_limit=18&pool_timeout=10"
EOF
# 3. 雿輻鍂 RDS <20>滨蔭
cd backend
export $(cat .env.rds | xargs)
甇仿炊 2嚗𡁏<E59A97>銵<EFBFBD><E98AB5><EFBFBD>穃<EFBFBD>甇伐<E79487><E4BC90>喲睸甇仿炊嚗?
# 霈?Prisma 霂餃<E99C82> RDS <20><><EFBFBD>摰䂿<E691B0><E482BF><EFBFBD><EFBFBD><EFBFBD>芸𢆡<E88AB8>滚<EFBFBD> schema.prisma
npx prisma db pull
# 颲枏枂蝷箔<E89DB7>嚗?# Prisma schema loaded from prisma/schema.prisma
# Datasource "db": PostgreSQL database "ai_clinical" at "pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432"
#
# Introspecting based on datasource defined in prisma/schema.prisma <20>?#
# <20>?Introspected 45 models and wrote them into prisma/schema.prisma in 2.34s
#
# Run prisma generate to generate Prisma Client.
餈嗘葵<EFBFBD>賭誘<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?*嚗?- 摰<><E691B0><EFBFBD>急<EFBFBD><E680A5>唳旿摨梶<E691A8><EFBFBD><EFBFBD><EFBFBD>㕑”<EFBFBD><EFBFBD><EFBFBD>畾萸<EFBFBD><EFBFBD>掩<EFBFBD>卝<EFBFBD><EFBFBD><EFBFBD>蝟?*
- <EFBFBD>嗅<EFBFBD>摰<EFBFBD><EFBFBD><EFBFBD>滚<EFBFBD>
prisma/schema.prisma<20><>辣 - 靽肽<EFBFBD> Schema 銝擧㺭<E693A7>桀<EFBFBD> 100% 銝<><E98A9D>?
甇仿炊 3嚗𡁏䰻<F0A1818F>见僎蝖株恕<E6A0AA>䀹凒
# <20>亦<EFBFBD> schema.prisma <20><><EFBFBD><EFBFBD>?git diff prisma/schema.prisma
# 雿牐<E99BBF><E78990>见<EFBFBD>嚗?# + phone String? @db.VarChar(50) // <20>啣<EFBFBD><E595A3><EFBFBD><EFBFBD>畾?# - role String @default("user") // 憒<><E68692><EFBFBD>唳旿摨㯄<E691A8><E3AF84>寞<EFBFBD>鈭?user_role
# + user_role String @default("user")
**<2A>𩤃<EFBFBD> 鈭箏極璉<E6A5B5><E79289>交<EFBFBD><E4BAA4>?*嚗?
-
**璉<><E79289>交鰵憓𧼮<E68693>畾?*嚗? - <20>臬炏<E887AC>㗇<EFBFBD>憭𣇉<E686AD>摮埈挾嚗<E68CBE><E59A97>瘚贝<E7989A>摮埈挾嚗㚁<E59A97>
- 摮埈挾蝐餃<EFBFBD><EFBFBD>臬炏甇<EFBFBD>&嚗?
-
**璉<><E79289>亙<EFBFBD><E4BA99>文<EFBFBD>畾?*嚗? - 憒<><E68692> Schema <20>𣬚<EFBFBD>摮埈挾<E59F88>冽㺭<E586BD>桀<EFBFBD>銝凋<E98A9D>摮睃銁嚗䈣db pull` 隡𡁜<E99AA1><F0A1819C>文<EFBFBD>
- 蝖株恕餈嗘<EFBFBD>摮埈挾<EFBFBD>臬炏<EFBFBD>毺<EFBFBD>摨磰砲<EFBFBD>𣳇膄
-
**璉<><E79289>亙<EFBFBD>蝟鳴<E89D9F>Relations嚗?*嚗? - 憭㚚睸<E39A9A>喟頂<E5969F>臬炏甇<E7828F>&霂<EFBC86><E99C82>嚗? -
@relation瘜刻圾<E588BB>臬炏<E887AC><E7828F><EFBFBD>嚗? -
**璉<><E79289>亦揣撘?*嚗? - <20>臬炏靽萘<E99DBD>鈭<EFBFBD><E988AD><EFBFBD>?
@@index<EFBFBD><EFBFBD>@@unique`嚗?
甇仿炊 4嚗𡁻<E59A97><F0A181BB>啁<EFBFBD><E59581>?Prisma Client
# <20>箔<EFBFBD><E7AE94>啁<EFBFBD> Schema <20><><EFBFBD>摰X<E691B0>蝡?npx prisma generate
# 颲枏枂蝷箔<E89DB7>嚗?# <20>?Generated Prisma Client (5.7.0) to ./node_modules/@prisma/client in 234ms
**撉諹<E69289><E8ABB9><EFBFBD><EFBFBD>蝏𤘪<E89D8F>**嚗?
// <20>其誨<E585B6><E8AAA8>葉瘚贝<E7989A>嚗<EFBFBD>葩<EFBFBD>塚<EFBFBD>
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// TypeScript 摨磰砲<E7A3B0>質<EFBFBD><E8B3AA>急鰵摮埈挾
const user = await prisma.user.findUnique({ where: { id: '123' } });
console.log(user.phone); // <20>?<3F>啣銁<E595A3>臭誑霈輸䔮鈭?```
#### 甇仿炊 5嚗𡁏<EFBFBD>鈭支誨<EFBFBD>?
```bash
# <20>W<EFBFBD><EFBCB7>砍𧑐 .env嚗<76><E59A97>閬<EFBFBD><E996AC>
cd backend
cp .env.backup .env
rm .env.rds
# <20>𣂷漱<F0A382B7>峕郊<E5B395>𡒊<EFBFBD> Schema
git add prisma/schema.prisma
git commit -m "chore: sync Prisma schema with RDS database (introspection)"
git push
<EFBFBD>辶 撣貉<E692A3><E8B289>桅<EFBFBD>憭<EFBFBD><E686AD>
<EFBFBD>桅<EFBFBD> 1嚗䫤db pull` <20>仿<EFBFBD>嚗𡁏<E59A97>瘜閗<E7989C><E99697>交㺭<E4BAA4>桀<EFBFBD>
# <20>躰秤靽⊥<E99DBD>嚗?Error: P1001: Can't reach database server at `pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432`
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# 1. 璉<><E79289>?RDS <20>賢<EFBFBD><E8B3A2>?# <20>輸<EFBFBD>鈭烐綉<E78390>嗅蝱 <20>?RDS <20>?<3F>唳旿摰匧<E691B0><E58CA7>?<3F>?<3F>賢<EFBFBD><E8B3A2>閗挽蝵?# 瘛餃<E7989B>雿删<E99BBF><E588A0>砍𧑐<E7A08D>祉<EFBFBD> IP嚗<50>䰻霂g<E99C82>curl ipinfo.io嚗?
# 2. 瘚贝<E7989A>餈墧𦻖
psql "postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical"
# 憒<><E68692><EFBFBD>質<EFBFBD>銝𠺪<E98A9D><F0A0BAAA>齿<EFBFBD>銵?npx prisma db pull
<EFBFBD>桅<EFBFBD> 2嚗䫤db pull` <20>𠬍<EFBFBD><F0A0AC8D>𣂷<EFBFBD>摮埈挾<E59F88><E68CBE>掩<EFBFBD>见<EFBFBD>鈭?
// 銋见<E98A8B>嚗?model User {
age Int
}
// db pull <20>𠬍<EFBFBD>
model User {
age String @db.VarChar(10) // <20>?蝐餃<E89D90><E9A483>䀹<EFBFBD>鈭?String
}
**<2A>笔<EFBFBD>**嚗𡁏㺭<F0A1818F>桀<EFBFBD>銝剔<E98A9D>摮埈挾蝐餃<E89D90>蝖桀<E89D96><E6A180>?VARCHAR(10)嚗諹<EFBFBD>䔶<EFBFBD><EFBFBD>?INT<EFBFBD>?
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?1. **靽格迤<E6A0BC>唳旿摨?*嚗<>綫<EFBFBD>琜<EFBFBD>嚗? ```sql
ALTER TABLE "User" ALTER COLUMN age TYPE INTEGER USING age::INTEGER;
2. **<2A>亙<EFBFBD><E4BA99>啁𠶖**嚗<><E59A97><EFBFBD>刻<EFBFBD>嚗㚁<E59A97>憒<EFBFBD><E68692><EFBFBD>唳旿摨梶&摰噼<E691B0><E599BC>?`VARCHAR` 摮睃<E691AE>撟湧<E6929F>嚗屸<E59A97>撠望㺿隞<E3BABF><E99A9E><EFBFBD>餉<EFBFBD><E9A489>?
#### <20>桅<EFBFBD> 3嚗䫤db pull` <20>𠬍<EFBFBD>銝W仃鈭<E4BB83>䌊摰帋<E691B0>瘜券<E7989C>
```prisma
// 銋见<E98A8B>嚗?model User {
/// <20>冽<EFBFBD><E586BD><EFBFBD>𣈲銝<F0A388B2><E98A9D><EFBFBD><EFBFBD>蝚? id String @id @default(uuid())
}
// db pull <20>𠬍<EFBFBD>
model User {
id String @id @default(uuid()) // <20>?瘜券<E7989C>銝W仃
}
**<2A>笔<EFBFBD>**嚗䫤db pull` <20>芾<EFBFBD>霂餃<E99C82><E9A483>唳旿摨梶<E691A8><E6A2B6><EFBFBD><EFBFBD><EFBFBD>䭾<EFBFBD>霂餃<E99C82>隞<EFBFBD><E99A9E>瘜券<E7989C><E588B8>? **閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗𡁏<E59A97><F0A1818F>冽<EFBFBD>憭漤<E686AD>閬<EFBFBD><E996AC>瘜券<E7989C><E588B8>?
5. <20><>遣 Docker <20>𨅯<EFBFBD>
<EFBFBD><EFBFBD> <20>滨蔭甇仿炊嚗𡁜<E59A97>憭?Prisma <20><>辣嚗<E8BEA3><E59A97>憿餅<E686BF>銵䕘<E98AB5>
**<2A>桅<EFBFBD>**嚗𡁻★<F0A181BB>桃<EFBFBD><E6A183><EFBFBD>葉嚗䈣prisma <20><>辣憭孵銁**<2A>寧𤌍敶?*嚗䔶<E59A97> Dockerfile <20>?backend/<EFBFBD>桀<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𦦵凒<EFBFBD>亙銁backend/<EFBFBD>桀<EFBFBD><EFBFBD><EFBFBD>遣嚗㷉ocker <20>衤<EFBFBD><E8A1A4>唬<EFBFBD>銝<EFBFBD>撅<EFBFBD><E69285>prisma` <20><>辣憭嫘<E686AD>?
閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD> A嚗𡁜<E59A97><F0A1819C>?Prisma <20>?backend <20>桀<EFBFBD>嚗<EFBFBD>綫<EFBFBD>琜<EFBFBD>
# <20>券★<E588B8>格覔<E6A0BC>桀<EFBFBD><E6A180>扯<EFBFBD>
cd AIclinicalresearch
# 憭滚<E686AD> prisma <20><>辣憭孵<E686AD> backend <20>桀<EFBFBD>
cp -r prisma backend/prisma
# 撉諹<E69289>憭滚<E686AD><E6BB9A>𣂼<EFBFBD>
ls backend/prisma/schema.prisma
# 摨磰砲颲枏枂嚗颹ackend/prisma/schema.prisma
# 瘜冽<E7989C>嚗?# 1. 餈嗘葵憭滚<E686AD><E6BB9A>臭葩<E887AD>嗥<EFBFBD>嚗𣬚鍂鈭擧<E988AD>撱粹<E692B1><E7B2B9>?# 2. 銝滩<E98A9D><E6BBA9>?backend/prisma <20>𣂷漱<F0A382B7>?Git嚗<74>歇<EFBFBD>?.gitignore 銝哨<E98A9D>
# 3. 瘥𤩺活<F0A4A9BA><E6B4BB>遣<EFBFBD>𨅯<EFBFBD><F0A885AF>漤<EFBFBD><E6BCA4><EFBFBD>閬<EFBFBD><E996AC><EFBFBD>啣<EFBFBD><E595A3>塚<EFBFBD>蝖桐<E89D96><E6A190><EFBFBD><EFBFBD>堆<EFBFBD>
*閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD> B嚗𡁜銁<F0A1819C>寧𤌍敶閙<E695B6>撱綽<E692B1><E7B6BD><EFBFBD><EFBFBD> CI/CD嚗?
憒<EFBFBD><EFBFBD>雿牐蝙<EFBFBD>?CI/CD <20>芸𢆡<E88AB8>𡝗<EFBFBD>撱綽<E692B1><E7B6BD>臭誑<E887AD>冽覔<E586BD>桀<EFBFBD><E6A180><EFBFBD>遣嚗?
# <20>冽覔<E586BD>桀<EFBFBD><E6A180><EFBFBD>遣嚗屸<E59A97>閬<EFBFBD>耨<EFBFBD>?Dockerfile <20><>楝敺?# 餈䠷<E9A488><E4A0B7><EFBFBD><EFBFBD>撅訫<E69285>嚗峕綫<E5B395>𣂷蝙<F0A382B7>冽䲮獢?A
<EFBFBD><EFBFBD> <20>𥕦遣 Dockerfile
<EFBFBD>?backend/ <20>桀<EFBFBD>銝见<E98A9D>撱?Dockerfile嚗?
# ==================== <20>嗆挾 1: <20><>遣<EFBFBD>嗆挾 ====================
FROM node:22-alpine AS builder
# 摰㕑<E691B0>蝻𤥁<E89DBB>撌亙<E6928C>嚗㇊risma <20><>閬<EFBFBD><E996AC>
RUN apk add --no-cache \
python3 \
make \
g++ \
openssl
WORKDIR /app
# 1. 憭滚<E686AD>靘肽<E99D98><E882BD><EFBFBD>辣
COPY package*.json ./
# 2. 憭滚<E686AD> Prisma Schema嚗<61>&靽嘥銁 backend/ <20>桀<EFBFBD>銝见歇<E8A781>?prisma <20><>辣憭對<E686AD>
COPY prisma ./prisma/
# 3. 摰㕑<E691B0>靘肽<E99D98>嚗<EFBFBD><E59A97><EFBFBD>?devDependencies嚗𣬚鍂鈭擧<E988AD>撱綽<E692B1>
# <20>𩤃<EFBFBD> 瘜冽<E7989C>嚗朞<E59A97><E69C9E><EFBFBD><EFBFBD>鋆<EFBFBD><E98B86><EFBFBD>其<EFBFBD>韏吔<E99F8F><E59094><EFBFBD>𡠺 prisma CLI
RUN npm ci
# 4. 憭滚<E686AD>皞𣂷誨<F0A382B7>?COPY . .
# 5. <20><><EFBFBD> Prisma Client
RUN npm run prisma:generate
# 6. 蝻𤥁<E89DBB> TypeScript
RUN npm run build
# <20>𩤃<EFBFBD> 銝滩<E98A9D><E6BBA9>刻<EFBFBD><E588BB>峕<EFBFBD>銵?npm prune --production
# <20>牐蛹<E78990>睲賑<E79DB2><E8B391>閬<EFBFBD>銁<EFBFBD>嗆挾 2 靽萘<E99DBD> prisma CLI <20>其<EFBFBD><E585B6>煺漣<E785BA>臬<EFBFBD>餈<EFBFBD>宏
# ==================== <20>嗆挾 2: 餈鞱<E9A488><E99EB1>嗆挾 ====================
FROM node:22-alpine
# 摰㕑<E691B0>餈鞱<E9A488><E99EB1>嗡<EFBFBD>韏?+ <20>嗅躹<E59785>唳旿
RUN apk add --no-cache \
openssl \
curl \
ca-certificates \
tzdata
# <20>𩤃<EFBFBD> 蝏煺<E89D8F><E785BA>嗅躹嚗鋫sia/Shanghai
ENV TZ=Asia/Shanghai
# <20>𥕦遣<F0A595A6>?root <20>冽<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>冽<EFBFBD>雿喳<E99BBF>頝蛛<E9A09D>
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
WORKDIR /app
# 隞擧<E99A9E>撱粹𧫴畾萄<E795BE><E89084>嗡漣<E597A1>?COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
COPY --from=builder --chown=nodejs:nodejs /app/prisma ./prisma
# <20>𤣳 <20>喲睸嚗𡁜<E59A97>撅<EFBFBD>摰㕑<E691B0> Prisma CLI嚗<49>鍂鈭𡒊<E988AD>鈭抒㴓憓<E3B493>虾<EFBFBD>賜<EFBFBD>餈<EFBFBD>宏<EFBFBD>滢<EFBFBD>嚗?# 瘜冽<E7989C>嚗朞<E59A97>隡𡁜<E99AA1><F0A1819C>删漲 50MB <20>𨅯<EFBFBD>雿梶妖嚗䔶<E59A97>蝖桐<E89D96><E6A190>煺漣<E785BA>臬<EFBFBD><E887AC>臭誑<E887AD>扯<EFBFBD> prisma <20>賭誘
RUN npm install -g prisma@6.17.0
# <20>𥕦遣銝𠹺<E98A9D><F0A0B9BA>桀<EFBFBD>嚗<EFBFBD>鍂鈭𦒘葩<F0A69298>嗆<EFBFBD>隞塚<E99A9E>
RUN mkdir -p /app/uploads && chown -R nodejs:nodejs /app/uploads
# <20><>揢<EFBFBD>圈<EFBFBD> root <20>冽<EFBFBD>
USER nodejs
# <20>亙熒璉<E78692><E79289>?HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD node -e "require('http').get('http://localhost:3001/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1); })"
# <20>湧蠧蝡臬藁
EXPOSE 3001
# <20>𤣳 <20>臬𢆡<E887AC>賭誘嚗<E8AA98><E59A97><EFBFBD>臬𢆡摨𠉛鍂嚗䔶<E59A97><E494B6>扯<EFBFBD><E689AF>唳旿摨栞<E691A8>蝘鳴<E89D98>
# 閫<><E996AB>嚗𡁜<E59A97>銝箸㺭<E7AEB8>桀<EFBFBD>撌脤<E6928C>朞<EFBFBD> pg_dump 撖澆<E69296>嚗𣬚<E59A97><F0A3AC9A><EFBFBD>歇撠梁貌嚗峕<E59A97><E5B395><EFBFBD> migrate
CMD ["node", "dist/index.js"]
<EFBFBD><EFBFBD> Dockerfile <20>喲睸靽格㺿霂湔<E99C82>
靽格㺿 1嚗𡁜<E59A97>撅<EFBFBD>摰㕑<E691B0> Prisma CLI
# <20>𤣳 <20>券𧫴畾?2 <20>啣<EFBFBD>嚗?RUN npm install -g prisma@6.17.0
**<2A>笔<EFBFBD>**嚗?- npm ci + npm prune --production 隡𡁜<E99AA1><F0A1819C>?devDependencies 銝剔<E98A9D> prisma <20>?- 雿<><E99BBF>鈭抒㴓憓<E3B493>虾<EFBFBD>賡<EFBFBD>閬<EFBFBD><E996AC>銵?npx prisma db pull <20>𡝗<EFBFBD><F0A19D97>仿䔮憸?- <20>典<EFBFBD>摰㕑<E691B0>蝖桐<E89D96> prisma <20>賭誘憪讠<E686AA><E8AEA0>舐鍂
隞<EFBFBD>遠嚗?- <20>𨅯<EFBFBD>雿梶妖憓𧼮<E68693>蝥?50MB
- 雿<EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD>澆<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>踹<EFBFBD>"<22>賭誘<E8B3AD>曆<EFBFBD><E69B86>?<3F><>䔮憸矋<E686B8>
靽格㺿 2嚗帋<E59A97><E5B88B>扯<EFBFBD><E689AF>唳旿摨栞<E691A8>蝘?
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗<EFBFBD><E59A97>撖潸稲"銵典歇摮睃銁"<22>躰秤嚗㚁<E59A97>
CMD ["sh", "-c", "npx prisma migrate deploy && node dist/index.js"]
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>臬𢆡摨𠉛鍂嚗㚁<E59A97>
CMD ["node", "dist/index.js"]
**<2A>笔<EFBFBD>**嚗?- <20>函<EFBFBD><E587BD>唳旿摨𤘪糓<F0A498AA>朞<EFBFBD> pg_dump 撖澆<E69296><E6BE86><EFBFBD><EFBFBD>銵函<E98AB5><E587BD><EFBFBD>歇蝏誩<E89D8F><E8AAA9>?- 憒<><E68692><EFBFBD>扯<EFBFBD> prisma migrate deploy嚗<EFBFBD>虾<EFBFBD>賢<EFBFBD>銝箄<EFBFBD>蝘餉扇敶訫笆銝滢<EFBFBD><EFBFBD>峕𥁒<EFBFBD>?- 甇<>&<EFBFBD><EFBC86><EFBFBD>瘜𤏪<E7989C><F0A48FAA>臬𢆡<E887AC>滨&靽?schema.prisma 銝擧㺭<E693A7>桀<EFBFBD>銝<EFBFBD><E98A9D>湛<EFBFBD>蝚?4 <20><>歇憭<E6AD87><E686AD>嚗?
靽格㺿 3嚗𡁶宏<F0A181B6>?dumb-init嚗<74>虾<EFBFBD>劐<EFBFBD><E58A90>吔<EFBFBD>
# 蝘駁膄嚗?# RUN apk add --no-cache dumb-init
# ENTRYPOINT ["dumb-init", "--"]
# Node.js 22 <20>典<EFBFBD><E585B8><EFBFBD>縑<EFBFBD>瑟𧒄撌脩<E6928C>頞喳<E9A09E>蝔喳<E89D94>
# 憒<><E68692>雿惩<E99BBF><E683A9>唬<EFBFBD>頧?dumb-init 敺<><E695BA><EFBFBD>𡝗𥁒<F0A19D97>辷<EFBFBD><E8BEB7>臭誑<E887AD>餅<EFBFBD>餈嗘葵隡睃<E99AA1>
<EFBFBD><EFBFBD> <20>𥕦遣 .dockerignore
<EFBFBD>?backend/ <20>桀<EFBFBD>銝见<E98A9D>撱?.dockerignore嚗?
# Node.js
node_modules
npm-debug.log
yarn-error.log
# 撘<><E69298>烐<EFBFBD>隞?.env
.env.*
*.local
# <20><>遣鈭抒<E988AD>嚗<EFBFBD>歇<EFBFBD>?Dockerfile 銝剔<E98A9D><E58994>琜<EFBFBD>
dist
# 瘚贝<E7989A><E8B49D><EFBFBD>辣
test
tests
*.test.ts
*.spec.ts
coverage
# <20><>﹝<EFBFBD>䔶葩<E494B6>嗆<EFBFBD>隞?docs
*.md
.vscode
.idea
.DS_Store
Thumbs.db
# 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>辣嚗<E8BEA3><E59A97>銵峕𧒄<E5B395><F0A79284><EFBFBD>嚗?uploads/*
# Git
.git
.gitignore
# <20>亙<EFBFBD>
*.log
logs
# 銝湔𧒄<E6B994><F0A79284>辣
temp
tmp
*.swp
*.swo
*~
# <20>唳旿摨𤘪<E691A8>隞塚<E99A9E>SQLite嚗<65><E59A97><EFBFBD>𨀣<EFBFBD>嚗?*.db
*.sqlite
# <20>𡁏𧋦<F0A1818F><F0A78BA6>辣嚗<E8BEA3><E59A97>撘<EFBFBD><E69298>睲蝙<E79DB2>剁<EFBFBD>
scripts/*.ts
*.bat
*.ps1
6. <20>砍𧑐瘚贝<E7989A>撉諹<E69289>
<EFBFBD><EFBFBD> <20>滨蔭甇仿炊嚗𡁜<E59A97><F0A1819C>?Prisma <20><>辣嚗<E8BEA3><E59A97>憿餅<E686BF>銵䕘<E98AB5>
# 1. <20>𧼮<EFBFBD>憿寧𤌍<E5AFA7>寧𤌍敶?cd AIclinicalresearch
# 2. 憭滚<E686AD> prisma <20>?backend <20>桀<EFBFBD>嚗<EFBFBD>&靽脲<E99DBD>撱箸𧒄<E7AEB8>賣𪄳<E8B3A3>堆<EFBFBD>
cp -r prisma backend/prisma
# 3. 撉諹<E69289>憭滚<E686AD><E6BB9A>𣂼<EFBFBD>
ls backend/prisma/schema.prisma
# 摨磰砲颲枏枂嚗颹ackend/prisma/schema.prisma
甇仿炊 1嚗𡁏<E59A97>撱粹<E692B1><E7B2B9>?
# <20>?backend <20>桀<EFBFBD>銝𧢲<E98A9D>銵?cd backend
# <20>𤣳 蝖桐<E89D96>撌脫<E6928C>銵䔶<E98AB5><E494B6>Y<EFBFBD>憭滚<E686AD>甇仿炊嚗?
# <20><>遣<EFBFBD>𨅯<EFBFBD>嚗<EFBFBD><E59A97>閬?5-10 <20><><EFBFBD>嚗?docker build -t backend-service:v1.0.0 .
# <20>亦<EFBFBD><E4BAA6>𨅯<EFBFBD>憭批<E686AD>
docker images backend-service:v1.0.0
# 憸<><E686B8>憭批<E686AD>嚗鰺300-500MB嚗㇁lpine <20>箇<EFBFBD><E7AE87>𨅯<EFBFBD> + Node.js + 靘肽<E99D98>嚗?```
**憒<><E68692><EFBFBD><EFBFBD>遣憭梯揖**嚗?
```bash
# 撣貉<E692A3><E8B289>桅<EFBFBD> 1嚗䥪risma <20><>辣<EFBFBD>曆<EFBFBD><E69B86>?# <20>躰秤靽⊥<E99DBD>嚗鋴OPY failed: file not found in build context or excluded by .dockerignore: stat prisma: file does not exist
# 閫<><E996AB>嚗𡁶&靽脲<E99DBD>銵䔶<E98AB5>憭滚<E686AD>甇仿炊嚗䬙p -r ../prisma ./prisma嚗<61>銁 backend <20>桀<EFBFBD>憭𡝗<E686AD>銵䕘<E98AB5>
# 撣貉<E692A3><E8B289>桅<EFBFBD> 2嚗𡁶<E59A97>蝏𡏭<E89D8F><F0A18FAD>塚<EFBFBD>npm install <20>g<EFBFBD>
# 閫<><E996AB>嚗帋蝙<E5B88B>典𤙴<E585B8><F0A499B4><EFBFBD><EFBFBD>𤩺<EFBFBD>
# <20>?Dockerfile <20>?npm ci 銋见<E98A8B>瘛餃<E7989B>嚗?RUN npm config set registry https://registry.npmmirror.com
# 撣貉<E692A3><E8B289>桅<EFBFBD> 3嚗䥪risma <20><><EFBFBD>憭梯揖
# 閫<><E996AB>嚗𡁏<E59A97><F0A1818F>?backend/prisma/schema.prisma <20>臬炏摮睃銁銝娍聢撘𤩺迤蝖?```
### 甇仿炊 2嚗𡁏𧋦<F0A1818F>啗<EFBFBD>銵峕<E98AB5>霂?
```bash
# <20>𥕦遣瘚贝<E7989A><E8B49D>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B><EFBFBD>辣
cat > .env.docker.test <<EOF
NODE_ENV=production
PORT=3001
DATABASE_URL=postgresql://postgres:postgres@host.docker.internal:5432/ai_clinical?connection_limit=18
STORAGE_TYPE=local
CACHE_TYPE=postgres
QUEUE_TYPE=pgboss
JWT_SECRET=test-secret-key-change-in-production
DEEPSEEK_API_KEY=sk-xxxxx
DIFY_API_KEY=app-xxxxx
DIFY_API_URL=http://host.docker.internal/v1
LOG_LEVEL=info
EOF
# 餈鞱<E9A488>摰孵膥
docker run -d \
--name backend-test \
--env-file .env.docker.test \
-p 3001:3001 \
backend-service:v1.0.0
# <20>亦<EFBFBD><E4BAA6>臬𢆡<E887AC>亙<EFBFBD>
docker logs -f backend-test
# 摨磰砲<E7A3B0>见<EFBFBD>嚗?# [Config] Environment validation passed
# [Database] Connection pool calculation:
# [Database] <20>?<3F>唳旿摨栞<E691A8><E6A09E>交<EFBFBD><E4BAA4><EFBFBD><EFBFBD>
# [Fastify] Server listening on http://0.0.0.0:3001
甇仿炊 3嚗𡁏<E59A97>霂訫<E99C82>摨瑟<E691A8><E7919F>?
# 瘚贝<E7989A><E8B49D>亙熒璉<E78692><E79289>亦垢<E4BAA6>?curl http://localhost:3001/health
# 憸<><E686B8>餈𥪜<E9A488>嚗?{
"status": "healthy",
"timestamp": "2025-12-13T10:30:00.000Z",
"uptime": 45.123,
"database": {
"status": "connected",
"connections": 2
},
"version": "1.0.0"
}
甇仿炊 4嚗𡁏<E59A97>霂?API 蝡舐<E89DA1>
# 瘚贝<E7989A><E8B49D>冽<EFBFBD>瘜典<E7989C>嚗<EFBFBD>內靘页<E99D98>
curl -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "Test123456",
"name": "瘚贝<E7989A><E8B49D>冽<EFBFBD>"
}'
# 憸<><E686B8>餈𥪜<E9A488>嚗?{
"success": true,
"user": {
"id": "...",
"email": "test@example.com",
"name": "瘚贝<E7989A><E8B49D>冽<EFBFBD>"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}
甇仿炊 5嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD>霂訫捆<E8A8AB>?
# <20>𨀣迫撟嗅<E6929F><E59785>斗<EFBFBD>霂訫捆<E8A8AB>?docker stop backend-test
docker rm backend-test
# <20>𣳇膄瘚贝<E7989A><E8B49D>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B><EFBFBD>辣
rm .env.docker.test
甇仿炊 5嚗𡁏<E59A97><F0A1818F><EFBFBD>葩<EFBFBD>嗆<EFBFBD>隞?
# <20><>遣<EFBFBD>𣂼<EFBFBD><F0A382BC>𠬍<EFBFBD>皜<EFBFBD><E79A9C> backend/prisma嚗<61><E59A97><EFBFBD>滩秤<E6BBA9>𣂷漱<F0A382B7>?Git嚗?cd backend
rm -rf prisma
# 撉諹<E69289>皜<EFBFBD><E79A9C><EFBFBD>𣂼<EFBFBD>
ls prisma 2>/dev/null || echo "<22>?prisma <20>桀<EFBFBD>撌脫<E6928C><E884AB>?
# 瘜冽<E7989C>嚗𡁏覔<F0A1818F>桀<EFBFBD><E6A180>?prisma/ <20><>辣憭嫣<E686AD><E5ABA3>辷<EFBFBD>餈蹱糓皞鞉<E79A9E>隞?```
---
## 7. <20>券<EFBFBD><E588B8><EFBFBD> ACR
### 甇仿炊 1嚗𡁶蒈敶?ACR
```bash
# <20>瑕<EFBFBD> ACR <20>餃<EFBFBD><E9A483>啣<EFBFBD>嚗<EFBFBD>燵<EFBFBD>䔶<EFBFBD><E494B6>批<EFBFBD><E689B9>?<3F>?摰孵膥<E5ADB5>𨅯<EFBFBD><F0A885AF>滚𦛚 <20>?霈輸䔮<E8BCB8>剛<EFBFBD>嚗?# 蝷箔<E89DB7>嚗鬏egistry.cn-hangzhou.aliyuncs.com
# <20>餃<EFBFBD>嚗<EFBFBD>蝙<EFBFBD>?ACR 撖<><E69296>嚗䔶<E59A97><E494B6>舫燵<E888AB>䔶<EFBFBD>韐血噡撖<E599A1><E69296>嚗?docker login --username=your-aliyun-account registry.cn-hangzhou.aliyuncs.com
# 颲枏<E9A2B2>撖<EFBFBD><E69296><EFBFBD>𡒊<EFBFBD><F0A1928A>堆<EFBFBD>
# Login Succeeded
甇仿炊 2嚗𡁏<E59A97>霈圈<E99C88><E59C88>?
# <20>澆<EFBFBD>嚗鬏egistry<72>啣<EFBFBD>/<2F>賢<EFBFBD>蝛粹𡢿/隞枏<E99A9E><E69E8F>?<3F><>𧋦<EFBFBD>?docker tag backend-service:v1.0.0 \
registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:v1.0.0
# <20>峕𧒄<E5B395>㮖<EFBFBD>銝?latest <20><>倌嚗<E5808C>䲮靘踵<E99D98>霂𤏪<E99C82>
docker tag backend-service:v1.0.0 \
registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:latest
甇仿炊 3嚗𡁏綫<F0A1818F><E7B6AB><EFBFBD><EFBFBD>?
# <20>券<EFBFBD><E588B8><EFBFBD>摰𡁶<E691B0><F0A181B6>?docker push registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:v1.0.0
# <20>券<EFBFBD>?latest
docker push registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:latest
# <20>券<EFBFBD><E588B8><EFBFBD>蝔钅<E89D94>閬?5-10 <20><><EFBFBD>嚗<EFBFBD><E59A97>蝵𤑳<E89DB5><F0A491B3>笔漲嚗?```
### 甇仿炊 4嚗𡁻<E59A97>霂<EFBFBD>綫<EFBFBD><E7B6AB><EFBFBD><EFBFBD>?
<0A>餃<EFBFBD><E9A483>輸<EFBFBD>鈭烐綉<E78390>嗅蝱 <20>?摰孵膥<E5ADB5>𨅯<EFBFBD><F0A885AF>滚𦛚 <20>?<3F>𨅯<EFBFBD>隞枏<E99A9E> <20>?`backend-service`
- 摨磰砲<E7A3B0>见<EFBFBD><E8A781><EFBFBD>𧋦嚗䫤v1.0.0` <20>?`latest`
- <20>𨅯<EFBFBD>憭批<E686AD>嚗鰺300-500MB
- <20>券<EFBFBD><E588B8>𧒄<EFBFBD>湛<EFBFBD><E6B99B>𡁏<EFBFBD><F0A1818F><EFBFBD>𧒄<EFBFBD>?
---
## 8. SAE 摨𠉛鍂<F0A0899B>滨蔭
### 甇仿炊 1嚗𡁜<E59A97>撱箏<E692B1><E7AE8F>?
**<2A>輸<EFBFBD>鈭烐綉<E78390>嗅蝱** <20>?**SAE** <20>?**摨𠉛鍂<F0A0899B>𡑒”** <20>?**<2A>𥕦遣摨𠉛鍂**
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|-------|-----|------|
| **摨𠉛鍂<F0A0899B>滨妍** | `backend-service` | <20>𡒊垢<F0A1928A>滚𦛚 |
| **<2A>賢<EFBFBD>蝛粹𡢿** | <20>㗇𥋘撌脣<E6928C>撱箇<E692B1><E7AE87>賢<EFBFBD>蝛粹𡢿 | 銝?Python <20>滚𦛚<E6BB9A>䔶<EFBFBD><E494B6>賢<EFBFBD>蝛粹𡢿 |
| **VPC** | <20>㗇𥋘 RDS <20><><EFBFBD>?VPC | 敹<>◆銝?RDS <20>典<EFBFBD>銝<EFBFBD> VPC |
| **鈭斗揢<E69697>?* | <20>㗇𥋘<E39787>舐鍂<E88890>?| 撱箄悅憭𡁜虾<F0A1819C>典躹 |
| **摨𠉛鍂摰硺<E691B0>閫<EFBFBD>聢** | 2<>?G | <20>嘥<EFBFBD>閫<EFBFBD>聢 |
| **摰硺<E691B0><E7A1BA>圈<EFBFBD>** | 2 | <20><>撠?2 銝芸<E98A9D>靘页<E99D98>擃睃虾<E79D83>剁<EFBFBD> |
### 甇仿炊 2嚗𡁻<E59A97>蝵桅<E89DB5><E6A185>?
| <20>滨蔭憿?| <20>?|
|-------|-----|
| **<2A>𨅯<EFBFBD>蝐餃<E89D90>** | 摰孵膥<E5ADB5>𨅯<EFBFBD><F0A885AF>滚𦛚隡<F0A69B9A><E99AA1><EFBFBD><EFBFBD><EFBFBD>靘?|
| **<2A>𨅯<EFBFBD>隞枏<E99A9E>** | `registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service` |
| **<2A>𨅯<EFBFBD><F0A885AF><EFBFBD>𧋦** | `v1.0.0` |
| **<2A>𨅯<EFBFBD><F0A885AF>匧<EFBFBD>蝑𣇉裦** | <20>餅糓<E9A485>匧<EFBFBD><E58CA7>𨅯<EFBFBD> |
### 甇仿炊 3嚗𡁻<E59A97>蝵桃垢<E6A183>?
| <20>滨蔭憿?| <20>?|
|-------|-----|
| **摰孵膥蝡臬藁** | `3001` |
| **<2A>讛悅** | TCP |
### 甇仿炊 4嚗𡁻<E59A97>蝵桃㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD><F0A7B68F>喲睸甇仿炊嚗?
**<2A>𩤃<EFBFBD> <20>滩<EFBFBD>嚗朞窈隞𠉛<E99A9E><F0A0899B>滨蔭隞乩<E99A9E><E4B9A9>臬<EFBFBD><E887AC>㗛<EFBFBD>**
#### <20>箇<EFBFBD><E7AE87>滨蔭
```bash
NODE_ENV=production
PORT=3001
HOST=0.0.0.0
LOG_LEVEL=info
SERVICE_NAME=backend-service
<EFBFBD>唳旿摨㯄<EFBFBD>蝵殷<EFBFBD>敹<EFBFBD><EFBFBD>嚗?
# <20>𩤃<EFBFBD> 雿輻鍂 RDS <20><><EFBFBD><EFBFBD>啣<EFBFBD>
DATABASE_URL=postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical?connection_limit=18&pool_timeout=10
# 餈墧𦻖瘙𣳇<E79899>蝵殷<E89DB5><E6AEB7>寞旿 RDS 閫<>聢靚<E881A2>㟲嚗?DB_MAX_CONNECTIONS=400
MAX_INSTANCES=20
**餈墧𦻖瘙㰘恣蝞𡑒秩<F0A19192>?*嚗?- <20><>挽 RDS <20><>憭扯<E686AD><E689AF>交㺭嚗?00
- SAE <20><>憭批<E686AD>靘𧢲㺭嚗?0
- 瘥誩<EFBFBD>靘贝<EFBFBD><EFBFBD>交㺭 = (400 / 20) - 憸<><E686B8> = 18
- 憸<EFBFBD><EFBFBD> 10 銝芾<E98A9D><E88ABE>亦<EFBFBD>蝞∠<E89D9E>隞餃𦛚<E9A483><F0A69B9A><EFBFBD>隞𡝗<E99A9E><F0A19D97>?
摮睃<EFBFBD><EFBFBD>滨蔭嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
# 雿輻鍂<E8BCBB>輸<EFBFBD>鈭?OSS
STORAGE_TYPE=oss
OSS_REGION=oss-cn-beijing
OSS_BUCKET=clinical-research-files
OSS_ACCESS_KEY_ID=LTAI5t...
OSS_ACCESS_KEY_SECRET=xxx...
蝻枏<EFBFBD><EFBFBD>屸<EFBFBD><EFBFBD>烾<EFBFBD>蝵殷<EFBFBD>Postgres-Only嚗?
# 雿輻鍂 PostgreSQL 雿靝蛹蝻枏<E89DBB>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD>閬?Redis嚗?CACHE_TYPE=postgres
# 雿輻鍂 pg-boss 雿靝蛹<E99D9D>笔<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD>閬?Redis嚗?QUEUE_TYPE=pgboss
LLM API <20>滨蔭嚗<E894AD>秐撠煾<E692A0>蝵桐<E89DB5>銝迎<E98A9D>
# DeepSeek嚗<6B>綫<EFBFBD>琜<EFBFBD><E7909C>找遠瘥娪<E798A5>嚗?DEEPSEEK_API_KEY=sk-xxxxx
DEEPSEEK_BASE_URL=https://api.deepseek.com
# <20>帋<EFBFBD><E5B88B><EFBFBD>䔮嚗<E494AE><E59A97><EFBFBD>㚁<EFBFBD>
DASHSCOPE_API_KEY=sk-xxxxx
# CloseAI嚗㇉penAI/Claude 隞<><E99A9E>嚗?CLOSEAI_API_KEY=sk-xxxxx
CLOSEAI_OPENAI_BASE_URL=https://api.openai-proxy.org/v1
CLOSEAI_CLAUDE_BASE_URL=https://api.openai-proxy.org/anthropic
Dify <20>滨蔭嚗<E894AD><E59A97><EFBFBD><EFBFBD>嚗?
# <20>𩤃<EFBFBD> 雿輻鍂 ECS <20><><EFBFBD> IP嚗<50><E59A97>閬<EFBFBD>蝙<EFBFBD>典<EFBFBD>蝵穃<E89DB5><E7A983>㵪<EFBFBD>
DIFY_API_URL=http://172.17.x.x:80/v1
DIFY_API_KEY=app-xxxxx
憒<EFBFBD><EFBFBD><EFBFBD>瑕<EFBFBD> Dify <20><><EFBFBD> IP嚗?1. <20>餃<EFBFBD> ECS <20>批<EFBFBD><E689B9>?2. <20>曉<EFBFBD> Dify <20><><EFBFBD>函<EFBFBD> ECS 摰硺<E691B0>
3. <20>亦<EFBFBD>"蝘<><E89D98> IP <20>啣<EFBFBD>"嚗<><E59A97> 172.16.0.20嚗?
摰匧<EFBFBD><EFBFBD>滨蔭嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
# <20>𩤃<EFBFBD> <20>煺漣<E785BA>臬<EFBFBD>敹<EFBFBD>◆靽格㺿銝箏撩撖<E692A9><E69296>嚗<EFBFBD>秐撠?32 雿漤<E99BBF><E6BCA4>箏<EFBFBD>蝚虫葡嚗?JWT_SECRET=your-strong-random-secret-min-32-chars-change-in-production
JWT_EXPIRES_IN=7d
**<2A><><EFBFBD>撘箏<E69298><E7AE8F>?*嚗?
# Linux/Mac
openssl rand -base64 32
# Windows PowerShell
-join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | ForEach-Object {[char]$_})
CORS <20>滨蔭嚗<E894AD>虾<EFBFBD>㚁<EFBFBD>
# 憒<><E68692><EFBFBD>滨垢雿輻鍂<E8BCBB>芸<EFBFBD>銋匧<E98A8B><E58CA7>㵪<EFBFBD><E3B5AA>滨蔭<E6BBA8><E894AD>捂<EFBFBD><E68D82><EFBFBD>
# 瘜冽<E7989C>嚗𡁜<E59A97><F0A1819C>𨅯<EFBFBD>蝡臭蝙<E887AD>?Nginx <20>滚<EFBFBD>隞<EFBFBD><E99A9E>嚗<EFBFBD><E59A97>銝漤<E98A9D>閬<EFBFBD><E996AC>蝵殷<E89DB5>Nginx 撌脣<E6928C><E884A3><EFBFBD><EFBFBD>
CORS_ORIGIN=https://your-frontend-domain.com
甇仿炊 5嚗𡁻<E59A97>蝵桀<E89DB5>摨瑟<E691A8><E7919F>?
SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂<EFBFBD>滨蔭 <20>?*<2A>亙熒璉<E78692><E79289>?*
| <EFBFBD>滨蔭憿? | <EFBFBD>? | 霂湔<EFBFBD> |
|---|---|---|
| *璉<EFBFBD><EFBFBD>交䲮撘? | HTTP 霂瑟<E99C82> | |
| *璉<EFBFBD><EFBFBD>亥楝敺? | /health |
<EFBFBD>𡒊垢<EFBFBD>亙熒璉<EFBFBD><EFBFBD>亦垢<EFBFBD>? |
| *璉<EFBFBD><EFBFBD>亦垢<EFBFBD>? | 3001 | 銝𤾸捆<EFBFBD>函垢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>? |
| *璉<EFBFBD><EFBFBD>亙<EFBFBD>霈? | HTTP | |
| <EFBFBD>嘥<EFBFBD>撱嗉<EFBFBD> | 60 蝘? | 蝏?Prisma <20>嘥<EFBFBD><E598A5>𤥁雲憭<E99BB2>𧒄<EFBFBD>? |
| *璉<EFBFBD><EFBFBD>仿𡢿<EFBFBD>? | 10 蝘? | |
| 頞<EFBFBD>𧒄<EFBFBD>園𡢿 | 3 蝘? | |
| *銝滚<EFBFBD>摨琿<EFBFBD><EFBFBD>? | 3 甈? | 餈䂿賒憭梯揖 3 甈⊥<E79488>霈唬蛹銝滚<E98A9D>摨? |
| *<EFBFBD>亙熒<EFBFBD><EFBFBD><EFBFBD>? | 2 甈? | 餈䂿賒<EFBFBD>𣂼<EFBFBD> 2 甈⊥<E79488>霈唬蛹<E594AC>亙熒 |
甇仿炊 6嚗𡁻<E59A97>蝵桀撕<E6A180>找撓蝻?
*SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂<EFBFBD>滨蔭 <20>?*撘寞<EFBFBD>找撓蝻?
| <EFBFBD>滨蔭憿? | <EFBFBD>? | 霂湔<EFBFBD> |
|---|---|---|
| <EFBFBD><EFBFBD>撠誩<EFBFBD>靘𧢲㺭 | 2 | 擃睃虾<EFBFBD>其<EFBFBD>霂? |
| <EFBFBD><EFBFBD>憭批<EFBFBD>靘𧢲㺭 | 10 | <EFBFBD>寞旿憸<EFBFBD><EFBFBD>韐蠘蝸靚<EFBFBD>㟲 |
| <EFBFBD>拙捆<EFBFBD>∩辣 | CPU > 70% <20><>賒 3 <20><><EFBFBD> | |
| 蝻拙捆<EFBFBD>∩辣 | CPU < 30% <20><>賒 5 <20><><EFBFBD> |
甇仿炊 7嚗𡁻<E59A97>蝵格𠯫敹?
SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂<EFBFBD>滨蔭 <20>?<EFBFBD>亙<EFBFBD><EFBFBD>滨蔭*
| <EFBFBD>滨蔭憿? | <EFBFBD>? |
|---|---|
| <EFBFBD>亙<EFBFBD>蝐餃<EFBFBD> | <EFBFBD><EFBFBD><EFBFBD>颲枏枂嚗ìtdout嚗? |
| <EFBFBD>亙<EFBFBD>摮睃<EFBFBD> | 撘<EFBFBD><EFBFBD>荔<EFBFBD>靽嘥<EFBFBD> 7 憭抬<E686AD> |
甇仿炊 8嚗𡁻<E59A97>蝵脣<E89DB5><E884A3>?
<EFBFBD>孵稬"<22>函蔡"<22>厰僼嚗玺AE 撠<><E692A0>
- 隞?ACR <20>匧<EFBFBD><E58CA7>𨅯<EFBFBD>嚗ǚ2 <20><><EFBFBD>嚗?2. <20>臬𢆡摰孵膥摰硺<E691B0>嚗ǚ1 <20><><EFBFBD>嚗?3. <20>扯<EFBFBD><E689AF>亙熒璉<E78692><E79289>伐<EFBFBD>~1 <20><><EFBFBD>嚗?4. 瘚<><E7989A><EFBFBD><EFBFBD>揢嚗ǚ30 蝘𡜐<E89D98>
<EFBFBD>餉<EFBFBD>埈𧒄嚗𡁶漲 5 <20><><EFBFBD>
9. <20>唳旿摨㯄<E691A8>蝵脩<E89DB5><E884A9>?
<EFBFBD>㴓 <20>函<EFBFBD>摰鮋<E691B0><E9AE8B><EFBFBD><EFBFBD>嚗<EFBFBD><E59A97>撣賊<E692A3>閬<EFBFBD><E996AC>
<EFBFBD>寞旿<EFBFBD>函<EFBFBD>撘<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>莎<EFBFBD><EFBFBD>唳旿摨㯄<EFBFBD>蝵脩<EFBFBD><EFBFBD>乩<EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD>**摰<><E691B0>銝滚<E98A9D>**嚗? **<2A><><EFBFBD>瘚<EFBFBD><E7989A>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD>剁<EFBFBD>**嚗?```mermaid graph LR A[隞<><E99A9E>] --> B[Prisma Migrations] B --> C[蝛箸㺭<E7AEB8>桀<EFBFBD>] C --> D[<5B>芸𢆡<E88AB8>𥕦遣銵函<E98AB5><E587BD><EFBFBD>
**<2A>函<EFBFBD>摰鮋<E691B0>瘚<EFBFBD><E7989A>**嚗?```mermaid
graph LR
A[<5B>砍𧑐 PostgreSQL<br/><3E><>鉄<EFBFBD>唳旿] --> B[pg_dump 撖澆枂]
B --> C[RDS 撖澆<E69296>]
C --> D[銵函<E98AB5><E587BD><EFBFBD>歇摮睃銁]
D --> E[Prisma <20>滚<EFBFBD><E6BB9A>峕郊]
<EFBFBD>?甇<>&<EFBFBD><EFBC86><EFBFBD>蝵脩<E89DB5><E884A9>?
蝑𣇉裦<EFBFBD>餉<EFBFBD>
| 甇仿炊 | <EFBFBD>滢<EFBFBD> | 雿閙𧒄<EFBFBD>扯<EFBFBD> | <EFBFBD>桃<EFBFBD> |
|---|---|---|---|
| *1. 撖澆枂<E6BE86>砍𧑐<E7A08D>唳旿摨? | pg_dump |
擐𡝗活<EFBFBD>函蔡<EFBFBD>? | 憭<EFBFBD>遢<EFBFBD>唳<EFBFBD><EFBFBD>唳旿<EFBFBD>𣬚<EFBFBD><EFBFBD>? |
| 2. 撖澆<E69296><E6BE86>?RDS | psql <20>?DMS |
擐𡝗活<EFBFBD>函蔡<EFBFBD>? | 餈<EFBFBD>宏<EFBFBD>唬<EFBFBD>蝡? |
| 3. Prisma <20>滚<EFBFBD><E6BB9A>峕郊 | prisma db pull |
擐𡝗活<EFBFBD>函蔡<EFBFBD>㵪<EFBFBD>蝚?4 <20><><EFBFBD> | <EFBFBD>峕郊 Schema |
| 4. <20>臬𢆡摨𠉛鍂 | node dist/index.js |
SAE <20>函蔡<E587BD>? | 甇<EFBFBD>虜餈鞱<EFBFBD> |
| 5. ~ |
prisma migrate deploy |
<EFBFBD>?*銝齿<EFBFBD>銵? | 銵典歇摮睃銁嚗峕<EFBFBD><EFBFBD><EFBFBD>餈<EFBFBD>宏 |
<EFBFBD>寞<EFBFBD> 1嚗帋蝙<E5B88B>?pg_dump 撖澆<E69296>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蛛<EFBFBD><E89B9B>刻<EFBFBD>嚗?
甇仿炊 1嚗𡁜紡<F0A1819C>箸𧋦<E7AEB8>唳㺭<E594B3>桀<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>𡏭<EFBFBD>瘝∪<E7989D>嚗?
# <20>冽𧋦<E586BD>啣<EFBFBD><E595A3>𤑳㴓憓<E3B493><E68693>銵?docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical \
--no-owner --no-acl --clean --if-exists \
> ai_clinical_backup_$(date +%Y%m%d).sql
# <20>亦<EFBFBD>撖澆枂<E6BE86><E69E82>辣
ls -lh ai_clinical_backup_*.sql
# 摨磰砲<E7A3B0>见<EFBFBD><E8A781><EFBFBD>辣憭批<E686AD>嚗<EFBFBD><E59A97> 5.2MB嚗?```
#### 甇仿炊 2嚗𡁜紡<F0A1819C>亙<EFBFBD> RDS嚗<53><E59A97><EFBFBD>𡏭<EFBFBD>瘝∪<E7989D>嚗?
**<2A>寞<EFBFBD> A嚗帋蝙<E5B88B>?psql <20>賭誘銵䕘<E98AB5><E49598>刻<EFBFBD>嚗?*
```bash
# 餈墧𦻖<E5A2A7>?RDS 撟嗅紡<E59785>?psql "postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical" \
< ai_clinical_backup_20251213.sql
# 颲枏枂蝷箔<E89DB7>嚗?# DROP TABLE
# CREATE TABLE
# INSERT 0 123
# ...
# <20>?撖澆<E69296>摰峕<E691B0>
*<EFBFBD>寞<EFBFBD> B嚗帋蝙<E5B88B>?DMS嚗<53>燵<EFBFBD>䔶<EFBFBD><E494B6>唳旿蝞∠<E89D9E>嚗?
- <EFBFBD>餃<EFBFBD><EFBFBD>輸<EFBFBD>鈭烐綉<EFBFBD>嗅蝱 <20>?<3F>唳旿蝞∠<E89D9E> DMS
- 餈墧𦻖<EFBFBD>?RDS 摰硺<E691B0>
- <EFBFBD>唳旿<EFBFBD>寞<EFBFBD> <20>?SQL 蝒堒藁 <20>?蝎䁅斐 SQL <20><>辣<EFBFBD><E8BEA3>捆
- <EFBFBD>扯<EFBFBD>
甇仿炊 3嚗𡁻<E59A97>霂<EFBFBD>紡<EFBFBD>交<EFBFBD><E4BAA4>?
# 餈墧𦻖<E5A2A7>?RDS
psql "postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical"
# <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>?Schema
\dn
# 摨磰砲<E7A3B0>见<EFBFBD>嚗?# aia_schema
# asl_schema
# common_schema
# dc_schema
# pkb_schema
# platform_schema
# rvw_schema
# ssa_schema
# st_schema
# public
# <20>亦<EFBFBD><E4BAA6>冽<EFBFBD>銵?SELECT count(*) FROM "User";
# 摨磰砲餈𥪜<E9A488>甇<EFBFBD>&<EFBFBD><EFBC86>鍂<EFBFBD>瑟㺭<E7919F>?
# <20><><EFBFBD>?\q
甇仿炊 4嚗𡁶&霈文歇<E69687>扯<EFBFBD> Prisma <20>滚<EFBFBD><E6BB9A>峕郊
<EFBFBD>𩤃<EFBFBD> 餈嗘<E9A488>甇仿<E79487>撣詨<E692A3><E8A9A8>殷<EFBFBD>
# 蝖桐<E89D96>蝚?4 <20><><EFBFBD>甇仿炊撌脣<E6928C><E884A3>琜<EFBFBD>
# 1. 撌脫<E6928C>銵?npx prisma db pull
# 2. 撌脫<E6928C>銵?npx prisma generate
# 3. 撌脫<E6928C>鈭?schema.prisma <20>?Git
# 撉諹<E69289>嚗𡁏<E59A97><F0A1818F>?schema.prisma <20><>耨<EFBFBD>寞𧒄<E5AF9E>?ls -l prisma/schema.prisma
# 靽格㺿<E6A0BC>園𡢿摨磰砲<E7A3B0>舀<EFBFBD>餈𡢅<E9A488>隞𠰴予嚗?
# 憒<><E68692>餈䀹瓷<E480B9>𡄯<EFBFBD>蝡见朖餈𥪜<E9A488>蝚?4 <20><><EFBFBD>銵䕘<E98AB5>
<EFBFBD>寞<EFBFBD> 2嚗𡁏<E59A97><F0A1818F>?Prisma Migrations嚗<73><E59A97><EFBFBD><EFBFBD>鍂鈭擧鰵憿寧𤌍嚗?
<EFBFBD>𩤃<EFBFBD> 憒<><E68692><EFBFBD>函<EFBFBD><E587BD>唳旿摨𤘪糓<F0A498AA>朞<EFBFBD> pg_dump 撖澆<E69296><E6BE86><EFBFBD><EFBFBD>霂瑁歲餈<E6ADB2><E9A488>銝<EFBFBD><E98A9D><EFBFBD><EFBFBD>
<EFBFBD>孵稬撅訫<EFBFBD>嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝘餅<EFBFBD>蝔页<EFBFBD>隞<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>鍂<EFBFBD>箸艶
- <EFBFBD>冽鰵憿寧𤌍嚗朙DS <20>唳旿摨𤘪糓蝛箇<E89D9B>
- 隞擧𧊋<EFBFBD>见𢆡靽格㺿餈<EFBFBD>㺭<EFBFBD>桀<EFBFBD>蝏𤘪<EFBFBD>
- <EFBFBD><EFBFBD><EFBFBD>㕑”蝏𤘪<EFBFBD><EFBFBD>賡<EFBFBD>朞<EFBFBD> Prisma Migrations 蝞∠<E89D9E>
<EFBFBD>扯<EFBFBD>甇仿炊
# 1. 餈墧𦻖<E5A2A7>?RDS
export DATABASE_URL="postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical"
# 2. <20>扯<EFBFBD>餈<EFBFBD>宏
cd backend
npx prisma migrate deploy
# 3. 撉諹<E69289>
npx prisma db execute --stdin <<< "SELECT schemaname FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY schemaname;"
<EFBFBD>辶 撣貉<E692A3><E8B289>躰秤銝𦒘耨甇?
<EFBFBD>躰秤 1嚗𡁜鍳<F0A1819C>冽𧒄<E586BD>扯<EFBFBD> prisma migrate deploy 撖潸稲憭梯揖
**<2A>躰秤靽⊥<E99DBD>**嚗?
Error: P3005: The database schema is not empty. Read more about how to baseline an existing production database: https://pris.ly/d/migrate-baseline
**<2A>笔<EFBFBD>**嚗朞”撌脤<E6928C>朞<EFBFBD> pg_dump 撖澆<E69296>嚗<EFBFBD><E59A97><EFBFBD>扯<EFBFBD> migrate 隡𡁜<E99AA1>蝒<EFBFBD><E89D92>?
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# <20>寞<EFBFBD> 1嚗𡁶宏<F0A181B6>文鍳<E69687>典𦶢隞支葉<E694AF>?migrate嚗<65>綫<EFBFBD>琜<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>滨蔭 <20>?<3F>臬𢆡<E887AC>賭誘
# 蝖桐<E89D96><E6A190>臬𢆡<E887AC>賭誘<E8B3AD>荔<EFBFBD>
node dist/index.js
# 銝滩<E98A9D><E6BBA9>辷<EFBFBD>
# sh -c "npx prisma migrate deploy && node dist/index.js" # <20>?```
#### <20>躰秤 2嚗𡁜<E59A97><F0A1819C>典鍳<E585B8>典<EFBFBD>嚗諹挪<E8ABB9>格㺭<E6A0BC>桀<EFBFBD><E6A180>仿<EFBFBD>
**<2A>躰秤靽⊥<E99DBD>**嚗?
```typescript
PrismaClientKnownRequestError:
Invalid `prisma.user.findMany()` invocation:
column "phone" does not exist
**<2A>笔<EFBFBD>**嚗䫤schema.prisma銝擧㺭<EFBFBD>桀<EFBFBD>銝滢<EFBFBD><EFBFBD>氬<EFBFBD>? **閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗? 餈𥪜<E9A488>蝚?4 <20><><EFBFBD><EFBFBD>扯<EFBFBD>npx prisma db pull` <20>滚<EFBFBD><E6BB9A>峕郊<E5B395>?
<EFBFBD>?<3F>函蔡璉<E894A1><E79289>交<EFBFBD><E4BAA4>?
<EFBFBD>典鍳<EFBFBD>?SAE 摨𠉛鍂<F0A0899B>㵪<EFBFBD>蝖株恕隞乩<E99A9E>甇仿炊撌脣<E6928C><E884A3>琜<EFBFBD>
- <EFBFBD>砍𧑐<EFBFBD>唳旿摨枏歇<EFBFBD>朞<EFBFBD>
pg_dump撖澆枂 - SQL <20><>辣撌脣紡<E884A3>亙<EFBFBD> RDS嚗<53>”蝏𤘪<E89D8F><F0A498AA>峕㺭<E5B395>桅<EFBFBD>摮睃銁嚗?- [ ] 撌脫<E6928C>銵?
npx prisma db pull<20>峕郊 Schema - 撌脫<EFBFBD>銵?
npx prisma generate<20><><EFBFBD>摰X<E691B0>蝡?- [ ] 撌脫<E6928C>鈭?schema.prisma<20>?Git - Docker <20>𨅯<EFBFBD><F0A885AF><EFBFBD>鍳<EFBFBD>典𦶢隞?銝滚<EFBFBD><EFBFBD>?
prisma migrate deploy - SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>銝剔<E98A9D>
DATABASE_URL<20><><EFBFBD> RDS
*憒<EFBFBD><EFBFBD>隞乩<EFBFBD><EFBFBD>賜&霈歹<EFBFBD><EFBFBD>臭誑<EFBFBD>曉<EFBFBD><EFBFBD>函蔡嚗? <20>?
10. 蝡臬<E89DA1>蝡舀<E89DA1>霂?
甇仿炊 1嚗朞繮<E69C9E>硋<EFBFBD><E7A18B>刻挪<E588BB>桀𧑐<E6A180><F0A79190>
*SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂霂行<EFBFBD> <20>?摨𠉛鍂霈輸䔮<EFBFBD>滨蔭
憭滚<EFBFBD>隞乩<EFBFBD><EFBFBD>啣<EFBFBD>嚗?
# <20>祉<EFBFBD>霈輸䔮<E8BCB8>啣<EFBFBD>嚗<EFBFBD>鍂鈭𤾸<E988AD>蝡航<E89DA1><E888AA>剁<EFBFBD>
https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com
# VPC <20><><EFBFBD>霈輸䔮<E8BCB8>啣<EFBFBD>嚗<EFBFBD>鍂鈭擧<E988AD><E693A7>⊿𡢿靚<F0A1A2BF>鍂嚗?http://172.16.0.30:3001
甇仿炊 2嚗𡁏<E59A97>霂訫<E99C82>摨瑟<E691A8><E7919F>?
# 雿輻鍂<E8BCBB>祉<EFBFBD><E7A589>啣<EFBFBD>瘚贝<E7989A>
curl https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/health
# 憸<><E686B8>餈𥪜<E9A488>嚗?{
"status": "healthy",
"timestamp": "2025-12-13T10:30:00.000Z",
"uptime": 12345.678,
"database": {
"status": "connected",
"connections": 8
},
"version": "1.0.0"
}
甇仿炊 3嚗𡁏<E59A97>霂閧鍂<E996A7>瑟釣<E7919F>?
curl -X POST https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "sae-test@example.com",
"password": "Test123456",
"name": "SAE瘚贝<E7989A><E8B49D>冽<EFBFBD>"
}'
# 憸<><E686B8>餈𥪜<E9A488>嚗?{
"success": true,
"user": {
"id": "...",
"email": "sae-test@example.com",
"name": "SAE瘚贝<E7989A><E8B49D>冽<EFBFBD>"
},
"token": "eyJhbGciOiJIUzI1NiIs..."
}
甇仿炊 4嚗𡁏<E59A97>霂閙<E99C82>隞嗡<E99A9E>隡𩤃<E99AA1>PKB 璅∪<E79285>嚗?
# <20>瑕<EFBFBD> Token嚗<6E><E59A97>甇仿炊 3嚗?TOKEN="eyJhbGciOiJIUzI1NiIs..."
# 銝𠹺<E98A9D> PDF <20><>﹝
curl -X POST https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/api/knowledge-bases/kb-xxx/documents \
-H "Authorization: Bearer $TOKEN" \
-F "file=@test.pdf" \
-F "name=瘚贝<E7989A><E8B49D><EFBFBD>﹝"
# 憸<><E686B8>餈𥪜<E9A488>嚗?{
"success": true,
"document": {
"id": "...",
"name": "瘚贝<E7989A><E8B49D><EFBFBD>﹝",
"status": "processing"
}
}
甇仿炊 5嚗𡁏<E59A97>霂?Python 敺格<E695BA><E6A0BC>∟<EFBFBD><E2889F>?
# 瘚贝<E7989A> ASL 璅∪<E79285><E288AA>?PDF <20>𣂼<EFBFBD><F0A382BC>蠘<EFBFBD>
curl -X POST https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/api/asl/extract \
-H "Authorization: Bearer $TOKEN" \
-F "file=@paper.pdf"
# <20>亦<EFBFBD><E4BAA6>𡒊垢<F0A1928A>亙<EFBFBD>嚗𠄎AE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>亙<EFBFBD>嚗?# 摨磰砲<E7A3B0>见<EFBFBD>嚗?# [INFO] Calling extraction service: http://172.17.x.x:8000/extract/pdf
# [INFO] Extraction completed in 3.2s
甇仿炊 6嚗𡁏<E59A97>霂?Dify <20>滚𦛚靚<F0A69B9A>鍂
# 瘚贝<E7989A> PKB 璅∪<E79285><E288AA><EFBFBD>䰻霂<E4B0BB><E99C82>撖寡<E69296>
curl -X POST https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/api/knowledge-bases/kb-xxx/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "餈嗵<E9A488><E597B5><EFBFBD>讃<EFBFBD><E8AE83><EFBFBD>蝛嗆䲮瘜閙糓隞<E7B393>銋<EFBFBD><E98A8B>",
"conversationId": "conv-xxx"
}'
# <20>亦<EFBFBD><E4BAA6>𡒊垢<F0A1928A>亙<EFBFBD>
# 摨磰砲<E7A3B0>见<EFBFBD>嚗?# [INFO] Calling Dify API: http://172.17.x.x:80/v1/chat-messages
# [INFO] Dify response received in 2.5s
甇仿炊 7嚗𡁏<E59A97>霂?OSS <20><>辣銝𠹺<E98A9D>
# 銝𠹺<E98A9D>憭扳<E686AD>隞塚<E99A9E>瘚贝<E7989A> OSS嚗?curl -X POST https://backend-service-xxxxx.cn-hangzhou.sae.aliyuncs.com/api/asl/upload \
-H "Authorization: Bearer $TOKEN" \
-F "file=@large-paper.pdf"
# <20>亦<EFBFBD><E4BAA6>亙<EFBFBD>嚗<EFBFBD><E59A97>霂亦<E99C82><E4BAA6>?OSS 銝𠹺<E98A9D><F0A0B9BA>𣂼<EFBFBD>嚗?# [INFO] File uploaded to OSS: clinical-research-files/asl/xxx.pdf
11. <20>烐綉銝𡒊輕<F0A1928A>?
<EFBFBD><EFBFBD> SAE <20>芸蒂<E88AB8>烐綉
1. 摰墧𧒄<E5A2A7>烐綉
SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂霂行<EFBFBD> <20>?<EFBFBD>烐綉*
**<2A>喲睸<E596B2><E79DB8><EFBFBD>**嚗?
| <EFBFBD><EFBFBD><EFBFBD> | <EFBFBD>亙熒<EFBFBD><EFBFBD><EFBFBD>? | <EFBFBD>𡃏郎<EFBFBD><EFBFBD><EFBFBD>? | 霂湔<EFBFBD> |
|---|---|---|---|
| *CPU 雿輻鍂<E8BCBB>? | < 60% | > 80% | LLM 靚<>鍂<EFBFBD>?CPU 撖<><E69296><EFBFBD>? |
| *<EFBFBD><EFBFBD><EFBFBD>雿輻鍂<EFBFBD>? | < 70% | > 85% | <EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD>瘜<EFBFBD><EFBFBD> |
| 霂瑟<EFBFBD> QPS | - | - | 鈭<EFBFBD>圾韐蠘蝸 |
| 撟喳<EFBFBD><EFBFBD>滚<EFBFBD><EFBFBD>園𡢿 | < 500ms | > 2000ms | AI 撖寡<E69296><E5AFA1>文<EFBFBD>嚗<EFBFBD>虾<EFBFBD>?10s+嚗? |
| *<EFBFBD>躰秤<EFBFBD>? | < 0.5% | > 2% | <EFBFBD>烐綉<EFBFBD>滚𦛚蝔喳<EFBFBD><EFBFBD>? |
| 摰硺<EFBFBD><EFBFBD>圈<EFBFBD> | 2+ | - | 蝖桐<EFBFBD>擃睃虾<EFBFBD>? |
2. <20>亙<EFBFBD><E4BA99>亦<EFBFBD>
SAE <20>批<EFBFBD><E689B9>? <20>?摨𠉛鍂霂行<EFBFBD> <20>?<EFBFBD>亙<EFBFBD>* <20>?摰墧𧒄<EFBFBD>亙<EFBFBD>
**<2A>喲睸<E596B2>亙<EFBFBD>蝷箔<E89DB7>**嚗?
# <20>?甇<>虜<EFBFBD>臬𢆡
[Config] Environment validation passed
[Database] <20>?<3F>唳旿摨栞<E691A8><E6A09E>交<EFBFBD><E4BAA4><EFBFBD><EFBFBD>
[Fastify] Server listening on http://0.0.0.0:3001
# <20>?甇<>虜霂瑟<E99C82>
[INFO] POST /api/chat 200 2345ms
# <20>𩤃<EFBFBD> 霅血<E99C85><E8A180>亙<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>單釣嚗?[WARN] Database connection pool near limit: 16/18 connections
# <20>?<3F>躰秤<E8BAB0>亙<EFBFBD>嚗<EFBFBD><E59A97>蝡见朖憭<E69C96><E686AD>嚗?[ERROR] Failed to connect to Python service: ECONNREFUSED
[ERROR] Prisma timeout: Database connection pool exhausted
[ERROR] Dify API error: 502 Bad Gateway
3. <20>唳旿摨栞<E691A8><E6A09E>亦<EFBFBD><E4BAA6>?
# <20>?SAE Webshell 銝剜<E98A9D>銵䕘<E98AB5><E49598>碶蝙<E7A2B6>?RDS <20>批<EFBFBD><E689B9>堆<EFBFBD>
psql $DATABASE_URL -c "
SELECT
count(*) as total_connections,
count(*) FILTER (WHERE state = 'active') as active_connections,
count(*) FILTER (WHERE state = 'idle') as idle_connections
FROM pg_stat_activity
WHERE datname = 'ai_clinical';
"
# 颲枏枂蝷箔<E89DB7>嚗?# total_connections | active_connections | idle_connections
# ------------------+--------------------+-----------------
# 35 | 5 | 30
# <20>𡃏郎<F0A1838F>∩辣嚗魩otal_connections > (MAX_INSTANCES * connection_limit * 0.8)
# 蝷箔<E89DB7>嚗?0 摰硺<E691B0> * 18 餈墧𦻖/摰硺<E691B0> * 0.8 = 288 餈墧𦻖
<EFBFBD>圲 <20>亙虜蝏湔擪隞餃𦛚
瘥𤩺𠯫璉<EFBFBD><EFBFBD>?
# 1. 璉<><E79289>亙<EFBFBD><E4BA99>典<EFBFBD>摨瑞𠶖<E7919E>?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>𡑒” <20>?<3F>亦<EFBFBD>餈鞱<E9A488><E99EB1>嗆<EFBFBD><E59786><EFBFBD>蝏輯𠧧銝箸迤撣賂<E692A3>
# 2. <20>亦<EFBFBD><E4BAA6>躰秤<E8BAB0>亙<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>亙<EFBFBD> <20>?蝑偦<E89D91>?ERROR 蝥批<E89DA5>
# 3. 璉<><E79289>交㺭<E4BAA4>桀<EFBFBD>餈墧𦻖<E5A2A7>?# RDS <20>批<EFBFBD><E689B9>?<3F>?摰硺<E691B0><E7A1BA>烐綉 <20>?餈墧𦻖<E5A2A7>堆<EFBFBD>< 80% 銝箏<E98A9D>摨瘀<E691A8>
瘥誩𪂹隞餃𦛚
# 1. <20>亦<EFBFBD><E4BAA6>扯<EFBFBD><E689AF><EFBFBD><EFBFBD>頞见飵
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>烐綉 <20>?<3F>㗇𥋘"<22><>餈?7 憭?
# <20>單釣嚗?# - CPU/<2F><><EFBFBD><EFBFBD>臬炏<E887AC>㗇<EFBFBD>蝏凋<E89D8F>瘨剁<E798A8><E58981><EFBFBD><EFBFBD>瘜<EFBFBD><E7989C>嚗<EFBFBD><E59A97>
# - <20>滚<EFBFBD><E6BB9A>園𡢿<E59C92>臬炏<E887AC>䀹<EFBFBD>
# - <20>躰秤<E8BAB0><E7A7A4>糓<EFBFBD>血<EFBFBD><E8A180>?
# 2. 皜<><E79A9C><EFBFBD>亙<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>𨀣𠯫敹堒<E695B9><E5A092>函征<E587BD>渡揮撘𩤃<E69298>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>亙<EFBFBD><E4BA99>滨蔭 <20>?皜<><E79A9C><EFBFBD>扳𠯫敹?```
#### 瘥𤩺<E798A5>隞餃𦛚
```bash
# 1. <20>湔鰵靘肽<E99D98>嚗<EFBFBD><E59A97><EFBFBD>刻‘銝<E28098><E98A9D>
# <20>冽𧋦<E586BD>啣<EFBFBD><E595A3>𤑳㴓憓<E3B493><E68693>銵䕘<E98AB5>
npm outdated
npm update
npm audit fix
# <20>齿鰵瘚贝<E7989A><E8B49D>𡡞<EFBFBD>蝵?
# 2. <20>滚遣<E6BB9A>𨅯<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>怎頂蝏笔<E89D8F><E7AC94>冽凒<E586BD>堆<EFBFBD>
docker build -t backend-service:v1.0.1 .
docker push registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:v1.0.1
# 3. <20>?SAE 銝剔<E98A9D>摨行凒<E8A18C>?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>函蔡
# <20>㗇𥋘<E39787>圈<EFBFBD><E59C88>讐<EFBFBD><E8AE90>穿<EFBFBD>v1.0.1
# <20>啣漲<E595A3>穃<EFBFBD>嚗𡁜<E59A97><F0A1819C>湔鰵 1 銝芸<E98A9D>靘页<E99D98>閫<EFBFBD><E996AB> 10 <20><><EFBFBD><EFBFBD>𤾸<EFBFBD><F0A4BEB8>誩<EFBFBD>撣?
# 4. <20>唳旿摨枏<E691A8>隞踝<E99A9E>RDS <20>芸𢆡憭<F0A286A1>遢嚗䔶<E59A97><E494B6><EFBFBD>撉諹<E69289>嚗?# RDS <20>批<EFBFBD><E689B9>?<3F>?憭<>遢<EFBFBD>W<EFBFBD> <20>?<3F>亦<EFBFBD><E4BAA6><EFBFBD>餈穃<E9A488>隞賣𧒄<E8B3A3>?```
### <20>辶 <20>𡃏郎<F0A1838F>滨蔭
**鈭𤑳<E988AD><F0A491B3>?* <20>?**摨𠉛鍂<F0A0899B>烐綉** <20>?**<2A>𥕦遣<F0A595A6>𡃏郎閫<E9838E><E996AB>**
**<2A>刻<EFBFBD><E588BB>𡃏郎閫<E9838E><E996AB>**嚗?
| <20>𡃏郎憿?| <20><><EFBFBD>?| <20>𡁶䰻<F0A181B6>孵<EFBFBD> |
|-------|------|---------|
| CPU 雿輻鍂<E8BCBB>?> 80% <20><>賒 5 <20><><EFBFBD> | <20>𡃏郎 | <20>厰<EFBFBD>/<2F>桐辣 |
| <20><><EFBFBD>雿輻鍂<E8BCBB>?> 85% <20><>賒 5 <20><><EFBFBD> | <20>𡃏郎 | <20>厰<EFBFBD>/<2F>桐辣 |
| <20>躰秤<E8BAB0>?> 2% <20><>賒 3 <20><><EFBFBD> | 蝝扳<E89D9D>?| <20>凋縑+<2B>厰<EFBFBD> |
| 摰硺<E691B0><E7A1BA>亙熒璉<E78692><E79289>亙仃韐?> 3 甈?| 蝝扳<E89D9D>?| <20>凋縑+<2B>厰<EFBFBD> |
| RDS 餈墧𦻖<E5A2A7>?> 80% | 霅血<E99C85> | <20>厰<EFBFBD>/<2F>桐辣 |
---
## 12. <20><><EFBFBD><EFBFBD>埝䰻
### <20>桅<EFBFBD> 1嚗𡁜<E59A97><F0A1819C>典鍳<E585B8>典仃韐?
**<2A><>𠶖**嚗?
SAE <20>批<EFBFBD><E689B9>唳遬蝷綽<E89DB7>摰硺<E691B0><E7A1BA>臬𢆡銝?<3F>?<3F>亙熒璉<E78692><E79289>亙仃韐?<3F>?摰硺<E691B0><E7A1BA>𨀣迫
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. <20>亦<EFBFBD><E4BAA6>臬𢆡<E887AC>亙<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>亙<EFBFBD> <20>?蝑偦<E89D91>㗇<EFBFBD>餈?5 <20><><EFBFBD>
# 2. 撣貉<E692A3><E8B289>躰秤<E8BAB0>笔<EFBFBD>嚗?
# <20>躰秤 A嚗𡁶㴓憓<E3B493><E68693><EFBFBD>誯<EFBFBD>霂<EFBFBD>仃韐?# <20>亙<EFBFBD>嚗尠<E59A97> [Config] Environment validation failed: DATABASE_URL is required
# 閫<><E996AB>嚗𡁏<E59A97><F0A1818F>?SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>滨蔭嚗諹‘<E8ABB9><E28098>撩憭梁<E686AD><E6A281>㗛<EFBFBD>
# <20>躰秤 B嚗𡁏㺭<F0A1818F>桀<EFBFBD>餈墧𦻖憭梯揖
# <20>亙<EFBFBD>嚗尠<E59A97> <20>唳旿摨栞<E691A8><E6A09E>亙仃韐? getaddrinfo ENOTFOUND pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com
# 閫<><E996AB>嚗?# - 璉<><E79289>?DATABASE_URL <20>臬炏甇<E7828F>&
# - 璉<><E79289>?RDS <20>賢<EFBFBD><E8B3A2>閙糓<E99699>血<EFBFBD>霈?SAE VPC 霈輸䔮
# - 璉<><E79289>?RDS <20><><EFBFBD><EFBFBD>啣<EFBFBD><E595A3>臬炏<E887AC>航噢
# <20>躰秤 C嚗䥪risma 餈<>宏<EFBFBD>芣<EFBFBD>銵?# <20>亙<EFBFBD>嚗鍃rror: P1001: Can't reach database server at `pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com`
# 閫<><E996AB>嚗𡁜<E59A97><F0A1819C>扯<EFBFBD><E689AF>唳旿摨栞<E691A8>蝘鳴<E89D98><E9B3B4><EFBFBD><EFBFBD>蝚?8 <20><><EFBFBD>
# <20>躰秤 D嚗𡁶垢<F0A181B6><E59EA2><EFBFBD>蝒?# <20>亙<EFBFBD>嚗鍃rror: listen EADDRINUSE: address already in use :::3001
# 閫<><E996AB>嚗𡁏<E59A97><F0A1818F>?PORT <20>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>臬炏銝?3001嚗<31><E59A97> Dockerfile EXPOSE 銝<><E98A9D>湛<EFBFBD>
<EFBFBD>桅<EFBFBD> 2嚗𡁏㺭<F0A1818F>桀<EFBFBD>餈墧𦻖瘙㰘<E79899>堒偷
<EFBFBD><EFBFBD>𠶖嚗?
[ERROR] Prisma timeout: Database connection pool exhausted
[ERROR] P2024: Timed out fetching a new connection from the pool
**<2A>寞𧋦<E5AF9E>笔<EFBFBD>**嚗?
- SAE 摰硺<E691B0><E7A1BA>?* 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 > RDS <20><>憭扯<E686AD><E689AF>交㺭
- 餈墧𦻖<EFBFBD>芣迤蝖桅<EFBFBD><EFBFBD>橘<EFBFBD>隞<EFBFBD><EFBFBD> Bug嚗? <EFBFBD>埝䰻甇仿炊嚗?
# 1. 璉<><E79289>亙<EFBFBD><E4BA99>滩<EFBFBD><E6BBA9>交㺭
psql $DATABASE_URL -c "
SELECT count(*) as current_connections
FROM pg_stat_activity
WHERE datname = 'ai_clinical';
"
# 2. 璉<><E79289>?SAE 摰硺<E691B0><E7A1BA>?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?摰硺<E691B0><E7A1BA>𡑒”
# <20><>挽<EFBFBD>?10 銝芸<E98A9D>靘?
# 3. 霈∠<E99C88>餈墧𦻖<E5A2A7>?# 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 = 18嚗Ếonnection_limit嚗?# <20>餉<EFBFBD><E9A489>交㺭 = 10 * 18 = 180
# 憒<><E68692>摰鮋<E691B0>餈墧𦻖<E5A2A7>啗<EFBFBD>頞?180嚗諹秩<E8ABB9>舘<EFBFBD><E88898>交𧊋<E4BAA4>𦠜𦆮
# 4. <20>交𪄳餈墧𦻖瘜<F0A6BB96><E7989C>
psql $DATABASE_URL -c "
SELECT pid, state, wait_event, query_start, state_change, query
FROM pg_stat_activity
WHERE datname = 'ai_clinical'
AND state_change < now() - interval '5 minutes'
ORDER BY state_change;
"
# 5. 蝝扳<E89D9D>亙<EFBFBD><E4BA99><EFBFBD><EFBFBD><EFBFBD><EFBFBD>甇駁鵭<E9A781>園𡢿蝛粹𤦭餈墧𦻖
psql $DATABASE_URL -c "
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'ai_clinical'
AND state = 'idle'
AND state_change < now() - interval '10 minutes';
"
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# <20>寞<EFBFBD> 1嚗朞<E59A97><E69C9E>渲<EFBFBD><E6B8B2>交<EFBFBD><E4BAA4>滨蔭嚗<E894AD>葩<EFBFBD>塚<EFBFBD>
# <20>?DATABASE_URL 銝剝<E98A9D>雿?connection_limit
DATABASE_URL=postgresql://...?connection_limit=10&pool_timeout=10
# <20>寞<EFBFBD> 2嚗𡁻<E59A97><F0A181BB>?SAE 摰硺<E691B0><E7A1BA>堆<EFBFBD>銝湔𧒄嚗?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>滨蔭 <20>?撘寞<E69298>找撓蝻?# 撠<><E692A0>憭批<E686AD>靘𧢲㺭隞?20 <20>滢<EFBFBD><E6BBA2>?10
# <20>寞<EFBFBD> 3嚗𡁜<E59A97>蝥?RDS 閫<>聢嚗<E881A2>鵭<EFBFBD><E9B5AD><EFBFBD>
# RDS <20>批<EFBFBD><E689B9>?<3F>?<3F>䀹凒<E480B9>滨蔭 <20>?<3F><>漣<EFBFBD>唳凒憭扯<E686AD><E689AF>潘<EFBFBD>憓𧼮<E68693><F0A7BCAE><EFBFBD>憭扯<E686AD><E689AF>交㺭嚗?
# <20>寞<EFBFBD> 4嚗帋耨憭滢誨<E6BBA2><E8AAA8><EFBFBD>憒<EFBFBD><E68692><EFBFBD>航<EFBFBD><E888AA>交<EFBFBD>瞍𧶏<E79E8D>
# 璉<><E79289>乩誨<E4B9A9><E8AAA8>葉<EFBFBD>臬炏<E887AC>㗇𧊋<E39787>𦠜𦆮<F0A6A09C><F0A686AE><EFBFBD><EFBFBD>伐<EFBFBD>
# - <20>芯蝙<E88AAF>?Prisma <20><><EFBFBD><EFBFBD>?API
# - <20>见𢆡<E8A781>𥕦遣<F0A595A6><E981A3>㺭<EFBFBD>桀<EFBFBD>餈墧𦻖<E5A2A7>芸<EFBFBD><E88AB8>?# - <20>踵𧒄<E8B8B5>渲<EFBFBD>銵𣬚<E98AB5><F0A3AC9A>亥砭
<EFBFBD>桅<EFBFBD> 3嚗𡁏<E59A97>瘜閗<E7989C><E99697>?Python 敺格<E695BA><E6A0BC>?
<EFBFBD><EFBFBD>𠶖嚗?
[ERROR] Failed to connect to Python service: ECONNREFUSED
<0A>?[ERROR] connect ETIMEDOUT 172.17.x.x:8000
<EFBFBD>埝䰻甇仿炊嚗?
# 1. 蝖株恕 Python <20>滚𦛚<E6BB9A>臬炏餈鞱<E9A488>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>𡑒” <20>?<3F>亦<EFBFBD> extraction-service <20>嗆<EFBFBD>?
# 2. 蝖株恕<E6A0AA><E68195><EFBFBD><EFBFBD>啣<EFBFBD><E595A3>臬炏甇<E7828F>&
# SAE <20>批<EFBFBD><E689B9>?<3F>?extraction-service 摨𠉛鍂 <20>?摨𠉛鍂霈輸䔮<E8BCB8>滨蔭
# 憭滚<E686AD>"VPC <20><><EFBFBD>霈輸䔮<E8BCB8>啣<EFBFBD>"嚗峕凒<E5B395>啣<EFBFBD>蝡舐㴓憓<E3B493><E68693><EFBFBD>?
# 3. 瘚贝<E7989A><E8B49D><EFBFBD><EFBFBD>餈鮋<E9A488>𡁏<EFBFBD>?# <20>典<EFBFBD>蝡臬<E89DA1><E887AC>函<EFBFBD> Webshell 銝剜<E98A9D>銵䕘<E98AB5>
curl -v http://172.17.x.x:8000/health
# 4. 璉<><E79289>亙<EFBFBD><E4BA99>函<EFBFBD>閫<EFBFBD><E996AB>
# SAE <20>批<EFBFBD><E689B9>?<3F>?extraction-service 摨𠉛鍂 <20>?蝵𤑳<E89DB5><F0A491B3>滨蔭
# 蝖株恕<E6A0AA>亦<EFBFBD>閫<EFBFBD><E996AB><EFBFBD><EFBFBD>捂 VPC <20><>挪<EFBFBD>?8000 蝡臬藁
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# 憒<><E68692><EFBFBD><EFBFBD><EFBFBD><EFBFBD>啣<EFBFBD><E595A3>躰秤嚗峕凒<E5B395>啁㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?backend-service 摨𠉛鍂 <20>?摨𠉛鍂<F0A0899B>滨蔭 <20>?<3F>臬<EFBFBD><E887AC>㗛<EFBFBD>
# 靽格㺿<E6A0BC>𡝗溶<F0A19D97>𩤃<EFBFBD>
EXTRACTION_SERVICE_URL=http://<甇<>&<EFBFBD><EFBC86><EFBFBD>蝵飡P>:8000
# <20>滚鍳摨𠉛鍂雿輻㴓憓<E3B493><E68693><EFBFBD>讐<EFBFBD><E8AE90>?# SAE <20>批<EFBFBD><E689B9>?<3F>?backend-service 摨𠉛鍂 <20>?<3F>滚鍳
<EFBFBD>桅<EFBFBD> 4嚗𡁏<E59A97>瘜閗<E7989C><E99697>?Dify <20>滚𦛚
<EFBFBD><EFBFBD>𠶖嚗?
[ERROR] Dify API error: ECONNREFUSED
<0A>?[ERROR] Dify API error: 502 Bad Gateway
<EFBFBD>埝䰻甇仿炊嚗?
# 1. 蝖株恕 Dify <20>滚𦛚<E6BB9A>臬炏餈鞱<E9A488>
# ECS <20>批<EFBFBD><E689B9>?<3F>?摰硺<E691B0><E7A1BA>𡑒” <20>?<3F>曉<EFBFBD> Dify 摰硺<E691B0> <20>?餈𦦵<E9A488>餈墧𦻖
# <20>?ECS 銝剜<E98A9D>銵䕘<E98AB5>
docker ps | grep dify
# 摨磰砲<E7A3B0>见<EFBFBD> dify-api, dify-worker, dify-web, redis, weaviate 蝑匧捆<E58CA7>刻<EFBFBD>銵䔶葉
# 2. 瘚贝<E7989A> Dify API
curl http://localhost/v1/info
# 3. 隞?SAE 瘚贝<E7989A>餈鮋<E9A488>𡁏<EFBFBD>?# <20>典<EFBFBD>蝡臬<E89DA1><E887AC>函<EFBFBD> Webshell 銝剜<E98A9D>銵䕘<E98AB5>
curl -v http://172.17.x.x:80/v1/info
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# 憒<><E68692> Dify <20>芸鍳<E88AB8>剁<EFBFBD><E58981>?ECS 銝剝<E98A9D><E5899D>荔<EFBFBD>
cd /path/to/dify
docker-compose up -d
# 憒<><E68692> API Key <20>躰秤嚗峕凒<E5B395>啁㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?backend-service 摨𠉛鍂 <20>?<3F>臬<EFBFBD><E887AC>㗛<EFBFBD>
DIFY_API_KEY=app-<甇<>&<EFBFBD><EFBC86>ey>
# 憒<><E68692><EFBFBD><EFBFBD><EFBFBD><EFBFBD>啣<EFBFBD><E595A3>躰秤嚗峕凒<E5B395>啁㴓憓<E3B493><E68693><EFBFBD>𧶏<EFBFBD>
DIFY_API_URL=http://<ECS<43><53><EFBFBD>IP>:80/v1
<EFBFBD>桅<EFBFBD> 5嚗鐾SS 銝𠹺<E98A9D>憭梯揖
<EFBFBD><EFBFBD>𠶖嚗?
[ERROR] OSS upload failed: AccessDenied
<0A>?[ERROR] OSS upload failed: InvalidAccessKeyId
<EFBFBD>埝䰻甇仿炊嚗?
# 1. 璉<><E79289>亦㴓憓<E3B493><E68693><EFBFBD>?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>臬<EFBFBD><E887AC>㗛<EFBFBD>
# 蝖株恕隞乩<E99A9E><E4B9A9>㗛<EFBFBD>甇<EFBFBD>&嚗?OSS_REGION=oss-cn-beijing
OSS_BUCKET=clinical-research-files
OSS_ACCESS_KEY_ID=LTAI5t...
OSS_ACCESS_KEY_SECRET=xxx...
# 2. 瘚贝<E7989A> OSS 霈輸䔮
# <20>典<EFBFBD>蝡臬<E89DA1><E887AC>函<EFBFBD> Webshell 銝剜<E98A9D>銵䕘<E98AB5>
node -e "
const OSS = require('ali-oss');
const client = new OSS({
region: process.env.OSS_REGION,
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
bucket: process.env.OSS_BUCKET
});
client.list().then(result => console.log('<27>?OSS connection successful')).catch(err => console.error('<27>?OSS error:', err.message));
"
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# 憒<><E68692> AccessKey <20>躰秤嚗屸<E59A97><E5B1B8>啁<EFBFBD><E59581>琜<EFBFBD>
# <20>輸<EFBFBD>鈭烐綉<E78390>嗅蝱 <20>?AccessKey 蝞∠<E89D9E> <20>?<3F>𥕦遣 AccessKey
# <20>湔鰵 SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>
# 憒<><E68692> Bucket <20><><EFBFBD><EFBFBD>躰秤嚗?# OSS <20>批<EFBFBD><E689B9>?<3F>?Bucket <20>𡑒” <20>?clinical-research-files <20>?霈輸䔮<E8BCB8>批<EFBFBD>
# 蝖株恕 Bucket 銝?蝘<><E89D98>"嚗䔶<E59A97> RAM <20>冽<EFBFBD><E586BD>㕑粉<E39591>蹱<EFBFBD><E8B9B1>?```
### <20>桅<EFBFBD> 6嚗𡁜<E59A97>摮䀹<E691AE>瞍?
**<2A><>𠶖**嚗?
SAE <20>烐綉<E78390>曄內嚗𡁜<E59A97>摮䀝蝙<E4809D>函<EFBFBD><E587BD><EFBFBD>賒銝𦠜隅嚗峕<E59A97>蝏<EFBFBD>紡<EFBFBD>?OOM嚗㇉ut of Memory嚗?<3F>亙<EFBFBD>嚗麿avaScript heap out of memory
**<2A>埝䰻甇仿炊**嚗?
```bash
# 1. <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>頞见飵
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>烐綉 <20>?<3F>㗇𥋘"<22><>餈?24 撠𤩺𧒄"
# 憒<><E68692><EFBFBD><EFBFBD><EFBFBD><EFBFBD>脩瑪<E884A9><E791AA>賒銝𦠜隅嚗䔶<E59A97>銝钅<E98A9D>嚗諹秩<E8ABB9>擧<EFBFBD><E693A7><EFBFBD><EFBFBD>瘜<EFBFBD><E7989C>
# 2. <20>亦<EFBFBD>摰硺<E691B0><E7A1BA><EFBFBD><EFBFBD>霂行<E99C82>
# <20>?Webshell 銝剜<E98A9D>銵䕘<E98AB5>
node -e "console.log(process.memoryUsage())"
# 颲枏枂蝷箔<E89DB7>嚗?# {
# rss: 123456789, // <20>餃<EFBFBD>摮矋<E691AE>摮𡑒<E691AE>嚗?# heapTotal: 45678910, // V8 <20><><EFBFBD>餃之撠?# heapUsed: 34567890, // V8 <20><>歇雿輻鍂
# external: 1234567, // 憭㚚<E686AD><E39A9A><EFBFBD><EFBFBD>嚗㇂uffer蝑㚁<E89D91>
# arrayBuffers: 123456 // ArrayBuffer
# }
# 3. <20>舐鍂<E88890><E98D82><EFBFBD>敹怎<E695B9>嚗<EFBFBD>𧋦<EFBFBD>啗<EFBFBD>霂𤏪<E99C82>
# <20>冽𧋦<E586BD>啣<EFBFBD><E595A3>𤑳㴓憓<E3B493>溶<EFBFBD>?--inspect <20><>㺭嚗?node --inspect dist/index.js
# 雿輻鍂 Chrome DevTools <20>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>敹怎<E695B9>
**撣貉<E692A3><E8B289><EFBFBD><EFBFBD>瘜<EFBFBD><E7989C><EFBFBD>笔<EFBFBD>**嚗?
- <EFBFBD>典<EFBFBD><EFBFBD>㗛<EFBFBD>蝝舐妖嚗<EFBFBD><EFBFBD>蝻枏<EFBFBD><EFBFBD>𣳇<EFBFBD>憓鮋鵭嚗?2. 鈭衤辣<EFBFBD>穃𨯬<EFBFBD>冽𧊋蝘駁膄
- 摰𡁏𧒄<EFBFBD>冽𧊋皜<EFBFBD><EFBFBD>
- *<EFBFBD>剖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憭批笆鞊?
- *Prisma <20>亥砭蝏𤘪<E89D8F><F0A498AA>芷<EFBFBD><E88AB7>?
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
// <20>躰秤蝷箔<E89DB7>嚗𡁜<E59A97>撅<EFBFBD>蝻枏<E89DBB><E69E8F>𣳇<EFBFBD>憓鮋鵭
const cache = {}; // <20>?瘞訾<E7989E>皜<EFBFBD><E79A9C>
// 甇<>&蝷箔<E89DB7>嚗帋蝙<E5B88B>?LRU 蝻枏<E89DBB>
import LRUCache from 'lru-cache';
const cache = new LRUCache({ max: 1000, ttl: 1000 * 60 * 10 }); // <20>?<3F><>憭?1000 憿對<E686BF>10 <20><><EFBFBD>餈<EFBFBD><E9A488>
// <20>躰秤蝷箔<E89DB7>嚗帋<E59A97>隞嗥<E99A9E><E597A5>砍膥瘜<E886A5><E7989C>
emitter.on('event', handler); // <20>?隞𦒘<E99A9E>蝘駁膄
// 甇<>&蝷箔<E89DB7>嚗𡁜<E59A97><F0A1819C>嗥宏<E597A5>斤<EFBFBD><E696A4>砍膥
emitter.once('event', handler); // <20>?<3F>芸𢆡蝘駁膄
// <20>?emitter.on('event', handler);
// 雿輻鍂<E8BCBB>𠬍<EFBFBD>
emitter.off('event', handler); // <20>?<3F>见𢆡蝘駁膄
// <20>躰秤蝷箔<E89DB7>嚗𡁜<E59A97><F0A1819C>嗅膥瘜<E886A5><E7989C>
setInterval(() => { ... }, 1000); // <20>?瘞訾<E7989E>皜<EFBFBD><E79A9C>
// 甇<>&蝷箔<E89DB7>嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD><EFBFBD>嗅膥
const timer = setInterval(() => { ... }, 1000);
process.on('SIGTERM', () => clearInterval(timer)); // <20>?隡㗛<E99AA1><E3979B>喲𡡒<E596B2>嗆<EFBFBD><E59786>?```
### <EFBFBD>桅<EFBFBD> 7嚗䥪risma Schema 銝擧㺭<EFBFBD>桀<EFBFBD>銝滢<EFBFBD><EFBFBD>?
**<EFBFBD><EFBFBD>𠶖**嚗?
```typescript
// 隞<><E99A9E>銝剛挪<E5899B>桀<EFBFBD>畾蛛<E795BE>
const user = await prisma.user.findUnique({ where: { id: '123' } });
console.log(user.phone); // <20>?TypeScript <20>仿<EFBFBD>嚗䥪roperty 'phone' does not exist
// <20>𤥁<EFBFBD>銵峕𧒄<E5B395>仿<EFBFBD>嚗?PrismaClientKnownRequestError: column "phone" does not exist
**<2A>笔<EFBFBD>**嚗?
- 撘<EFBFBD><EFBFBD>𤏸<EFBFBD>蝔衤葉<EFBFBD>湔𦻖靽格㺿鈭<EFBFBD>㺭<EFBFBD>桀<EFBFBD>嚗<EFBFBD><EFBFBD>鈭?
phone摮埈挾嚗?- 雿<>瓷<EFBFBD>㗇凒<E39787>?schema.prisma - Prisma Client <20>箔<EFBFBD><E7AE94>抒<EFBFBD> Schema <20><><EFBFBD>嚗䔶<E59A97><E494B6>仿<EFBFBD><E4BBBF>啣<EFBFBD>畾? **閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
# 1. <20>冽𧋦<E586BD>啣<EFBFBD><E595A3>𤑳㴓憓<E3B493><E68693>餈墧𦻖<E5A2A7>?RDS
export DATABASE_URL="postgresql://username:password@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical"
# 2. <20>滚<EFBFBD><E6BB9A>峕郊 Schema
npx prisma db pull
# 3. <20>齿鰵<E9BDBF><E9B0B5><EFBFBD> Client
npx prisma generate
# 4. <20>𣂷漱隞<E6BCB1><E99A9E>
git add prisma/schema.prisma
git commit -m "fix: sync Prisma schema with database"
git push
# 5. <20>齿鰵<E9BDBF><E9B0B5>遣<EFBFBD>𨅯<EFBFBD>撟園<E6929F>蝵?cp -r prisma backend/prisma
cd backend
docker build -t backend-service:v1.0.1 .
docker push registry.cn-hangzhou.aliyuncs.com/clinical-research/backend-service:v1.0.1
# 6. <20>?SAE 銝剜凒<E5899C>圈<EFBFBD><E59C88>讐<EFBFBD><E8AE90>?# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂霂行<E99C82> <20>?<3F>函蔡 <20>?<3F>㗇𥋘<E39787>啁<EFBFBD><E59581>?v1.0.1
13. 瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹?
<EFBFBD>?<3F><>雿喳<E99BBF>頝?
1. <EFBFBD>臬<EFBFBD><EFBFBD>㗛<EFBFBD>蝞∠<EFBFBD>
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>
# SAE <20>批<EFBFBD><E689B9>?<3F>?摨𠉛鍂<F0A0899B>滨蔭 <20>?<3F>臬<EFBFBD><E887AC>㗛<EFBFBD>
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁜銁隞<E98A81><E99A9E><EFBFBD>?Dockerfile 銝剔′蝻𣇉<E89DBB>
# Dockerfile
ENV DATABASE_URL="postgresql://user:pass@host/db" # <20>?瘜<>蠧<EFBFBD>𤩺<EFBFBD>靽⊥<E99DBD>
2. *餈墧𦻖瘙𣳇<EFBFBD>蝵?
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗𡁏覔<F0A1818F>?RDS <20>?SAE <20>滨蔭<E6BBA8>冽<EFBFBD><E586BD>恣蝞?DATABASE_URL=postgresql://...?connection_limit=18&pool_timeout=10
# 霈∠<E99C88><E288A0>砍<EFBFBD>嚗?# connection_limit = (RDS_MAX_CONNECTIONS / MAX_INSTANCES) - 憸<><E686B8>
# 蝷箔<E89DB7>嚗?400 / 20) - 2 = 18
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗帋蝙<E5B88B>券<EFBFBD>霈文<E99C88>?DATABASE_URL=postgresql://... # <20>?暺䁅恕<E48185>𣳇<EFBFBD><F0A3B387>塚<EFBFBD>撖潸稲餈墧𦻖<E5A2A7>堒偷
3. <EFBFBD><EFBFBD>辣摮睃<EFBFBD>
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?OSS 摮睃<E691AE>
import { StorageFactory } from './common/storage';
const storage = StorageFactory.create(); // <20>寞旿 STORAGE_TYPE <20>芸𢆡<E88AB8>㗇𥋘
await storage.upload('uploads/file.pdf', buffer);
// <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C>典<EFBFBD>摰孵膥<E5ADB5><E886A5>辣蝟餌<E89D9F>
import fs from 'fs';
fs.writeFileSync('/app/uploads/file.pdf', buffer); // <20>?摰孵膥<E5ADB5>滚鍳<E6BB9A>𦒘腺憭?```
#### 4. **<EFBFBD>亙<EFBFBD>颲枏枂**
```typescript
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?stdout嚗𠄎AE <20>芸𢆡<E88AB8>園<EFBFBD>嚗?console.log('[INFO] User logged in:', userId);
logger.info('User logged in', { userId });
// <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C>交<EFBFBD>隞?import fs from 'fs';
fs.appendFileSync('/var/log/app.log', message); // <20>?摰孵膥<E5ADB5>滚鍳<E6BB9A>𦒘腺憭?```
#### 5. **隡㗛<EFBFBD><EFBFBD>喲𡡒**
```typescript
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗𡁶<E59A97><F0A181B6>?SIGTERM 靽∪噡
process.on('SIGTERM', async () => {
console.log('[Server] Received SIGTERM, shutting down gracefully...');
await fastify.close(); // <20>喲𡡒 HTTP <20>滚𦛚<E6BB9A>? await prisma.$disconnect(); // <20>喲𡡒<E596B2>唳旿摨栞<E691A8><E6A09E>? process.exit(0);
});
// <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗𡁶凒<F0A181B6>仿<EFBFBD><E4BBBF><EFBFBD>?process.on('SIGTERM', () => process.exit(0)); // <20>?餈墧𦻖<E5A2A7>芷<EFBFBD><E88AB7>?```
### <EFBFBD>?蝏嘥笆蝳<EFBFBD>迫
#### 1. **蝳<EFBFBD>迫<EFBFBD>湔𦻖靽格㺿<EFBFBD>唳旿摨栞<EFBFBD>䔶<EFBFBD><EFBFBD>峕郊 Prisma Schema嚗<EFBFBD>稲<EFBFBD>踝<EFBFBD>**
```bash
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗?# 1. <20>?Navicat 銝剔凒<E58994>交溶<E4BAA4>惩<EFBFBD>畾?ALTER TABLE "User" ADD COLUMN phone VARCHAR(50);
# 2. <20>嗅<EFBFBD><E59785>湔𦻖<E6B994>其誨<E585B6><E8AAA8>葉雿輻鍂
const user = await prisma.user.create({
data: {
email: 'test@example.com',
phone: '13800138000' // <20>?TypeScript <20>仿<EFBFBD>嚗䮝hone 銝滚<E98A9D><E6BB9A>? }
});
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗?# 1. <20><>耨<EFBFBD>?schema.prisma
model User {
email String
phone String? @db.VarChar(50) // 瘛餃<E7989B>摮埈挾摰帋<E691B0>
}
# 2. <20><><EFBFBD>餈<EFBFBD>宏嚗<E5AE8F><E59A97>撘<EFBFBD><E69298>𤑳㴓憓<E3B493><E68693>
npx prisma migrate dev --name add_user_phone
# 3. <20><><EFBFBD>摰X<E691B0>蝡?npx prisma generate
# 4. <20>其誨<E585B6><E8AAA8>葉雿輻鍂
const user = await prisma.user.create({
data: {
email: 'test@example.com',
phone: '13800138000' // <20>?TypeScript 霂<><E99C82>
}
});
# <20>𤥁<EFBFBD><F0A4A581><EFBFBD>憒<EFBFBD><E68692><EFBFBD>唳旿摨枏歇<E69E8F>见𢆡靽格㺿嚗?# 1. <20>滚<EFBFBD><E6BB9A>峕郊
npx prisma db pull
# 2. <20><><EFBFBD>摰X<E691B0>蝡?npx prisma generate
**<2A>笔<EFBFBD>**嚗?- Prisma Client <20>箔<EFBFBD> Schema <20><><EFBFBD>
- Schema 銝擧㺭<E693A7>桀<EFBFBD>銝滢<E98A9D><E6BBA2>港<EFBFBD>撖潸稲餈鞱<E9A488><E99EB1>園<EFBFBD>霂舀<E99C82>蝐餃<E89D90>銝滚龪<E6BB9A>?- 餈蹱糓撖潸稲<E6BDB8>煺漣<E785BA>臬<EFBFBD>撏拇<E6928F><E68B87><EFBFBD><EFBFBD>撣貉<E692A3><E8B289>笔<EFBFBD>銋衤<E98A8B>
2. 蝳<EFBFBD>迫<EFBFBD>典鍳<EFBFBD>典𦶢隞支葉<EFBFBD>㰘<EFBFBD><EFBFBD>扯<EFBFBD> prisma migrate deploy
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>𨀣㺭<F0A880A3>桀<EFBFBD><E6A180>舫<EFBFBD>朞<EFBFBD> pg_dump 撖澆<E69296><E6BE86><EFBFBD><EFBFBD>嚗?CMD ["sh", "-c", "npx prisma migrate deploy && node dist/index.js"]
# <20>躰秤<E8BAB0>笔<EFBFBD>嚗?# - 銵函<E98AB5><E587BD><EFBFBD>歇摮睃銁嚗<E98A81><E59A97>朞<EFBFBD> pg_dump 撖澆<E69296>嚗?# - migrate deploy 隡𡁜<E99AA1>霂閖<E99C82><E99696>啣<EFBFBD>撱箄”
# - 撖潸稲<E6BDB8>躰秤嚗関able already exists
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗<EFBFBD><E59A97>撖寞<E69296><E5AF9E><EFBFBD><EFBFBD><EFBFBD>蛛<EFBFBD>嚗?CMD ["node", "dist/index.js"]
# 閫<><E996AB>嚗?# - <20>唳旿摨梶<E691A8><E6A2B6><EFBFBD>歇<EFBFBD>朞<EFBFBD> pg_dump 撖澆<E69296>
# - Schema 撌脤<E6928C>朞<EFBFBD> prisma db pull <20>峕郊
# - <20>𣳇<EFBFBD><F0A3B387>典鍳<E585B8>冽𧒄<E586BD>扯<EFBFBD>餈<EFBFBD>宏
3. 蝳<EFBFBD>迫敹賜裦 Prisma <20>滚<EFBFBD><E6BB9A>峕郊甇仿炊
# <20>?<3F>躰秤瘚<E7A7A4><E7989A>嚗?pg_dump <20>?撖澆<E69296> RDS <20>?<3F>湔𦻖<E6B994><F0A6BB96>遣<EFBFBD>𨅯<EFBFBD> <20>?<3F>函蔡
# <20>?<3F>桅<EFBFBD>嚗锭chema 銝擧㺭<E693A7>桀<EFBFBD>銝滢<E98A9D><E6BBA2>?
# <20>?甇<>&瘚<EFBC86><E7989A>嚗?pg_dump <20>?撖澆<E69296> RDS <20>?prisma db pull嚗<6C><E59A97>甇伐<E79487><E4BC90>?<3F><>遣<EFBFBD>𨅯<EFBFBD> <20>?<3F>函蔡
# <20>?<3F>喲睸嚗䮝risma db pull 蝖桐<E89D96>銝<EFBFBD><E98A9D>湔<EFBFBD>?```
#### 4. **蝳<>迫<EFBFBD>其誨<E585B6><E8AAA8>葉蝖祉<E89D96><E7A589><EFBFBD><EFBFBD><EFBFBD>煺縑<E785BA>?*
```typescript
// <20>?<3F>躰秤蝷箔<E89DB7>
const dbUrl = 'postgresql://admin:P@ssw0rd@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical';
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>
const dbUrl = process.env.DATABASE_URL;
5. 蝳<EFBFBD>迫<EFBFBD>?backend/ <20>桀<EFBFBD><E6A180><EFBFBD>遣<EFBFBD>滢<EFBFBD>憭滚<E686AD> Prisma <20><>辣
# <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗?cd backend
docker build -t backend-service:v1.0.0 .
# <20>?<3F>躰秤嚗鋴OPY prisma ./prisma 隡𡁜仃韐伐<E99F90><E4BC90>曆<EFBFBD><E69B86>唳<EFBFBD>隞塚<E99A9E>
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗?cd AIclinicalresearch # 憿寧𤌍<E5AFA7>寧𤌍敶?cp -r prisma backend/prisma # <20><><EFBFBD><EFBFBD>?cd backend
docker build -t backend-service:v1.0.0 . # <20>齿<EFBFBD>撱?```
#### 6. **蝳<>迫雿輻鍂<E8BCBB><E98D82><EFBFBD>雿靝蛹蝻枏<E89DBB>嚗<EFBFBD><E59A97>摰硺<E691B0><E7A1BA>臬<EFBFBD>嚗?*
```typescript
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁜<E59A97>摮条<E691AE>摮䀝<E691AE><E4809D>曹澈
const cache = new Map(); // 摰硺<E691B0> 1 <20><><EFBFBD>摮矋<E691AE>摰硺<E691B0> 2 <20>衤<EFBFBD><E8A1A4>?
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?PostgreSQL 蝻枏<E89DBB>嚗㇊ostgres-Only嚗?import { CacheFactory } from './common/cache';
const cache = CacheFactory.create(); // <20>寞旿 CACHE_TYPE <20>㗇𥋘
7. 蝳<EFBFBD>迫雿輻鍂<EFBFBD>砍𧑐<EFBFBD><EFBFBD>辣雿靝蛹<EFBFBD>笔<EFBFBD>
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁏<E59A97>隞園<E99A9E><E59C92>𦯀<EFBFBD><F0A6AF80>曹澈
import fs from 'fs';
fs.writeFileSync('/tmp/queue.json', JSON.stringify(tasks)); // 摰硺<E691B0><E7A1BA>港<EFBFBD><E6B8AF>峕郊
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>?pg-boss嚗㇊ostgres-Only嚗?import { jobQueue } from './common/jobs';
await jobQueue.send('pdf-extraction', { fileId: '123' });
8. 蝳<EFBFBD>迫雿輻鍂<EFBFBD>峕郊<EFBFBD>餃<EFBFBD><EFBFBD>滢<EFBFBD>
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁻獈憛硺<E6869B>隞嗅儐<E59785>?import fs from 'fs';
const data = fs.readFileSync('/large-file.pdf'); // <20>餃<EFBFBD><E9A483>嗡<EFBFBD>霂瑟<E99C82>
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗帋蝙<E5B88B>典<EFBFBD>甇?API
const data = await fs.promises.readFile('/large-file.pdf');
9. *蝳<EFBFBD>迫頝唾<EFBFBD><EFBFBD>亙熒璉<EFBFBD><EFBFBD>?
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁜<E59A97>摨瑟<E691A8><E7919F>交<EFBFBD>餅糓餈𥪜<E9A488> 200
app.get('/health', async (req, reply) => {
return { status: 'ok' }; // <20>喃蝙<E59683>唳旿摨𤘪鱏撘<E9B18F>銋蠘<E98A8B><E8A098>?ok
});
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗𡁶<E59A97>甇<EFBFBD><E79487><EFBFBD>乩<EFBFBD>韏𡝗<E99F8F><F0A19D97>?app.get('/health', async (req, reply) => {
const dbHealthy = await testDatabaseConnection();
if (!dbHealthy) {
reply.code(503);
return { status: 'unhealthy', database: 'disconnected' };
}
return { status: 'healthy' };
});
10. 蝳<EFBFBD>迫敹賜裦<EFBFBD>躰秤憭<EFBFBD><EFBFBD>
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁜<E59A97><F0A1819C>厰<EFBFBD>霂?try {
await riskyOperation();
} catch (error) {
// 隞<>銋<EFBFBD><E98A8B>銝滚<E98A9D>
}
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗朞扇敶閖<E695B6>霂臬僎餈𥪜<E9A488><F0A5AA9C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摨?try {
await riskyOperation();
} catch (error) {
logger.error('Risky operation failed', { error, stack: error.stack });
reply.code(500).send({ error: 'Internal server error' });
}
11. 蝳<EFBFBD>迫<EFBFBD>函<EFBFBD>鈭抒㴓憓<EFBFBD>蝙<EFBFBD>?development 璅∪<E79285>
# <20>?<3F>躰秤<E8BAB0>滨蔭
NODE_ENV=development # 隡𡁏<E99AA1><F0A1818F>啣之<E595A3>讛<EFBFBD>霂閙𠯫敹梹<E695B9><E6A2B9>湧蠧<E6B9A7>𤩺<EFBFBD>靽⊥<E99DBD>
# <20>?甇<>&<EFBFBD>滨蔭
NODE_ENV=production
LOG_LEVEL=info
12. 蝳<EFBFBD>迫雿輻鍂撘?JWT 撖<>𤨎
# <20>?<3F>躰秤<E8BAB0>滨蔭
JWT_SECRET=secret # 憭芸摹嚗<E691B9>捆<EFBFBD>栞◤<E6A09E>渲圾
# <20>?甇<>&<EFBFBD>滨蔭嚗<E894AD>秐撠?32 雿漤<E99BBF><E6BCA4>箏<EFBFBD>蝚虫葡嚗?JWT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 # 雿輻鍂 openssl rand -base64 32 <20><><EFBFBD>
13. *蝳<EFBFBD>迫<EFBFBD>湔𦻖<EFBFBD>湧蠧 Prisma <20>躰秤<E8BAB0>啣<EFBFBD>蝡?
// <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁏<E59A97><F0A1818F>脫㺭<E884AB>桀<EFBFBD>蝏𤘪<E89D8F>
try {
await prisma.user.create({ data: { email: 'test@example.com' } });
} catch (error) {
reply.code(500).send({ error: error.message }); // <20>航<EFBFBD><E888AA>湧蠧銵典<E98AB5><E585B8><EFBFBD><EFBFBD>畾萄<E795BE>
}
// <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗朞<E59A97><E69C9E>鮋<EFBFBD>𡁶鍂<F0A181B6>躰秤
try {
await prisma.user.create({ data: { email: 'test@example.com' } });
} catch (error) {
logger.error('Failed to create user', { error });
reply.code(500).send({ error: 'Failed to create user' });
}
14. 蝳<EFBFBD>迫敹賜裦 Docker <20>𨅯<EFBFBD>隡睃<E99AA1>
# <20>?<3F>躰秤蝷箔<E89DB7>嚗𡁜<E59A97><F0A1819C>嗆挾<E59786><E68CBE>遣嚗屸<E59A97><E5B1B8>讛<EFBFBD><E8AE9B>?FROM node:22
COPY . .
RUN npm install # <20><>鉄 devDependencies
CMD ["node", "dist/index.js"]
# <20>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗𡁜<E59A97><F0A1819C>嗆挾<E59786><E68CBE>遣嚗<E981A3><E59A97>撠誯<E692A0><E8AAAF>譍<EFBFBD>蝘?FROM node:22-alpine AS builder
# ... <20><>遣<EFBFBD>嗆挾 ...
FROM node:22-alpine
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules # 隞<><E99A9E>鈭找<E988AD>韏?```
---
## <20><> <20>詨<EFBFBD><E8A9A8><EFBFBD>﹝
- [03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md](./03-Dify-ECS<43>函蔡摰<E894A1><E691B0><EFBFBD><EFBFBD><EFBFBD>.md)
- [04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md](./04-Python敺格<E695BA><E6A0BC>?SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md)
- [06-<2D>滨垢Nginx-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md](./06-<2D>滨垢Nginx-SAE摰孵膥<E5ADB5>函蔡<E587BD><E894A1><EFBFBD>.md)嚗<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
---
## <20><> <20>瑕<EFBFBD>撣桀𨭌
**<2A><><EFBFBD><EFBFBD>桅<EFBFBD>嚗?*
1. <20>亦<EFBFBD><E4BAA6>祆<EFBFBD>獢<EFBFBD><E78DA2>"<22><><EFBFBD><EFBFBD>埝䰻"蝡㰘<EFBFBD>
2. <20>亦<EFBFBD> SAE <20>批<EFBFBD><E689B9>啁<EFBFBD>摰墧𧒄<E5A2A7>亙<EFBFBD>
3. <20>亦<EFBFBD> RDS <20>批<EFBFBD><E689B9>啁<EFBFBD><E59581>扯<EFBFBD><E689AF>烐綉
4. <20>𠉛頂<F0A0899B>a<EFBFBD><EFBD81><EFBFBD><EFBFBD>舀𣈲<E88880>?
---
**<2A>函蔡<E587BD>匧翰嚗<E7BFB0><E59A97><EFBFBD>**