Files
AIclinicalresearch/docs/09-架构实施/后端架构增量演进方案.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

463 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# <20>𡒊垢<F0A1928A><EFBFBD>憓鮋<E68693>瞍磰<E79E8D><E7A3B0><EFBFBD>
> **<2A><>𧋦嚗?* V1.0
> **<2A>𥕦遣<F0A595A6><EFBFBD>嚗?* 2025-11-14
> **蝑𣇉裦嚗?* <20>唳唂撟嗅<E6929F><EFBFBD><E59A97><EFBFBD>𤩺<EFBFBD>餈?
> **<2A><EFBFBD>嚗?* <20><EFBFBD><E59C92>拇㺿<E68B87>𩤃<EFBFBD><F0A9A483>唳芋<E594B3>埈鰵<E59F88><EFBFBD>
---
## <20><20><EFBFBD>蝑𣇉裦
### "蝏墧<E89D8F><E5A2A7><EFBFBD>芋撘?嚗𠄎trangler Fig Pattern嚗?
**銝齿㺿<E9BDBF>䭾唂隞<E59482><E99A9E>嚗峕鰵<E5B395><EFBFBD><E8A098>唳沲<E594B3>?*
```
<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><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><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>? AI銝游<E98A9D><E6B8B8>𠉛弦撟喳蝱 - Backend <20>?
<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><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><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>? <20>?
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><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>? <20>𢞖<EFBFBD><F0A29E96><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>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E79285> <20>? <20>? <20>唳芋<E594B3>? <20>? <20>?
<EFBFBD>? <20>? (<28>扳沲<E689B3>? <20>? <20>? (<28>唳沲<E594B3>? <20>? <20>?
<EFBFBD>? <20><EFBFBD><E98EBF><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>? <20><EFBFBD><E98EBF><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>? <20>?
<EFBFBD>? <20>?<3F>?AIA <20>? <20>?<3F>?ASL (<28>? <20>? <20>?
<EFBFBD>? <20>?<3F>?PKB <20>? <20>?<3F>?<3F>芣䔉璅<E79285>... <20>? <20>?
<EFBFBD>? <20>?<3F>?RVW <20>? <20>? <20>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><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>? <20><EFBFBD><E5A999><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>? <20>?
<EFBFBD>? <20>? <20>? <20>?
<EFBFBD>? 撟喲唍蝏𤘪<E89D8F> platform/common/modules <20>?
<EFBFBD>? 靽脲<E99DBD>銝滚<E98A9D> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
<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><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><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>?
```
---
## <20><> <20><EFBFBD><E59581><EFBFBD>蝏𤘪<E89D8F><EFBFBD>僎摮条<E691AE>嚗?
```
backend/
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> src/
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> index.ts # 銝餃<E98A9D><E9A483><EFBFBD><EFBFBD>瘜典<E7989C><E585B8><EFBFBD><EFBFBD>㗇芋<E39787><EFBFBD>
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> config/ # <20>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD>蝵桀<E89DB5>
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> env.ts
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> database.ts
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> legacy/ # <20><20><EFBFBD><EFBFBD><E99A9E><EFBFBD><EFBFBD><EFBFBD>嚗?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> routes/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> agents.ts # AIA 頝舐眏
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> conversations.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> chatRoutes.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> projects.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> knowledgeBases.ts # PKB 頝舐眏
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> batchRoutes.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> reviewRoutes.ts # RVW 頝舐眏
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> controllers/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> agentController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> conversationController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> chatController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> knowledgeBaseController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> reviewController.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> services/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> agentService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> conversationService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> knowledgeBaseService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> reviewService.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> templates/
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> clinicalResearch.ts
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> common/ # <20>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD>𡁶鍂<F0A181B6><EFBFBD>撅?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> llm/ # LLM <20><><EFBFBD><EFBFBD>?
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> adapters/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> DeepSeekAdapter.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> QwenAdapter.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> LLMFactory.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> types.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> rag/ # RAG <20><EFBFBD>
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> DifyClient.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> types.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> document/ # <20><>﹝憭<EFB99D><E686AD>
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> ExtractionClient.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> TokenService.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> middleware/ # 銝剝𡢿隞?
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> validateProject.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> utils/ # 撌亙<E6928C><E4BA99>賣㺭
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> jsonParser.ts
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> modules/ # <20><> <20>唳沲<E594B3><E6B2B2><EFBFBD><EFBFBD><E6A2B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E98EBF><EFBFBD> asl/ # 潃?AI<41><EFBFBD><E7AE84><EFBFBD>讃嚗<E8AE83>鰵璅<E79285>嚗?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> index.ts # 璅<E79285>撖澆枂
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> routes/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> index.ts # 頝舐眏蝏煺<E89D8F>撖澆枂
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> projects.ts # 憿寧𤌍蝞∠<E89D9E>
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> screening.ts # <20><>讃蝑偦<E89D91>?
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> extraction.ts # <20>唳旿<E594B3>𣂼<EFBFBD>
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> analysis.ts # 蝏澆<E89D8F><E6BE86><EFBFBD><EFBFBD>
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> controllers/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> projectController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> screeningController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> extractionController.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> analysisController.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E98EBF><EFBFBD> services/
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> projectService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> screeningService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E98EBF><EFBFBD> extractionService.ts
<EFBFBD>? <20>? <20>? <20><EFBFBD><E5A999><EFBFBD> analysisService.ts
<EFBFBD>? <20>? <20>?
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> types/ # 璅<E79285>蝐餃<E89D90>摰帋<E691B0>
<EFBFBD>? <20>? <20><EFBFBD><E5A999><EFBFBD> index.ts
<EFBFBD>? <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> [<5B>芣䔉璅<E79285>]/ # <20>芣䔉<E88AA3><E49489>鰵璅<E79285><E288AA><EFBFBD>甇斤<E79487><E696A4>?
<EFBFBD>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> package.json
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> tsconfig.json # TypeScript <20>滨蔭
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> .env
```
---
## <20><> 銝餃<E98A9D><E9A483><EFBFBD><EFBFBD>隞塚<E99A9E>index.ts嚗?
```typescript
/**
* AI銝游<E98A9D><E6B8B8>𠉛弦撟喳蝱 - 蝏煺<E89D8F><E785BA>亙藁
*
* <20><EFBFBD>瞍磰<E79E8D>蝑𣇉裦嚗𡁏鰵<F0A1818F>批僎摮?
* - Legacy 璅<E79285>嚗帋<E59A97><E5B88B><EFBFBD><EFBFBD><EFBFBD><E58EA9>?
* - New 璅<E79285>嚗𡁻<E59A97><F0A181BB><EFBFBD><E586BD><EFBFBD><EFBFBD>銝匧<E98A9D><E58CA7><EFBFBD>
*/
import Fastify from 'fastify';
import cors from '@fastify/cors';
import multipart from '@fastify/multipart';
import { config, validateEnv } from './config/env.js';
import { testDatabaseConnection, prisma } from './config/database.js';
// ============================================
// <20>鞉唂<E99E89><EFBFBD><E59786>鍸egacy 璅<E79285> - 靽脲<E99DBD>銝滚<E98A9D>
// ============================================
import { projectRoutes } from './legacy/routes/projects.js';
import { agentRoutes } from './legacy/routes/agents.js';
import { conversationRoutes } from './legacy/routes/conversations.js';
import { chatRoutes } from './legacy/routes/chatRoutes.js';
import knowledgeBaseRoutes from './legacy/routes/knowledgeBases.js';
import batchRoutes from './legacy/routes/batchRoutes.js';
import reviewRoutes from './legacy/routes/reviewRoutes.js';
// ============================================
// <20>鞉鰵<E99E89><EFBFBD><E59786><EFBFBD><E78390><EFBFBD><EFBFBD><E79285>
// ============================================
import { aslRoutes } from './modules/asl/routes/index.js'; // ASL 璅<E79285><EFBFBD>鰵嚗?
const fastify = Fastify({ logger: true });
// 瘜典<E7989C><E585B8>雴辣
await fastify.register(cors, { origin: true });
await fastify.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
// <20>亙熒璉<E78692><E79289>?
fastify.get('/health', async () => ({
status: 'ok',
architecture: 'hybrid', // 瘛瑕<E7989B><E79195><EFBFBD>
modules: {
legacy: ['aia', 'pkb', 'rvw'],
modern: ['asl'],
},
}));
// ============================================
// 瘜典<E7989C> Legacy 璅<E79285>頝舐眏嚗<E79C8F><EFBFBD><EFBFBD>嚗?
// ============================================
console.log('\n<>𣑐 <20>㰘蝸 Legacy 璅<E79285>...');
await fastify.register(projectRoutes, { prefix: '/api/v1/aia' });
await fastify.register(agentRoutes, { prefix: '/api/v1/aia' });
await fastify.register(conversationRoutes, { prefix: '/api/v1/aia' });
await fastify.register(chatRoutes, { prefix: '/api/v1/aia' });
await fastify.register(knowledgeBaseRoutes, { prefix: '/api/v1/pkb' });
await fastify.register(batchRoutes, { prefix: '/api/v1/pkb' });
await fastify.register(reviewRoutes, { prefix: '/api/v1/rvw' });
console.log('<27>?Legacy 璅<E79285><E288AA>㰘蝸摰峕<E691B0>嚗㇁IA, PKB, RVW嚗?);
// ============================================
// 瘜典<E7989C><E585B8>唳沲<E594B3><E6B2B2><EFBFBD>𡑒楝<F0A19192>?
// ============================================
console.log('\n<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?..');
await fastify.register(aslRoutes, { prefix: '/api/v1/asl' });
console.log('<EFBFBD>?<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ASL嚗?);
// <20>臬𢆡<E887AC>滚𦛚<E6BB9A>?
async function start() {
try {
validateEnv();
await testDatabaseConnection();
await fastify.listen({ port: config.port, host: config.host });
console.log('\n' + '='.repeat(60));
console.log('<27><> AI銝游<E98A9D><E6B8B8>𠉛弦撟喳蝱<E596B3>臬𢆡<E887AC>𣂼<EFBFBD>嚗?);
console.log('='.repeat(60));
console.log(`<60><> <20>滚𦛚<E6BB9A><EFBFBD>: http://${config.host}:${config.port}`);
console.log('\n<EFBFBD>𣑐 <EFBFBD><EFBFBD><EFBFBD>:');
console.log(' <EFBFBD> Legacy <EFBFBD><EFBFBD>: AIA, PKB, RVW (<EFBFBD><EFBFBD>)');
console.log(' <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>? ASL (<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡝗<EFBFBD>?');
console.log('='.repeat(60) + '\n');
} catch (error) {
console.error('<EFBFBD>?<EFBFBD>𢆡:', error);
await prisma.$disconnect();
process.exit(1);
}
}
start();
```
---
## <20><> <20>唳芋<E594B3><EFBFBD><E5A092><EFBFBD><E78390><EFBFBD>ASL 銝箔<E98A9D>嚗?
### 1. <20>𥕦遣璅<E79285>撉冽沲
```bash
# 銝<>甈⊥<E79488><EFBFBD>撱箸<E692B1><E7AEB8>厩𤌍敶?
mkdir -p backend/src/modules/asl/{routes,controllers,services,types}
```
### 2. <20>𥕦遣璅<E79285>撖澆枂嚗ǎndex.ts嚗?
```typescript
// backend/src/modules/asl/index.ts
/**
* ASL 璅<E79285>蝏煺<E89D8F>撖澆枂
*/
export { aslRoutes } from './routes/index.js';
export * from './types/index.js';
```
### 3. <20>𥕦遣頝舐眏蝏煺<E89D8F>撖澆枂
```typescript
// backend/src/modules/asl/routes/index.ts
import { FastifyInstance } from 'fastify';
import { projectRoutes } from './projects.js';
import { screeningRoutes } from './screening.js';
import { extractionRoutes } from './extraction.js';
import { analysisRoutes } from './analysis.js';
/**
* ASL 璅<E79285>頝舐眏瘜典<E7989C>
*/
export async function aslRoutes(fastify: FastifyInstance) {
// 瘜典<E7989C><E585B8><EFBFBD><EFBFBD><E79285>頝舐眏
await fastify.register(projectRoutes); // /projects
await fastify.register(screeningRoutes); // /screening
await fastify.register(extractionRoutes); // /extraction
await fastify.register(analysisRoutes); // /analysis
console.log('<27>?ASL 璅<E79285>頝舐眏瘜典<E7989C>摰峕<E691B0>');
}
```
### 4. <20><><EFBFBD><EFBFBD>𣇉<EFBFBD> Controller 璅<E79285>
```typescript
// backend/src/modules/asl/controllers/projectController.ts
import { FastifyRequest, FastifyReply } from 'fastify';
import * as projectService from '../services/projectService.js';
export class ProjectController {
/**
* <20><EFBFBD>憿寧𤌍<E5AFA7>𡑒”
*/
async getProjects(request: FastifyRequest, reply: FastifyReply) {
try {
const projects = await projectService.getProjects();
return reply.send({ success: true, data: projects });
} catch (error) {
console.error('<27><EFBFBD>憿寧𤌍<E5AFA7>𡑒”憭梯揖:', error);
return reply.status(500).send({
success: false,
message: error instanceof Error ? error.message : '<EFBFBD>𦛚<EFBFBD><EFBFBD>?
});
}
}
// ... <20><EFBFBD><E597A1><EFBFBD>
}
export const projectController = new ProjectController();
```
---
## <20>圲 TSConfig 頝臬<E9A09D><E887AC><EFBFBD><E680A0>滨蔭
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@config/*": ["src/config/*"],
"@common/*": ["src/common/*"],
"@legacy/*": ["src/legacy/*"],
"@modules/*": ["src/modules/*"]
}
}
}
```
**雿輻鍂蝷箔<E89DB7>嚗?*
```typescript
// <20>唳芋<E594B3>𦯀葉撖澆<E69296><E6BE86>𡁶鍂<F0A181B6><EFBFBD>
import { LLMFactory } from '@common/llm/adapters/LLMFactory.js';
import { DifyClient } from '@common/rag/DifyClient.js';
import { config } from '@config/env.js';
// Legacy 璅<E79285>靽脲<E99DBD><E884B2><EFBFBD><EFBFBD>撖澆<E69296>銝滚<E98A9D>
import { agentService } from '../services/agentService.js';
```
---
## <20><> 摰墧鴌甇仿炊嚗<E7828A>妟憌𡡞埯嚗?
### 蝚?1 甇伐<E79487><E4BC90><EFBFBD><EFBFBD><EFBFBD>嚗?<3F><><EFBFBD>嚗争<E59A97>
```bash
# 1. <20>𥕦遣 legacy <20><EFBFBD>
mkdir backend/src/legacy
# 2. 蝘餃𢆡<E9A483><EFBFBD><EFBFBD><E99A9E><EFBFBD>?legacy嚗<79><E59A97><EFBFBD><EFBFBD>㮾撖寡楝敺<E6A59D><E695BA><EFBFBD><EFBFBD>
mv backend/src/routes backend/src/legacy/
mv backend/src/controllers backend/src/legacy/
mv backend/src/services backend/src/legacy/
mv backend/src/templates backend/src/legacy/
# 3. <20>𥕦遣<F0A595A6>唳沲<E594B3><E6B2B2>𤌍敶?
mkdir -p backend/src/modules/asl/{routes,controllers,services,types}
```
**撉諹<E69289>嚗?* <20>𣳇<EFBFBD>靽格㺿隞颱<E99A9E><EFBFBD><E99A9E><EFBFBD><EFBFBD>舐宏<E88890>函𤌍敶蓥<E695B6>蝵?
---
### 蝚?2 甇伐<E79487><E4BC90>湔鰵銝餃<E98A9D><E9A483><EFBFBD><EFBFBD>5<EFBFBD><35><EFBFBD>嚗?
<EFBFBD>芯耨<EFBFBD>?`src/index.ts` <20><><EFBFBD>亥楝敺<E6A59D><E695BA>
```typescript
// <20><EFBFBD>from './routes/agents.js'
// <20><EFBFBD>from './legacy/routes/agents.js'
```
**撉諹<E69289>嚗?* `npm run dev` <20>滚𦛚<E6BB9A>冽迤撣詨鍳<E8A9A8>?
---
### 蝚?3 甇伐<E79487><E4BC90>滨蔭 TSConfig嚗?<3F><><EFBFBD>嚗?
瘛餃<EFBFBD>頝臬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨蔭<EFBFBD>?
**撉諹<E69289>嚗?* IDE <20><EFBFBD><E8B3AA>?`@legacy/*`, `@modules/*` 蝑㕑楝敺?
---
### 蝚?4 甇伐<E79487><EFBFBD><E69298>?ASL 璅<E79285><EFBFBD><EFBFBD><EFBFBD>嚗?
<EFBFBD>㗇鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡢅<EFBFBD><EFBFBD><EFBFBD>銝滚蔣<EFBFBD>滨緵<EFBFBD>㗇芋<EFBFBD>𨰜<EFBFBD>?
---
## <20>?<3F><EFBFBD>隡睃飵
### 1. **<2A><EFBFBD><E59C92>拇㺿<E68B87>?*
- <20>?<3F><EFBFBD><EFBFBD><E99A9E><EFBFBD>芰宏<E88AB0>函𤌍敶𤏪<E695B6>銝滢耨<E6BBA2><EFBFBD>摰?
- <20>?<3F>芣㺿銝<E3BABF>銝芣<E98A9D>隞嗥<E99A9E>撖澆<E69296>頝臬<E9A09D>
- <20>?<3F><EFBFBD><E888AB><EFBFBD>皛?
### 2. **皜<><EFBFBD><E88B8A><EFBFBD><E6B2B2><EFBFBD>?*
```
legacy/ <20>?<3F>找誨<E689BE><E8AAA8><EFBFBD><EFBFBD>𡒊<F0A1928A><EFBC86><EFBFBD>
modules/ <20>?<3F>唬誨<E594AC><E8AAA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
```
### 3. **<2A>唳芋<E594B3>埈鰵<E59F88><EFBFBD>**
- <20>?ASL <20>湔𦻖<E6B994><EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD>?
- <20>?<3F>𣂷蛹<F0A382B7>芣䔉璅<E79285><E288AA><EFBFBD><EFBFBD><EFBFBD>?
- <20>?銝滚<E98A9D><E6BB9A>找誨<E689BE><E8AAA8><EFBFBD>?
### 4. **撟單<E6929F>瞍磰<E79E8D>頝臬<E9A09D>**
```
<EFBFBD>啣銁嚗?銝芣唂璅<E79285> + 0銝芣鰵璅<E79285>
<EFBFBD>芣䔉嚗?銝芣唂璅<E79285> + 1銝芣鰵璅<E79285>嚗㇁SL嚗?
<EFBFBD><EFBFBD>嚗?銝芣唂璅<E79285> + N銝芣鰵璅<E79285>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞉郊餈<EFBFBD><EFBFBD>扳芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
```
---
## <20>㴓 瞍磰<E79E8D><E7A3B0>園𡢿頧?
| <20>嗆挾 | <20>園𡢿 | 撌乩<E6928C><E4B9A9><EFBFBD>捆 | 憌𡡞埯 |
|------|------|---------|------|
| **隞𠰴予** | 15<31><35><EFBFBD> | <20><EFBFBD><E6BBA8><EFBFBD>+<2B>湔鰵<E6B994>亙藁 | <20><><EFBFBD> |
| **Week 3** | - | 撘<><E69298>?ASL 璅<E79285><EFBFBD><EFBFBD><EFBFBD>嚗?| <20>𩤃<EFBFBD><F0A9A483><EFBFBD><E595A3><EFBFBD> |
| **Week 4+** | - | 蝏抒賒撘<E8B392><E69298>烐鰵璅<E79285> | <20>?|
| **<EFBFBD>芣䔉** | <20><EFBFBD> | <20>鞉郊餈<E9838A><EFBFBD>扳芋<E689B3><EFBFBD><E6A2B9><EFBFBD><EFBFBD> | <20>舀綉 |
---
## <20><><><E69298>𤏸<EFBFBD><F0A48FB8>?
### Legacy 璅<E79285><EFBFBD><E996AB>
- <20>𩤃<EFBFBD> **銝滢蜓<E6BBA2>其耨<E585B6>?*嚗屸膄<E5B1B8>硺耨憭嵖ug
- <20>𩤃<EFBFBD> 靽脲<E99DBD><E884B2><EFBFBD>蝏𤘪<E89D8F>銝滚<E98A9D>
- <20>𩤃<EFBFBD> <20>臭誑撘閧鍂 `common/`<><E69285><EFBFBD><EFBFBD>
### <20>唳芋<E594B3>𡑒<EFBFBD><F0A19192>?
- <20>?敹<><EFBFBD><EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <20>?敹<>◆雿輻鍂頝臬<E9A09D><E887AC><EFBFBD>
- <20>?敹<><EFBFBD><EFBFBD><E7A589><EFBFBD>蝵?
- <20>?敹<><EFBFBD><EFBFBD><E58CA7><EFBFBD>蝐餃<E89D90>摰帋<E691B0>
---
## <20><> 銝衤<E98A9D>甇亥<E79487><E4BAA5>?
1. **隞𠰴予嚗?5<><35><EFBFBD>嚗?*嚗𡁏<E59A97>銵𣬚洵1-3甇伐<E79487>摰峕<E691B0><E5B395><EFBFBD><E6A180><EFBFBD>
2. **<EFBFBD>𤾸予**嚗𡁜<E59A97>憪?ASL 璅<E79285><EFBFBD><E69298>𡢅<EFBFBD><F0A1A285>唳沲<E594B3><E6B2B2><EFBFBD>
3. **Week 3**嚗鋫SL 璅<E79285>銝羓瑪
4. **<EFBFBD>芣䔉**嚗𡁏鰵璅<E79285><E288AA><EFBFBD><EFBFBD><EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD>?
---
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-14
**蝏湔擪<E6B994><E693AA><EFBFBD>**<><E69298>穃𣪧<E7A983>?