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%)
1838 lines
55 KiB
Markdown
1838 lines
55 KiB
Markdown
# 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
|
||
**<EFBFBD><EFBFBD><EFBFBD>𦒘耨霈?*: 2025-12-13
|
||
**<EFBFBD><EFBFBD>鍂<EFBFBD><EFBFBD>凒**: AIclinicalresearch 撟喳蝱 - Node.js <20>𡒊垢<F0A1928A>滚𦛚
|
||
**<EFBFBD>格<EFBFBD>霂餉<EFBFBD>?*: 餈鞟輕撌亦<E6928C>撣<EFBFBD><E692A3><EFBFBD><EFBFBD>蝡臬<E89DA1><E887AC>穃極蝔见<E89D94>
|
||
**<EFBFBD>函蔡<EFBFBD>格<EFBFBD>**: <20>輸<EFBFBD>鈭?SAE嚗𠄎erverless 摨𠉛鍂撘閙<E69298>嚗匧捆<E58CA7>券<EFBFBD>蝵?
|
||
**v1.1 <20>湔鰵<E6B994>亙<EFBFBD>**:
|
||
- <20><> 靽桀<E99DBD>嚗䥪risma <20>桀<EFBFBD><E6A180><EFBFBD>遣銝𠹺<E98A9D><F0A0B9BA><EFBFBD>䔮憸矋<E686B8>憓𧼮<E68693>憸<EFBFBD><E686B8><EFBFBD><EFBFBD>郊撉歹<E69289>
|
||
- <20><> 靽桀<E99DBD>嚗𡁶<E59A97>鈭抒㴓憓<E3B493>撩撠?Prisma CLI 撖潸稲餈<E7A8B2>宏憭梯揖
|
||
- <20>𤣳 <20>啣<EFBFBD>嚗𡁻<E59A97>撖孵<E69296><E5ADB5>穃<EFBFBD><E7A983>脖<EFBFBD>閫<EFBFBD><E996AB><EFBFBD>?<3F>滚<EFBFBD><E6BB9A>峕郊"瘚<><E7989A>嚗<EFBFBD><E59A97><EFBFBD>殷<EFBFBD>
|
||
- <20>?隡睃<E99AA1>嚗𡁏㺭<F0A1818F>桀<EFBFBD>餈<EFBFBD>宏蝑𣇉裦嚗īg_dump 撖澆<E69296><E6BE86>𦒘<EFBFBD><F0A69298>扯<EFBFBD> migrate嚗?- <20>?蝞<><E89D9E>吔<EFBFBD>蝘駁膄 Init Container <20>寞<EFBFBD>嚗峕㺿<E5B395>典鍳<E585B8>典𦶢隞?
|
||
---
|
||
|
||
## <20><> <20>桀<EFBFBD>
|
||
|
||
1. [銝箔<EFBFBD>銋<EFBFBD><EFBFBD>㗇𥋘 SAE 摰孵膥<E5ADB5>函蔡](#1-銝箔<E98A9D>銋<EFBFBD><E98A8B>㗇𥋘-sae-摰孵膥<E5ADB5>函蔡)
|
||
2. [<5B>函蔡<E587BD>滚<EFBFBD>憭䚡(#2-<2D>函蔡<E587BD>滚<EFBFBD>憭?
|
||
3. [<EFBFBD>𡒊垢<EFBFBD>滚𦛚<EFBFBD><EFBFBD><EFBFBD>](#3-<2D>𡒊垢<F0A1928A>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>)
|
||
4. [<EFBFBD>𤣳 Prisma <20>滚<EFBFBD><E6BB9A>峕郊嚗<E9838A><E59A97>霂鳴<E99C82>](#4-prisma-<2D>滚<EFBFBD><E6BB9A>峕郊敹<E9838A>粉)
|
||
5. [<EFBFBD><EFBFBD>遣 Docker <20>𨅯<EFBFBD>](#5-<2D><>遣-docker-<2D>𨅯<EFBFBD>)
|
||
6. [<EFBFBD>砍𧑐瘚贝<EFBFBD>撉諹<EFBFBD>](#6-<2D>砍𧑐瘚贝<E7989A>撉諹<E69289>)
|
||
7. [<EFBFBD>券<EFBFBD><EFBFBD><EFBFBD> ACR](#7-<2D>券<EFBFBD><E588B8><EFBFBD>-acr)
|
||
8. [SAE 摨𠉛鍂<F0A0899B>滨蔭](#8-sae-摨𠉛鍂<F0A0899B>滨蔭)
|
||
9. [<5B>唳旿摨㯄<E691A8>蝵脩<E89DB5><E884A9>包(#9-<2D>唳旿摨㯄<E691A8>蝵脩<E89DB5><E884A9>?
|
||
10. [蝡臬<E89DA1>蝡舀<E89DA1>霂騟(#10-蝡臬<E89DA1>蝡舀<E89DA1>霂?
|
||
11. [<5B>烐綉銝𡒊輕<F0A1928A>也(#11-<2D>烐綉銝𡒊輕<F0A1928A>?
|
||
12. [<EFBFBD><EFBFBD><EFBFBD><EFBFBD>埝䰻](#12-<2D><><EFBFBD><EFBFBD>埝䰻)
|
||
13. [瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹䀉(#13-瘜冽<E7989C>鈭钅★銝𡒊<E98A9D>敹?
|
||
|
||
---
|
||
|
||
## 1. 銝箔<E98A9D>銋<EFBFBD><E98A8B>㗇𥋘 SAE 摰孵膥<E5ADB5>函蔡
|
||
|
||
### <20>?<3F>詨<EFBFBD>隡睃飵
|
||
|
||
| 隡睃飵 | 霂湔<E99C82> | 撖寞<E69296><E5AF9E><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>?| <20>𦦵<EFBFBD>"<22>烐𧋦<E78390>唳<EFBFBD><E594B3>舘<EFBFBD>頝?<3F><>䔮憸?|
|
||
| **撘寞<E69298>找撓蝻?* | SAE <20>寞旿 CPU/<2F><><EFBFBD>雿輻鍂<E8BCBB><E98D82>䌊<EFBFBD>典<EFBFBD><E585B8>誩<EFBFBD>靘𧢲㺭<F0A7A2B2>?| 憭折<E686AD><E68A98>冽<EFBFBD> AI 撖寡<E69296><E5AFA1>嗉䌊<E59789>冽<EFBFBD>摰?|
|
||
| **<EFBFBD>滩<EFBFBD>蝏?* | <20>𣳇<EFBFBD>蝞∠<E89D9E><E288A0>滚𦛚<E6BB9A>?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>帋縑 | 瘥怎<E798A5>蝥批辣餈<E8BEA3><E9A488><EFBFBD>惩<EFBFBD>蝵烐<E89DB5><E78390>讛晶 |
|
||
| **蝘<><E89D98><EFBFBD>硋停蝏?* | Docker <20>𨅯<EFBFBD><F0A885AF>舐凒<E88890>乩漱隞条<E99A9E><E69DA1>駁堺嚗屸<E59A97>蝵脣<E89DB5><E884A3><EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD> | 皛∟雲<E2889F>餌<EFBFBD><E9A48C>唳旿<E594B3><E697BF><EFBFBD>閬<EFBFBD><E996AC> |
|
||
| **蝏煺<E89D8F><E785BA>嗆<EFBFBD>** | <20>滨垢嚗𠃊ginx嚗剹<E59A97><E589B9><EFBFBD>蝡荔<E89DA1>Node.js嚗剹<E59A97><E589B9>ython 敺格<E695BA><E6A0BC>⊿<EFBFBD><E28ABF>?Docker | 銝<>憟烾<E6869F>蝵脫<E89DB5>蝔页<E89D94><E9A1B5>滢<EFBFBD>摮虫<E691AE><E899AB>鞉𧋦 |
|
||
|
||
### <20>㴓 銝箔<E98A9D>銋<EFBFBD><E98A8B><EFBFBD>?Code Package <20>函蔡嚗?
|
||
| 撖寞<E69296>憿?| Code Package | 摰孵膥<E5ADB5>函蔡嚗<E894A1>綫<EFBFBD>琜<EFBFBD>|
|
||
|-------|--------------|----------------|
|
||
| <20>臬<EFBFBD>銝<EFBFBD><E98A9D>湔<EFBFBD>?| <20>𩤃<EFBFBD> 鈭𤑳垢 Node <20><>𧋦<EFBFBD>航<EFBFBD>銝滚<E98A9D> | <20>?<3F>𨅯<EFBFBD><F0A885AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦 |
|
||
| 蝘<><E89D98><EFBFBD>碶漱隞?| <20>?<3F>䭾<EFBFBD><E4ADBE>湔𦻖鈭支<E988AD> | <20>?<3F>枏<EFBFBD><E69E8F>喳虾鈭支<E988AD> |
|
||
| 蝟餌<E89D9F>靘肽<E99D98> | <20>𩤃<EFBFBD> <20>䭾<EFBFBD><E4ADBE>芸<EFBFBD>銋?| <20>?Dockerfile 摰<><E691B0><EFBFBD>批<EFBFBD> |
|
||
| <20><>遣<EFBFBD>笔漲 | <20>?敹恬<E695B9>銝𠹺<E98A9D><F0A0B9BA>喳虾嚗?| <20>𩤃<EFBFBD> <20>g<EFBFBD><EFBD87><EFBFBD><EFBFBD><EFBFBD>遣<EFBFBD>𨅯<EFBFBD>嚗车
|
||
| <20><>鍂<EFBFBD>箸艶 | 敹恍<E695B9>笔<EFBFBD><E7AC94>钅<EFBFBD>霂?| <20>煺漣<E785BA>臬<EFBFBD><E887AC><EFBFBD><EFBFBD><EFBFBD>匧<EFBFBD> |
|
||
|
||
**蝏栞捏**嚗𡁜笆鈭𡡞<E988AD>閬<EFBFBD><E996AC><EFBFBD>匧<EFBFBD><E58CA7>函蔡<E587BD><E894A1>龫<EFBFBD>㛖<EFBFBD><E39B96>𥪯漣<F0A5AAAF><E6BCA3><EFBFBD>摰孵膥<E5ADB5>函蔡<E587BD>臬𣈲銝<F0A388B2><E98A9D>㗇𥋘<E39787>?
|
||
---
|
||
|
||
## 2. <20>函蔡<E587BD>滚<EFBFBD>憭?
|
||
### <20>?<3F>滨蔭<E6BBA8>∩辣璉<E8BEA3><E79289>交<EFBFBD><E4BAA4>?
|
||
#### <20>砍𧑐撘<F0A79190><E69298>𤑳㴓憓?
|
||
- [ ] 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>砍𧑐
|
||
- [ ] <20>𡒊垢<F0A1928A>冽𧋦<E586BD>啗<EFBFBD>甇<EFBFBD>虜<EFBFBD>臬𢆡嚗Ǒnpm run dev`嚗?
|
||
撉諹<EFBFBD><EFBFBD>賭誘嚗?
|
||
```bash
|
||
# 璉<><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
|
||
```
|
||
|
||
#### <20>輸<EFBFBD>鈭𤏸<E988AD>皞?
|
||
- [ ] **RDS PostgreSQL 15** 摰硺<E691B0>撌脣<E6928C>撱箏僎餈鞱<E9A488>
|
||
- <20>唳旿摨枏<E691A8>蝘堆<E89D98>`ai_clinical`嚗<EFBFBD><EFBFBD><EFBFBD>芸<EFBFBD>銋㚁<EFBFBD>
|
||
- <20>冽<EFBFBD><E586BD>滚<EFBFBD>撖<EFBFBD><E69296>撌脣<E6928C>憭? - <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>?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`
|
||
|
||
#### <20>𤩺<EFBFBD>靽⊥<E99DBD><E28AA5><EFBFBD><EFBFBD>
|
||
|
||
<EFBFBD><EFBFBD><EFBFBD>隞乩<EFBFBD><EFBFBD>滨蔭靽⊥<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>𡡞<EFBFBD>蝵桀<EFBFBD> SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>嚗㚁<E59A97>
|
||
|
||
```bash
|
||
# <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>
|
||
|
||
### <20>𣑐 <20><><EFBFBD>舀<EFBFBD>
|
||
|
||
| <20><><EFBFBD>?| <20><>𧋦 | <20>券<EFBFBD>?|
|
||
|------|------|------|
|
||
| **Node.js** | 22+ | 餈鞱<E9A488><E99EB1>嗥㴓憓?|
|
||
| **Fastify** | 5.6+ | Web 獢<>沲嚗<E6B2B2><E59A97><EFBFBD>扯<EFBFBD>嚗?|
|
||
| **TypeScript** | 5.9+ | 蝐餃<E89D90>摰匧<E691B0> |
|
||
| **Prisma** | 6.17+ | ORM嚗<4D>㺭<EFBFBD>桀<EFBFBD>霈輸䔮嚗?|
|
||
| **pg-boss** | 12.5+ | <20>笔<EFBFBD>嚗㇊ostgres-Only嚗?|
|
||
| **winston** | 3.18+ | <20>亙<EFBFBD>蝟餌<E89D9F> |
|
||
|
||
### <20><> 靘肽<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
|
||
```
|
||
|
||
### <20>圲 <20>詨<EFBFBD><E8A9A8>蠘<EFBFBD>璅∪<E79285>
|
||
|
||
| 璅∪<E79285> | 頝臬<E9A09D> | <20>蠘<EFBFBD> | 靘肽<E99D98><E882BD>滚𦛚 |
|
||
|------|------|------|---------|
|
||
| **AIA** | `/api/chat` | AI <20>箄<EFBFBD><E7AE84>拍<EFBFBD> | DeepSeek/<2F><>䔮/Claude |
|
||
| **PKB** | `/api/knowledge-bases` | 銝芯犖<E88AAF>亥<EFBFBD>摨?| Dify + OSS |
|
||
| **ASL** | `/api/asl/*` | <20>箄<EFBFBD><E7AE84><EFBFBD>讃 | Python 敺格<E695BA><E6A0BC>?+ OSS |
|
||
| **DC** | `/api/dc/*` | <20>唳旿皜<E697BF><E79A9C> | Python 敺格<E695BA><E6A0BC>?+ OSS |
|
||
| **RVW** | `/api/review` | 蝔蹂辣摰⊥䰻 | DeepSeek/<2F><>䔮 |
|
||
| **Health** | `/health` | <20>亙熒璉<E78692><E79289>?| RDS |
|
||
|
||
### <20><> <20>臬𢆡瘚<F0A286A1><E7989A>
|
||
|
||
```bash
|
||
# 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>
|
||
|
||
### <20>𩤃<EFBFBD> <20>滩<EFBFBD>霅血<E99C85>嚗帋蛹隞<E89BB9>銋<EFBFBD><E98A8B>閬<EFBFBD><E996AC>銝<EFBFBD>甇伐<E79487>
|
||
|
||
**<EFBFBD>函<EFBFBD>撘<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>?*嚗?- <20>?雿輻鍂 `pg_dump` 撖澆枂鈭<E69E82>𧋦<EFBFBD>?PostgreSQL <20>唳旿摨橒<E691A8><E6A992><EFBFBD>鉄銵函<E98AB5><E587BD><EFBFBD><EFBFBD><EFBFBD>唳旿嚗?- <20>?撌脩<E6928C>撖澆<E69296><E6BE86>圈燵<E59C88>䔶<EFBFBD> RDS PostgreSQL
|
||
- <20>𩤃<EFBFBD> **雿<>糓**嚗𡁜<E59A97><F0A1819C>𤏸<EFBFBD>蝔衤葉嚗𣬚<E59A97>撣貊凒<E8B28A>亦鍂 SQL <20>?Navicat 靽格㺿<E6A0BC>唳旿摨橒<E691A8>**瘝⊥<E7989D><E28AA5>峕郊<E5B395>湔鰵 `schema.prisma` <20><>辣**
|
||
|
||
**<EFBFBD>擧<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>唳旿摨?
|
||
<EFBFBD>冽𧋦<EFBFBD>啣<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>銝湔𧒄餈墧𦻖<EFBFBD>?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>喲睸甇仿炊嚗?
|
||
```bash
|
||
# 霈?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.
|
||
```
|
||
|
||
**餈嗘葵<E59798>賭誘<E8B3AD><E8AA98><EFBFBD><EFBFBD>?*嚗?- 摰<><E691B0><EFBFBD>急<EFBFBD><E680A5>唳旿摨梶<E691A8>**<2A><><EFBFBD>㕑”<E39591><E2809D><EFBFBD>畾萸<E795BE><E890B8>掩<EFBFBD>卝<EFBFBD><E58D9D><EFBFBD>蝟?*
|
||
- <20>嗅<EFBFBD>**摰<><E691B0><EFBFBD>滚<EFBFBD>** `prisma/schema.prisma` <20><>辣
|
||
- 靽肽<E99DBD> Schema 銝擧㺭<E693A7>桀<EFBFBD> 100% 銝<><E98A9D>?
|
||
#### 甇仿炊 3嚗𡁏䰻<F0A1818F>见僎蝖株恕<E6A0AA>䀹凒
|
||
|
||
```bash
|
||
# <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>?*嚗?
|
||
1. **璉<><E79289>交鰵憓𧼮<E68693>畾?*嚗? - <20>臬炏<E887AC>㗇<EFBFBD>憭𣇉<E686AD>摮埈挾嚗<E68CBE><E59A97>瘚贝<E7989A>摮埈挾嚗㚁<E59A97>
|
||
- 摮埈挾蝐餃<E89D90><E9A483>臬炏甇<E7828F>&嚗?
|
||
2. **璉<><E79289>亙<EFBFBD><E4BA99>文<EFBFBD>畾?*嚗? - 憒<><E68692> Schema <20>𣬚<EFBFBD>摮埈挾<E59F88>冽㺭<E586BD>桀<EFBFBD>銝凋<E98A9D>摮睃銁嚗䈣db pull` 隡𡁜<E99AA1><F0A1819C>文<EFBFBD>
|
||
- 蝖株恕餈嗘<E9A488>摮埈挾<E59F88>臬炏<E887AC>毺<EFBFBD>摨磰砲<E7A3B0>𣳇膄
|
||
|
||
3. **璉<><E79289>亙<EFBFBD>蝟鳴<E89D9F>Relations嚗?*嚗? - 憭㚚睸<E39A9A>喟頂<E5969F>臬炏甇<E7828F>&霂<EFBC86><E99C82>嚗? - `@relation` 瘜刻圾<E588BB>臬炏<E887AC><E7828F><EFBFBD>嚗?
|
||
4. **璉<><E79289>亦揣撘?*嚗? - <20>臬炏靽萘<E99DBD>鈭<EFBFBD><E988AD><EFBFBD>?`@@index`<EFBFBD><EFBFBD>@@unique`嚗?
|
||
#### 甇仿炊 4嚗𡁻<E59A97><F0A181BB>啁<EFBFBD><E59581>?Prisma Client
|
||
|
||
```bash
|
||
# <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>**嚗?
|
||
```typescript
|
||
// <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
|
||
```
|
||
|
||
### <20>辶 撣貉<E692A3><E8B289>桅<EFBFBD>憭<EFBFBD><E686AD>
|
||
|
||
#### <20>桅<EFBFBD> 1嚗䫤db pull` <20>仿<EFBFBD>嚗𡁏<E59A97>瘜閗<E7989C><E99697>交㺭<E4BAA4>桀<EFBFBD>
|
||
|
||
```bash
|
||
# <20>躰秤靽⊥<E99DBD>嚗?Error: P1001: Can't reach database server at `pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432`
|
||
```
|
||
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
|
||
```bash
|
||
# 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
|
||
```
|
||
|
||
#### <20>桅<EFBFBD> 2嚗䫤db pull` <20>𠬍<EFBFBD><F0A0AC8D>𣂷<EFBFBD>摮埈挾<E59F88><E68CBE>掩<EFBFBD>见<EFBFBD>鈭?
|
||
```prisma
|
||
// 銋见<E98A8B>嚗?model User {
|
||
age Int
|
||
}
|
||
|
||
// db pull <20>𠬍<EFBFBD>
|
||
model User {
|
||
age String @db.VarChar(10) // <20>?蝐餃<E89D90><E9A483>䀹<EFBFBD>鈭?String
|
||
}
|
||
```
|
||
|
||
**<EFBFBD>笔<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仃
|
||
}
|
||
```
|
||
|
||
**<EFBFBD>笔<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>
|
||
|
||
### <20><> <20>滨蔭甇仿炊嚗𡁜<E59A97>憭?Prisma <20><>辣嚗<E8BEA3><E59A97>憿餅<E686BF>銵䕘<E98AB5>
|
||
|
||
**<2A>桅<EFBFBD>**嚗𡁻★<F0A181BB>桃<EFBFBD><E6A183><EFBFBD>葉嚗䈣prisma` <20><>辣憭孵銁**<2A>寧𤌍敶?*嚗䔶<E59A97> Dockerfile <20>?`backend/` <20>桀<EFBFBD><E6A180><EFBFBD><EFBFBD><EFBFBD>𦦵凒<F0A6A6B5>亙銁 `backend/` <20>桀<EFBFBD><E6A180><EFBFBD>遣嚗㷉ocker <20>衤<EFBFBD><E8A1A4>唬<EFBFBD>銝<EFBFBD>撅<EFBFBD><E69285> `prisma` <20><>辣憭嫘<E686AD>?
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD> A嚗𡁜<E59A97><F0A1819C>?Prisma <20>?backend <20>桀<EFBFBD>嚗<EFBFBD>綫<EFBFBD>琜<EFBFBD>**
|
||
|
||
```bash
|
||
# <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>
|
||
```
|
||
|
||
**閫<><E996AB><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>遣嚗?
|
||
```bash
|
||
# <20>冽覔<E586BD>桀<EFBFBD><E6A180><EFBFBD>遣嚗屸<E59A97>閬<EFBFBD>耨<EFBFBD>?Dockerfile <20><>楝敺?# 餈䠷<E9A488><E4A0B7><EFBFBD><EFBFBD>撅訫<E69285>嚗峕綫<E5B395>𣂷蝙<F0A382B7>冽䲮獢?A
|
||
```
|
||
|
||
### <20><> <20>𥕦遣 Dockerfile
|
||
|
||
<EFBFBD>?`backend/` <20>桀<EFBFBD>銝见<E98A9D>撱?`Dockerfile`嚗?
|
||
```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"]
|
||
```
|
||
|
||
### <20><> Dockerfile <20>喲睸靽格㺿霂湔<E99C82>
|
||
|
||
#### 靽格㺿 1嚗𡁜<E59A97>撅<EFBFBD>摰㕑<E691B0> Prisma CLI
|
||
|
||
```dockerfile
|
||
# <20>𤣳 <20>券𧫴畾?2 <20>啣<EFBFBD>嚗?RUN npm install -g prisma@6.17.0
|
||
```
|
||
|
||
**<EFBFBD>笔<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>舐鍂
|
||
|
||
**隞<>遠**嚗?- <20>𨅯<EFBFBD>雿梶妖憓𧼮<E68693>蝥?50MB
|
||
- 雿<><E99BBF><EFBFBD>臬<EFBFBD>澆<EFBFBD><E6BE86><EFBFBD><EFBFBD><EFBFBD>踹<EFBFBD>"<22>賭誘<E8B3AD>曆<EFBFBD><E69B86>?<3F><>䔮憸矋<E686B8>
|
||
|
||
#### 靽格㺿 2嚗帋<E59A97><E5B88B>扯<EFBFBD><E689AF>唳旿摨栞<E691A8>蝘?
|
||
```dockerfile
|
||
# <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"]
|
||
```
|
||
|
||
**<EFBFBD>笔<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>
|
||
|
||
```dockerfile
|
||
# 蝘駁膄嚗?# 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>
|
||
```
|
||
|
||
### <20><> <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>
|
||
|
||
### <20><> <20>滨蔭甇仿炊嚗𡁜<E59A97><F0A1819C>?Prisma <20><>辣嚗<E8BEA3><E59A97>憿餅<E686BF>銵䕘<E98AB5>
|
||
|
||
```bash
|
||
# 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>?
|
||
```bash
|
||
# <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>?
|
||
```bash
|
||
# 瘚贝<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>
|
||
|
||
```bash
|
||
# 瘚贝<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>?
|
||
```bash
|
||
# <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>隞?
|
||
```bash
|
||
# <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 "<EFBFBD>?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>?
|
||
```bash
|
||
# <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>?
|
||
```bash
|
||
# <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>?
|
||
<EFBFBD>餃<EFBFBD><EFBFBD>輸<EFBFBD>鈭烐綉<EFBFBD>嗅蝱 <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
|
||
```
|
||
|
||
#### <20>唳旿摨㯄<E691A8>蝵殷<E89DB5>敹<EFBFBD><E695B9>嚗?
|
||
```bash
|
||
# <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
|
||
- 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 = (400 / 20) - 憸<><E686B8> = 18
|
||
- 憸<><E686B8> 10 銝芾<E98A9D><E88ABE>亦<EFBFBD>蝞∠<E89D9E>隞餃𦛚<E9A483><F0A69B9A><EFBFBD>隞𡝗<E99A9E><F0A19D97>?
|
||
#### 摮睃<E691AE><E79D83>滨蔭嚗<E894AD><E59A97><EFBFBD><EFBFBD>嚗?
|
||
```bash
|
||
# 雿輻鍂<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...
|
||
```
|
||
|
||
#### 蝻枏<E89DBB><E69E8F>屸<EFBFBD><E5B1B8>烾<EFBFBD>蝵殷<E89DB5>Postgres-Only嚗?
|
||
```bash
|
||
# 雿輻鍂 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>
|
||
|
||
```bash
|
||
# 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>嚗?
|
||
```bash
|
||
# <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
|
||
```
|
||
|
||
**憒<><E68692><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`嚗?
|
||
#### 摰匧<E691B0><E58CA7>滨蔭嚗<E894AD><E59A97><EFBFBD><EFBFBD>嚗?
|
||
```bash
|
||
# <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
|
||
```
|
||
|
||
**<EFBFBD><EFBFBD><EFBFBD>撘箏<EFBFBD><EFBFBD>?*嚗?
|
||
```bash
|
||
# 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>
|
||
|
||
```bash
|
||
# 憒<><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>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**<2A>亙熒璉<E78692><E79289>?*
|
||
|
||
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|
||
|-------|-----|------|
|
||
| **璉<><E79289>交䲮撘?* | HTTP 霂瑟<E99C82> | |
|
||
| **璉<><E79289>亥楝敺?* | `/health` | <20>𡒊垢<F0A1928A>亙熒璉<E78692><E79289>亦垢<E4BAA6>?|
|
||
| **璉<><E79289>亦垢<E4BAA6>?* | 3001 | 銝𤾸捆<F0A4BEB8>函垢<E587BD><E59EA2><EFBFBD><EFBFBD>?|
|
||
| **璉<><E79289>亙<EFBFBD>霈?* | HTTP | |
|
||
| **<EFBFBD>嘥<EFBFBD>撱嗉<EFBFBD>** | 60 蝘?| 蝏?Prisma <20>嘥<EFBFBD><E598A5>𤥁雲憭<E99BB2>𧒄<EFBFBD>?|
|
||
| **璉<><E79289>仿𡢿<E4BBBF>?* | 10 蝘?| |
|
||
| **頞<>𧒄<EFBFBD>園𡢿** | 3 蝘?| |
|
||
| **銝滚<E98A9D>摨琿<E691A8><E790BF>?* | 3 甈?| 餈䂿賒憭梯揖 3 甈⊥<E79488>霈唬蛹銝滚<E98A9D>摨?|
|
||
| **<EFBFBD>亙熒<EFBFBD><EFBFBD><EFBFBD>?* | 2 甈?| 餈䂿賒<E482BF>𣂼<EFBFBD> 2 甈⊥<E79488>霈唬蛹<E594AC>亙熒 |
|
||
|
||
### 甇仿炊 6嚗𡁻<E59A97>蝵桀撕<E6A180>找撓蝻?
|
||
**SAE <20>批<EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**撘寞<E69298>找撓蝻?*
|
||
|
||
| <20>滨蔭憿?| <20>?| 霂湔<E99C82> |
|
||
|-------|-----|------|
|
||
| **<EFBFBD><EFBFBD>撠誩<EFBFBD>靘𧢲㺭** | 2 | 擃睃虾<E79D83>其<EFBFBD>霂?|
|
||
| **<EFBFBD><EFBFBD>憭批<EFBFBD>靘𧢲㺭** | 10 | <20>寞旿憸<E697BF><E686B8>韐蠘蝸靚<E89DB8>㟲 |
|
||
| **<EFBFBD>拙捆<EFBFBD>∩辣** | CPU > 70% <20><>賒 3 <20><><EFBFBD> | |
|
||
| **蝻拙捆<E68B99>∩辣** | CPU < 30% <20><>賒 5 <20><><EFBFBD> | |
|
||
|
||
### 甇仿炊 7嚗𡁻<E59A97>蝵格𠯫敹?
|
||
**SAE <20>批<EFBFBD><E689B9>?* <20>?**摨𠉛鍂<F0A0899B>滨蔭** <20>?**<2A>亙<EFBFBD><E4BA99>滨蔭**
|
||
|
||
| <20>滨蔭憿?| <20>?|
|
||
|-------|-----|
|
||
| **<EFBFBD>亙<EFBFBD>蝐餃<EFBFBD>** | <20><><EFBFBD>颲枏枂嚗ìtdout嚗?|
|
||
| **<EFBFBD>亙<EFBFBD>摮睃<EFBFBD>** | 撘<><E69298>荔<EFBFBD>靽嘥<E99DBD> 7 憭抬<E686AD> |
|
||
|
||
### 甇仿炊 8嚗𡁻<E59A97>蝵脣<E89DB5><E884A3>?
|
||
<EFBFBD>孵稬"<22>函蔡"<22>厰僼嚗玺AE 撠<><E692A0>
|
||
|
||
1. 隞?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>?
|
||
### <20>㴓 <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>**嚗?
|
||
**<EFBFBD><EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><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>峕郊]
|
||
```
|
||
|
||
### <20>?甇<>&<EFBFBD><EFBC86><EFBFBD>蝵脩<E89DB5><E884A9>?
|
||
#### 蝑𣇉裦<F0A38789>餉<EFBFBD>
|
||
|
||
| 甇仿炊 | <20>滢<EFBFBD> | 雿閙𧒄<E99699>扯<EFBFBD> | <20>桃<EFBFBD> |
|
||
|------|------|---------|------|
|
||
| **1. 撖澆枂<E6BE86>砍𧑐<E7A08D>唳旿摨?* | `pg_dump` | 擐𡝗活<F0A19D97>函蔡<E587BD>?| 憭<>遢<EFBFBD>唳<EFBFBD><E594B3>唳旿<E594B3>𣬚<EFBFBD><F0A3AC9A>?|
|
||
| **2. 撖澆<E69296><E6BE86>?RDS** | `psql` <20>?DMS | 擐𡝗活<F0A19D97>函蔡<E587BD>?| 餈<>宏<EFBFBD>唬<EFBFBD>蝡?|
|
||
| **3. Prisma <20>滚<EFBFBD><E6BB9A>峕郊** | `prisma db pull` | 擐𡝗活<F0A19D97>函蔡<E587BD>㵪<EFBFBD>蝚?4 <20><><EFBFBD> | <20>峕郊 Schema |
|
||
| **4. <20>臬𢆡摨𠉛鍂** | `node dist/index.js` | SAE <20>函蔡<E587BD>?| 甇<>虜餈鞱<E9A488> |
|
||
| **5. ~~<7E>唳旿摨栞<E691A8>蝘誤~** | ~~`prisma migrate deploy`~~ | <20>?**銝齿<E98A9D>銵?* | 銵典歇摮睃銁嚗峕<E59A97><E5B395><EFBFBD>餈<EFBFBD>宏 |
|
||
|
||
### <20>寞<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>嚗?
|
||
```bash
|
||
# <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>
|
||
```
|
||
|
||
**<2A>寞<EFBFBD> B嚗帋蝙<E5B88B>?DMS嚗<53>燵<EFBFBD>䔶<EFBFBD><E494B6>唳旿蝞∠<E89D9E>嚗?*
|
||
|
||
1. <20>餃<EFBFBD><E9A483>輸<EFBFBD>鈭烐綉<E78390>嗅蝱 <20>?<3F>唳旿蝞∠<E89D9E> DMS
|
||
2. 餈墧𦻖<E5A2A7>?RDS 摰硺<E691B0>
|
||
3. <20>唳旿<E594B3>寞<EFBFBD> <20>?SQL 蝒堒藁 <20>?蝎䁅斐 SQL <20><>辣<EFBFBD><E8BEA3>捆
|
||
4. <20>扯<EFBFBD>
|
||
|
||
#### 甇仿炊 3嚗𡁻<E59A97>霂<EFBFBD>紡<EFBFBD>交<EFBFBD><E4BAA4>?
|
||
```bash
|
||
# 餈墧𦻖<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>峕郊
|
||
|
||
**<2A>𩤃<EFBFBD> 餈嗘<E9A488>甇仿<E79487>撣詨<E692A3><E8A9A8>殷<EFBFBD>**
|
||
|
||
```bash
|
||
# 蝖桐<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>
|
||
```
|
||
|
||
### <20>寞<EFBFBD> 2嚗𡁏<E59A97><F0A1818F>?Prisma Migrations嚗<73><E59A97><EFBFBD><EFBFBD>鍂鈭擧鰵憿寧𤌍嚗?
|
||
**<2A>𩤃<EFBFBD> 憒<><E68692><EFBFBD>函<EFBFBD><E587BD>唳旿摨𤘪糓<F0A498AA>朞<EFBFBD> `pg_dump` 撖澆<E69296><E6BE86><EFBFBD><EFBFBD>霂瑁歲餈<E6ADB2><E9A488>銝<EFBFBD><E98A9D><EFBFBD><EFBFBD>**
|
||
|
||
<details>
|
||
<summary><3E>孵稬撅訫<E69285>嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD>蝘餅<E89D98>蝔页<E89D94>隞<EFBFBD><E99A9E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></summary>
|
||
|
||
#### <20><>鍂<EFBFBD>箸艶
|
||
|
||
- <20>冽鰵憿寧𤌍嚗朙DS <20>唳旿摨𤘪糓蝛箇<E89D9B>
|
||
- 隞擧𧊋<E693A7>见𢆡靽格㺿餈<E3BABF>㺭<EFBFBD>桀<EFBFBD>蝏𤘪<E89D8F>
|
||
- <20><><EFBFBD>㕑”蝏𤘪<E89D8F><F0A498AA>賡<EFBFBD>朞<EFBFBD> Prisma Migrations 蝞∠<E89D9E>
|
||
|
||
#### <20>扯<EFBFBD>甇仿炊
|
||
|
||
```bash
|
||
# 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;"
|
||
```
|
||
|
||
</details>
|
||
|
||
### <20>辶 撣貉<E692A3><E8B289>躰秤銝𦒘耨甇?
|
||
#### <20>躰秤 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>**嚗?
|
||
```bash
|
||
# <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` 銝擧㺭<E693A7>桀<EFBFBD>銝滢<E98A9D><E6BBA2>氬<EFBFBD>?
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
|
||
餈𥪜<EFBFBD>蝚?4 <20><><EFBFBD><EFBFBD>扯<EFBFBD> `npx prisma db pull` <20>滚<EFBFBD><E6BB9A>峕郊<E5B395>?
|
||
### <20>?<3F>函蔡璉<E894A1><E79289>交<EFBFBD><E4BAA4>?
|
||
<EFBFBD>典鍳<EFBFBD>?SAE 摨𠉛鍂<F0A0899B>㵪<EFBFBD>蝖株恕隞乩<E99A9E>甇仿炊撌脣<E6928C><E884A3>琜<EFBFBD>
|
||
|
||
- [ ] <20>砍𧑐<E7A08D>唳旿摨枏歇<E69E8F>朞<EFBFBD> `pg_dump` 撖澆枂
|
||
- [ ] SQL <20><>辣撌脣紡<E884A3>亙<EFBFBD> RDS嚗<53>”蝏𤘪<E89D8F><F0A498AA>峕㺭<E5B395>桅<EFBFBD>摮睃銁嚗?- [ ] 撌脫<E6928C>銵?`npx prisma db pull` <20>峕郊 Schema
|
||
- [ ] 撌脫<E6928C>銵?`npx prisma generate` <20><><EFBFBD>摰X<E691B0>蝡?- [ ] 撌脫<E6928C>鈭?`schema.prisma` <20>?Git
|
||
- [ ] Docker <20>𨅯<EFBFBD><F0A885AF><EFBFBD>鍳<EFBFBD>典𦶢隞?*銝滚<E98A9D><E6BB9A>?* `prisma migrate deploy`
|
||
- [ ] SAE <20>臬<EFBFBD><E887AC>㗛<EFBFBD>銝剔<E98A9D> `DATABASE_URL` <20><><EFBFBD> RDS
|
||
|
||
**憒<><E68692>隞乩<E99A9E><E4B9A9>賜&霈歹<E99C88><E6ADB9>臭誑<E887AD>曉<EFBFBD><E69B89>函蔡嚗?* <20>?
|
||
---
|
||
|
||
## 10. 蝡臬<E89DA1>蝡舀<E89DA1>霂?
|
||
### 甇仿炊 1嚗朞繮<E69C9E>硋<EFBFBD><E7A18B>刻挪<E588BB>桀𧑐<E6A180><F0A79190>
|
||
|
||
**SAE <20>批<EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**摨𠉛鍂霈輸䔮<E8BCB8>滨蔭**
|
||
|
||
憭滚<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>?
|
||
```bash
|
||
# 雿輻鍂<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>?
|
||
```bash
|
||
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>嚗?
|
||
```bash
|
||
# <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>?
|
||
```bash
|
||
# 瘚贝<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>鍂
|
||
|
||
```bash
|
||
# 瘚贝<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>
|
||
|
||
```bash
|
||
# 銝𠹺<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>?
|
||
### <20><> SAE <20>芸蒂<E88AB8>烐綉
|
||
|
||
#### 1. 摰墧𧒄<E5A2A7>烐綉
|
||
|
||
**SAE <20>批<EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**<2A>烐綉**
|
||
|
||
**<EFBFBD>喲睸<EFBFBD><EFBFBD><EFBFBD>**嚗?
|
||
| <20><><EFBFBD> | <20>亙熒<E4BA99><E78692><EFBFBD>?| <20>𡃏郎<F0A1838F><E9838E><EFBFBD>?| 霂湔<E99C82> |
|
||
|------|---------|---------|------|
|
||
| **CPU 雿輻鍂<E8BCBB>?* | < 60% | > 80% | LLM 靚<>鍂<EFBFBD>?CPU 撖<><E69296><EFBFBD>?|
|
||
| **<EFBFBD><EFBFBD><EFBFBD>雿輻鍂<EFBFBD>?* | < 70% | > 85% | <20>烐綉<E78390><E7B689><EFBFBD>瘜<EFBFBD><E7989C> |
|
||
| **霂瑟<E99C82> QPS** | - | - | 鈭<>圾韐蠘蝸 |
|
||
| **撟喳<E6929F><E596B3>滚<EFBFBD><E6BB9A>園𡢿** | < 500ms | > 2000ms | AI 撖寡<E69296><E5AFA1>文<EFBFBD>嚗<EFBFBD>虾<EFBFBD>?10s+嚗?|
|
||
| **<EFBFBD>躰秤<EFBFBD>?* | < 0.5% | > 2% | <20>烐綉<E78390>滚𦛚蝔喳<E89D94><E596B3>?|
|
||
| **摰硺<E691B0><E7A1BA>圈<EFBFBD>** | 2+ | - | 蝖桐<E89D96>擃睃虾<E79D83>?|
|
||
|
||
#### 2. <20>亙<EFBFBD><E4BA99>亦<EFBFBD>
|
||
|
||
**SAE <20>批<EFBFBD><E689B9>?* <20>?**摨𠉛鍂霂行<E99C82>** <20>?**<2A>亙<EFBFBD>** <20>?**摰墧𧒄<E5A2A7>亙<EFBFBD>**
|
||
|
||
**<EFBFBD>喲睸<EFBFBD>亙<EFBFBD>蝷箔<EFBFBD>**嚗?
|
||
```bash
|
||
# <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>?
|
||
```bash
|
||
# <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 餈墧𦻖
|
||
```
|
||
|
||
### <20>圲 <20>亙虜蝏湔擪隞餃𦛚
|
||
|
||
#### 瘥𤩺𠯫璉<F0A0AFAB><E79289>?
|
||
```bash
|
||
# 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>
|
||
```
|
||
|
||
#### 瘥誩𪂹隞餃𦛚
|
||
|
||
```bash
|
||
# 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>
|
||
```
|
||
|
||
### <20>桅<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
|
||
```
|
||
|
||
**<EFBFBD>寞𧋦<EFBFBD>笔<EFBFBD>**嚗?
|
||
- SAE 摰硺<E691B0><E7A1BA>?* 瘥誩<E798A5>靘贝<E99D98><E8B49D>交㺭 > RDS <20><>憭扯<E686AD><E689AF>交㺭
|
||
- 餈墧𦻖<E5A2A7>芣迤蝖桅<E89D96><E6A185>橘<EFBFBD>隞<EFBFBD><E99A9E> Bug嚗?
|
||
**<2A>埝䰻甇仿炊**嚗?
|
||
```bash
|
||
# 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>**嚗?
|
||
```bash
|
||
# <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>亥砭
|
||
```
|
||
|
||
### <20>桅<EFBFBD> 3嚗𡁏<E59A97>瘜閗<E7989C><E99697>?Python 敺格<E695BA><E6A0BC>?
|
||
**<2A><>𠶖**嚗?
|
||
```
|
||
[ERROR] Failed to connect to Python service: ECONNREFUSED
|
||
<EFBFBD>?[ERROR] connect ETIMEDOUT 172.17.x.x:8000
|
||
```
|
||
|
||
**<EFBFBD>埝䰻甇仿炊**嚗?
|
||
```bash
|
||
# 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>**嚗?
|
||
```bash
|
||
# 憒<><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>滚鍳
|
||
```
|
||
|
||
### <20>桅<EFBFBD> 4嚗𡁏<E59A97>瘜閗<E7989C><E99697>?Dify <20>滚𦛚
|
||
|
||
**<EFBFBD><EFBFBD>𠶖**嚗?
|
||
```
|
||
[ERROR] Dify API error: ECONNREFUSED
|
||
<EFBFBD>?[ERROR] Dify API error: 502 Bad Gateway
|
||
```
|
||
|
||
**<EFBFBD>埝䰻甇仿炊**嚗?
|
||
```bash
|
||
# 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>**嚗?
|
||
```bash
|
||
# 憒<><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
|
||
```
|
||
|
||
### <20>桅<EFBFBD> 5嚗鐾SS 銝𠹺<E98A9D>憭梯揖
|
||
|
||
**<EFBFBD><EFBFBD>𠶖**嚗?
|
||
```
|
||
[ERROR] OSS upload failed: AccessDenied
|
||
<EFBFBD>?[ERROR] OSS upload failed: InvalidAccessKeyId
|
||
```
|
||
|
||
**<EFBFBD>埝䰻甇仿炊**嚗?
|
||
```bash
|
||
# 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>**嚗?
|
||
```bash
|
||
# 憒<><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>**嚗?
|
||
1. **<EFBFBD>典<EFBFBD><EFBFBD>㗛<EFBFBD>蝝舐妖**嚗<><E59A97>蝻枏<E89DBB><E69E8F>𣳇<EFBFBD>憓鮋鵭嚗?2. **鈭衤辣<E8A1A4>穃𨯬<E7A983>冽𧊋蝘駁膄**
|
||
3. **摰𡁏𧒄<F0A1818F>冽𧊋皜<F0A78A8B><E79A9C>**
|
||
4. **<EFBFBD>剖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憭批笆鞊?*
|
||
5. **Prisma <20>亥砭蝏𤘪<E89D8F><F0A498AA>芷<EFBFBD><E88AB7>?*
|
||
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
|
||
```typescript
|
||
// <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
|
||
```
|
||
|
||
**<EFBFBD>笔<EFBFBD>**嚗?
|
||
- 撘<><E69298>𤏸<EFBFBD>蝔衤葉<E8A1A4>湔𦻖靽格㺿鈭<E3BABF>㺭<EFBFBD>桀<EFBFBD>嚗<EFBFBD><E59A97>鈭?`phone` 摮埈挾嚗?- 雿<>瓷<EFBFBD>㗇凒<E39787>?`schema.prisma`
|
||
- Prisma Client <20>箔<EFBFBD><E7AE94>抒<EFBFBD> Schema <20><><EFBFBD>嚗䔶<E59A97><E494B6>仿<EFBFBD><E4BBBF>啣<EFBFBD>畾?
|
||
**閫<><E996AB><EFBFBD>寞<EFBFBD>**嚗?
|
||
```bash
|
||
# 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>敹?
|
||
### <20>?<3F><>雿喳<E99BBF>頝?
|
||
#### 1. **<2A>臬<EFBFBD><E887AC>㗛<EFBFBD>蝞∠<E89D9E>**
|
||
|
||
```bash
|
||
# <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. **餈墧𦻖瘙𣳇<E79899>蝵?*
|
||
|
||
```bash
|
||
# <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. **<2A><>辣摮睃<E691AE>**
|
||
|
||
```typescript
|
||
// <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
|
||
```
|
||
|
||
**<EFBFBD>笔<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>典鍳<E585B8>典𦶢隞支葉<E694AF>㰘<EFBFBD><E3B098>扯<EFBFBD> `prisma migrate deploy`**
|
||
|
||
```bash
|
||
# <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. **蝳<>迫敹賜裦 Prisma <20>滚<EFBFBD><E6BB9A>峕郊甇仿炊**
|
||
|
||
```bash
|
||
# <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>?backend/ <20>桀<EFBFBD><E6A180><EFBFBD>遣<EFBFBD>滢<EFBFBD>憭滚<E686AD> Prisma <20><>辣**
|
||
|
||
```bash
|
||
# <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. **蝳<>迫雿輻鍂<E8BCBB>砍𧑐<E7A08D><F0A79190>辣雿靝蛹<E99D9D>笔<EFBFBD>**
|
||
|
||
```typescript
|
||
// <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. **蝳<>迫雿輻鍂<E8BCBB>峕郊<E5B395>餃<EFBFBD><E9A483>滢<EFBFBD>**
|
||
|
||
```typescript
|
||
// <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. **蝳<>迫頝唾<E9A09D><E594BE>亙熒璉<E78692><E79289>?*
|
||
|
||
```typescript
|
||
// <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. **蝳<>迫敹賜裦<E8B39C>躰秤憭<E7A7A4><E686AD>**
|
||
|
||
```typescript
|
||
// <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>鈭抒㴓憓<E3B493>蝙<EFBFBD>?development 璅∪<E79285>**
|
||
|
||
```bash
|
||
# <20>?<3F>躰秤<E8BAB0>滨蔭
|
||
NODE_ENV=development # 隡𡁏<E99AA1><F0A1818F>啣之<E595A3>讛<EFBFBD>霂閙𠯫敹梹<E695B9><E6A2B9>湧蠧<E6B9A7>𤩺<EFBFBD>靽⊥<E99DBD>
|
||
|
||
# <20>?甇<>&<EFBFBD>滨蔭
|
||
NODE_ENV=production
|
||
LOG_LEVEL=info
|
||
```
|
||
|
||
#### 12. **蝳<>迫雿輻鍂撘?JWT 撖<>𤨎**
|
||
|
||
```bash
|
||
# <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>湔𦻖<E6B994>湧蠧 Prisma <20>躰秤<E8BAB0>啣<EFBFBD>蝡?*
|
||
|
||
```typescript
|
||
// <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. **蝳<>迫敹賜裦 Docker <20>𨅯<EFBFBD>隡睃<E99AA1>**
|
||
|
||
```dockerfile
|
||
# <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)嚗<><E59A97><EFBFBD>𥕦遣嚗?
|
||
---
|
||
|
||
## <20><> <20>瑕<EFBFBD>撣桀𨭌
|
||
|
||
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>桅<EFBFBD>嚗?*
|
||
|
||
1. <20>亦<EFBFBD><E4BAA6>祆<EFBFBD>獢<EFBFBD><E78DA2>"<22><><EFBFBD><EFBFBD>埝䰻"蝡㰘<E89DA1>
|
||
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>?
|
||
---
|
||
|
||
**<EFBFBD>函蔡<EFBFBD>匧翰嚗<EFBFBD><EFBFBD><EFBFBD>**
|
||
|