Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/04-开发计划/最小MVP闭环开发计划.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

46 KiB
Raw Blame History

IIT Manager Agent - 譛€蟆舟VP髣ュ邇ッ蠑€蜿題ョ。蛻?

迚域悽: v1.0
蛻帛サコ譌・譛<EFBFBD>: 2026-01-02
逶ョ譬<EFBFBD>: 謇馴€?REDCap 竊?Node.js 竊?莨∽ク壼セョ菫。 逧<>ョ梧紛髣ュ邇? **鬚<>シー蟾・菴憺<E88FB4>?*: 2螟ゥ<E89E9F><EFBDA9>ay 3-4<>? 譬ク蠢<EFBFBD>炊蠢オ: 蜈域遠騾壽怙蟆城溜邇ッ<E98287>碁ェ瑚ッ∵橿譛ッ蜿ッ陦梧€<C280><EFBFBD>騾先ュ・荳ー蟇悟粥閭ス


<EFBFBD>識 荳€VP螳壻ケ我ク守岼譬?

1.1 莉€荵域弍譛€蟆城溜邇ッ<E98287><EFBDAF>

譬ク蠢<EFBFBD>溜邇ッ<EFBFBD>?``` REDCap蠖募<E8A096>謨ー謐ョ 竊?Node.js螳樊慮謐戊執 竊?莨∽ク壼セョ菫。譎コ閭ス騾夂衍 竊?PI蟇ケ隸晄衍隸「


**鬪瑚ッ∽サキ蛟?*<2A>?1. 笨?**螳樊慮諢溽衍**<2A>啀I譌<49>€逋サ蠖紐EDCap<61>碁囂譌カ謗梧升鬘ケ逶ョ霑帛ア?2. 笨?**荳サ蜉ィ騾夂衍**<2A>壽焚謐ョ蠖募<E8A096>蜷守ォ句叉謗ィ騾<EFBDA8>シ御ク堺シ夐<EFBCA0>
3. 笨?**譎コ閭ス莠、莠<EFBDA4>**<2A>壼惠莨∽ク壼セョ菫。荳ュ蜊ウ蜿ッ譟・隸「謨ー謐ョ縲∬執蜿匁冠蜻?4. 笨?**譏捺黄螻?*<2A>夐溜邇ッ謇馴€壼錘<E5A3BC>悟庄莉・蠢ォ騾滓キサ蜉<EFBDBB>雍ィ謗ァ縲∵署驢偵€∫サ溯ョ。遲牙粥閭ス

### 1.2 證ゆク榊ョ樒鴫逧<E9B4AB>粥閭ス<E996AD>亥錘扈ュ謇ゥ螻包シ?
- 竢ク<E7ABA2><EFBDB8> **謨ー謐ョ雍ィ謗ァ隗<EFBDA7><E99A97>逕滓<E98095>**<2A><>hase 1.5<EFBFBD>会シ壻ク贋シ<EFBFBD>遐皮ゥカ譁ケ譯<EFBFBD> 竊?AI逕滓<E98095><EFBFBD><E99A97>蠎?竊?蝓コ莠手ァ<E6898B><EFBDA7>雍ィ謗ァ
- 竢ク<E7ABA2><EFBDB8> **PC Workbench蜑咲ォッ**<2A><>hase 2<>会シ壼、肴<EFBDA4>クAI蟒コ隶ョ逧Цeb逡碁擇
- 竢ク<E7ABA2><EFBDB8> **REDCap謨ー謐ョ蝗槫<E89D97>**<2A><>hase 2<>会シ哂I蟒コ隶ョ螳。謇ケ蜷主屓蜀吝芦REDCap
- 竢ク<E7ABA2><EFBDB8> **蠕ョ菫。蟆冗ィ句コ?*<2A><>hase 3<>会シ夂ァサ蜉ィ遶ッ蜴溽函菴馴ェ?- 竢ク<E7ABA2><EFBDB8> **螟肴揩蟇ケ隸晁<E99AB8><EFBFBD>**<2A><>hase 3<>会シ壼、夊スョ蟇ケ隸昴€∽ク贋ク区枚逅<E69E9A>ァ」

---

## <20>投 莠後€∝ス灘燕迥カ諤∵€サ扈<EFBDBB>

### 2.1 蟾イ螳梧<E89EB3><EFBFBD>㊥螟<E38AA5>キ・菴懶シ<E687B6>ay 1-2<>?
#### 笨?Day 1<>夂識蠅<E8AD98><E8A085>蟋句喧<E58FA5>?026-01-01<30>?
**謨ー謐ョ蠎?*<2A>?- 笨?蛻帛サコ `iit_schema`<60>?荳ェ陦ィ<E999A6>?- 笨?Prisma Schema螳梧紛<E6A2A7><E7B49B>itProject, IitPendingAction, IitTaskRun, IitUserMapping, IitAuditLog<6F>?- 笨?CRUD豬玖ッ暮€夊ソ<E5A48A>シ?1/11<31>?
**莨∽ク壼セョ菫。**<2A>?- 笨?莨∽ク壼セョ菫。蠑€蜿題€<E9A18C>エヲ蜿キ豕ィ蜀?- 笨?閾ェ蟒コ蠎皮畑蛻帛サコ<EFBDBB><EFBDBA>IT Manager Agent<6E>?- 笨?蜃ュ隸∬執蜿厄シ?  - **CorpID**: `ww01cb7b72ea2db83c`
  - **AgentID**: `1000002`
  - **Secret**: `F3XqlAqKdcOKHi9pLGv5a2dSUowWbevdcDRrBk2pXLM`
- 笨?**鄂鷹。オ謗域揀蜿開S-SDK謗域揀蟾イ闔キ蜿?*
- 笨?**蜿ッ菫。蝓溷錐驟咲スョ謌仙粥**<2A>啻iit.xunzhengyixue.com`
- 笨?**蝓溷錐鬪瑚ッ∵枚莉カ驛ィ鄂イ**<2A>啻WW_verify_YnhsQBwI0ARnNoG0.txt`
- 笨?**Access Token闔キ蜿匁オ玖ッ暮€夊ソ<E5A48A>**

**讓。蝮鈴ェィ譫カ**<2A>?- 笨?逶ョ蠖慕サ捺桷蛻帛サコ
- 笨?邀サ蝙句ョ壻ケ牙ョ梧紛<E6A2A7>?23陦鯉シ<E9AF89>
- 笨?霍ッ逕ア蜑咲シ€驟咲スョ<EFBDBD><EFBDAE>/api/v1/iit`<60>?
---

#### 笨?Day 2<>啌EDCap螳樊慮髮<E685AE><E9ABAE><EFBFBD>?026-01-02<30>?
**譬ク蠢<EFBDB8>コ、莉倡<E88E89>?*<2A><>2,200陦御サ」遐<EFBDA3>シ会シ?1. 笨?**RedcapAdapter.ts**<2A>?71陦鯉シ<E9AF89>
   - `exportRecords()` - 蟇シ蜃コ隶ー蠖包シ域髪謖∝<E8AC96>驥?蠅樣㍼/謖<>ョ夊ョー蠖包シ?   - `exportMetadata()` - 蟇シ蜃コ蟄玲ョオ螳壻ケ<E5A3BB>
   - `importRecords()` - 蟇シ蜈・隶ー蠖包シ磯「<E7A3AF><EFBFBD><E89597>
   - `testConnection()` - 霑樊磁豬玖ッ<E78E96>

2. 笨?**WebhookController.ts**<2A>?27陦鯉シ<E9AF89>
   - `handleWebhook()` - 謗・謾カREDCap DET隗ヲ蜿托シ?10ms蜩榊コ費シ?   - 蟷らュ画€ァ譽€譟・<E8AD9F>磯亟豁「驥榊、榊、<E6A68A><EFBFBD>?   - 螳。隶。譌・蠢苓ョー蠖<EFBDB0>
   - 謗ィ騾∝芦雍ィ謗ァ髦溷<E9ABA6><E6BAB7><EFBFBD>iit_quality_check`<60>?
3. 笨?**SyncManager.ts**<2A>?98陦鯉シ<E9AF89>
   - `initScheduledJob()` - 蛻晏ァ句喧螳壽慮莉サ蜉。<E89C89>域ッ?蛻<><EFBFBD>?   - `handlePoll()` - 霓ョ隸「謇€譛餌ctive鬘ケ逶ョ
   - `manualSync()` - 謇句勘蜷梧ュ・
   - `fullSync()` - 蜈ィ驥丞酔豁・

4. 笨?**Worker豕ィ蜀<EFBDA8>**<2A>?1陦鯉シ<E9AF89>
   - `iit_quality_check` - 雍ィ謗ァ莉サ蜉。<E89C89>亥キイ豕ィ蜀鯉シ悟セ<E6829F>。・蜈<EFBDA5>€サ霎托シ?   - `iit_redcap_poll` - 螳壽慮霓ョ隸「莉サ蜉。

5. 笨?**霍ッ逕ア驟咲スョ**<2A>?03陦鯉シ<E9AF89>
   - `/api/v1/iit/health` - 蛛・蠎キ譽€譟?   - `/api/v1/iit/webhooks/redcap` - DET蝗櫁ー<E6AB81>磁謾カ<E8ACBE>域髪謖orm-urlencoded<65>?   - `/api/v1/iit/webhooks/health` - Webhook蛛・蠎キ譽€譟?   - `/api/v1/iit/projects/:id/sync` - 謇句勘蜷梧ュ・
   - `/api/v1/iit/projects/:id/full-sync` - 蜈ィ驥丞酔豁・

**豬玖ッ戊<EFBDAF>譛ャ**<2A>?12陦鯉シ会シ?- 笨?`test-redcap-api.ts`<60>?89陦鯉シ<E9AF89>- API騾る<E9A8BE>蝎ィ豬玖ッ?- 笨?`test-redcap-webhook.ts`<60>?74陦鯉シ<E9AF89>- Webhook謗・謾カ蝎ィ豬玖ッ?- 笨?`test-redcap-integration.ts`<60>?49陦鯉シ<E9AF89>- 遶ッ蛻ー遶ッ髮<EFBDAF><E9ABAE>豬玖ッ?
**豬玖ッ慕サ捺棡**<2A>?- 笨?**髮<><E9ABAE>豬玖ッ暮€夊ソ<E5A48A><EFBDBF>?*<2A>?2/12<31>?00%<25>?- 笨?**Webhook蜩榊コ疲慮髣エ**<2A>?10ms<6D>育岼譬?100ms<6D>?- 笨?**DET隗ヲ蜿大サカ霑<EFBDB6>**<2A>?遘抵シ亥ョ樊慮<E6A88A>?- 笨?**謨ー謐ョ蜷梧ュ・蜃<EFBDA5>。ョ諤?*<2A>?00%

**REDCap邇ッ蠅<EFBDAF>**<2A>?- 笨?REDCap 15.8.0譛ャ蝨ーDocker驛ィ鄂イ
- 笨?豬玖ッ暮。ケ逶ョ蛻帛サコ<EFBDBB><EFBDBA>est0102, PID 16<31>?- 笨?6譚。豬玖ッ墓焚謐ョ蠖募<E8A096>?- 笨?DET驟咲スョ謌仙粥<E4BB99>啻http://host.docker.internal:3001/api/v1/iit/webhooks/redcap`
- 笨?API Token逕滓<E98095><E6BB93>啻FCB30F9CBD12EE9E8E9B3E3A0106701B`

**蜈ウ髞ョ謚€譛ッ遯∫<E981AF>?*<2A>?1. 笨?REDCap DET螳樊慮隗ヲ蜿托シ?遘貞サカ霑滂シ<E6BB82>
2. 笨?form-urlencoded譬シ蠑乗髪謖<E9ABAA><EFBFBD>EDCap蜴溽函譬シ蠑擾シ?3. 笨?蜿御ソ晞勦譛コ蛻カ<E89BBB><EFBDB6>ebhook + 螳壽慮霓ョ隸「<E99AB8>?4. 笨?隨ヲ蜷亥屬髦溷シ€蜿題ァ<E9A18C><EFBFBD>磯弌蛻怜多蜷阪€仝orker豕ィ蜀鯉シ?
---

### 2.2 蠖灘燕譫カ譫<EFBDB6>憾諤?

笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏? 蟾イ螳梧<E89EB3><EFBFBD>渕遑€隶セ譁ス 笏?笏懌楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏? 笏?笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏? REDCap 笏? 竊?謨ー謐ョ蠖募<E8A096> 笏?笏? 笏? 15.8.0 笏? 竊?DET驟咲スョ 笨? 笏?笏? 笏披楳笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏?DET隗ヲ蜿托シ?遘貞サカ霑滂シ俄<EFBDBC>? 笏?笏? 竊? 笏?笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏? Node.js Backend 笏? 笏?笏? 笏? (Fastify + pg-boss) 笏? 笏?笏? 笏懌楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏?笨?WebhookController 笏?竊?謗・謾カDET (<10ms) 笏?笏? 笏?笨?RedcapAdapter 笏?竊?諡牙叙謨ー謐ョ 笏?笏? 笏?笨?SyncManager 笏?竊?霓ョ隸「陦・蜈<EFBDA5> 笏?笏? 笏?笨?Worker髦溷<E9ABA6> 笏?竊?蠑よュ・螟<EFBDA5>炊 笏?笏? 笏?竢?WechatService 笏?竊?蠕<>€蜿?<3F>櫨 笏?笏? 笏披楳笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏?蠕<>遠騾?<3F>櫨 笏?笏? 竊? 笏?笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏? 莨∽ク壼セョ菫。 笏? 笏?笏? 笏? (蟾イ驟咲ス?笨? 笏? 笏?笏? 笏懌楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏?笨?蠎皮畑蛻帛サコ 笏? 笏?笏? 笏?笨?蜃ュ隸<EFBDAD><E99AB8>鄂ョ 笏? 笏?笏? 笏?笨?蝓溷錐謗域揀 笏? 笏?笏? 笏?笨?AccessToken闔キ蜿<EFBDB7> 笏? 笏?笏? 笏?竢?豸域<E8B1B8>謗ィ騾? 笏?竊?蠕<>€蜿?<3F>櫨 笏?笏? 笏?竢?豸域<E8B1B8>謗・謾カ 笏?竊?蠕<>€蜿?<3F>櫨 笏?笏? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 笏?笏? 笏?笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?```


<EFBFBD><EFBFBD><EFBFBD> 荳峨€<C280>髞ョ謚€譛ッ鬟朱勦荳手ァ<E6898B>∩譁ケ譯<EFBDB9>

蝨ィ豁」蠑丞シ€蜿大燕<EFBFBD>?*蠢<>。サ莠<EFBDBB>ァ」**莉・荳<EFBDA5>3荳ェ莨∽ク壼セョ菫。蟇ケ謗・逧<EFBDA5><E980A7>蜻ス髯キ髦ア<E9ABA6>?

鬟朱勦A<EFBFBD>?遘定カ<E5AE9A>慮鬲泌<E9ACB2>?<3F>櫨 Critical

髣ョ鬚<EFBFBD><EFBFBD>壻シ∽ク壼セョ菫。隕∵アり「ォ蜉ィ蝗槫、肴カ域<EFBFBD><EFBFBD>。サ蝨ィ**5遘貞<E98198>**螳梧<E89EB3>縲ょヲよ棡Node.js遲陰I隶。邂怜ョ悟<EFBDAE>return<72>御シ∝セョ譌ゥ蟾イ謠千、?譛榊苅證よ慮荳榊庄逕?蟷カ譁ュ蠑€霑樊磁縲? 髞呵ッッ蛛壽ウ<EFBFBD><EFBFBD>?```typescript 笶?async handleCallback(request, reply) { const answer = await callLLM(message); // 蜿ッ閭ス閠玲慮10遘? return reply.send(answer); // 雜<>慮莠<E685AE><EFBFBD> }


**豁」遑ョ蛛壽ウ<E5A3BD>**<2A>夐㊦逕?*蠑よュ・蝗槫、肴ィ。蠑<EFBDA1>**
```typescript
笨?async handleCallback(request, reply) {
  // 1. 遶句叉霑泌屓<E6B38C>?1遘抵シ<E68AB5>
  reply.send('success');
  
  // 2. 蠑よュ・螟<EFBDA5><EFBFBD>井ク埼仆蝪橸シ?  setImmediate(async () => {
    const answer = await callLLM(message); // 蜿ッ莉・諷「諷「邂?    await wechatService.sendTextMessage(userId, answer); // 荳サ蜉ィ謗ィ騾?  });
}

<EFBFBD>∩謗ェ譁ス<EFBFBD>壼惠Day 3蠑€蜿台クュ<EFBFBD>。サ菴ソ逕ィ蠑よュ・蝗槫、肴ィ。蠑擾シ檎ヲ∵ュ「蝨ィHTTP Response荳ュ逶エ謗・霑泌屓AI扈捺棡縲?

鬟朱勦B<EFBFBD>唸ML蜉<EFBFBD>隗」蟇?<3F>櫨 P0

髣ョ鬚<EFBFBD><EFBFBD>壻シ∽ク壼セョ菫。逧<EFBFBD>カ域<EFBFBD>菴捺弍<EFBFBD><EFBFBD>噪XML<EFBFBD><EFBFBD>ncrypt蟄玲ョオ<EFBFBD>会シ御ク肴弍譏取枚JSON縲りァ」蟇<EFBFBD>怙隕、ES邂玲ウ募柱螟肴揩逧Пadding隗<EFBFBD><EFBFBD>縲? 髞呵ッッ蛛壽ウ<EFBFBD><EFBFBD><EFBFBD>蟾ア蜀吝刈隗」蟇<EFBFBD>ョ玲ウ包シ域栫譏灘<EFBFBD>髞呻シ? 豁」遑ョ蛛壽ウ<EFBFBD><EFBFBD>壻スソ逕ィ螳俶婿蠎<EFBFBD>

npm install @wecom/crypto
import { WXBizMsgCrypt } from '@wecom/crypto';

const crypt = new WXBizMsgCrypt(
  WECHAT_TOKEN,              // 閾ェ螳壻ケ欝oken
  WECHAT_ENCODING_AES_KEY,   // 莨∝セョ蜷主床逕滓<E98095><E6BB93>?3菴搾シ<E690BE>
  WECHAT_CORP_ID
);

// 隗」蟇<EFBDA3>カ域<EFBDB6>
const decrypted = crypt.decrypt(encryptedXml);

<EFBFBD>∩謗ェ譁ス<EFBFBD>壼シコ蛻カ菴ソ逕ィ螳俶婿蠎難シ檎ヲ∵ュ「閾ェ蟾ア螳樒鴫蜉<EFBFBD>隗」蟇<EFBFBD>€?

鬟朱勦C<EFBFBD>唔P逋ス蜷榊黒髯仙<EFBFBD>?<3F>櫨 P0

髣ョ鬚<EFBFBD><EFBFBD>夊執蜿泡ccessToken譌カ<EFBFBD>御シ∽ク壼セョ菫。莨壽<EFBFBD>。鬪瑚ッキ豎よ擂貅蝕P縲? 邇ー迥カ<EFBFBD>售AE騾夊ソ⑮AT鄂大<EFBFBD>隶ソ髣ョ螟也ス<EFBFBD>

  • NAT鄂大<EFBFBD>IP<EFBFBD>啻182.92.176.14`
  • 莨∽ク壼セョ菫。驟咲スョ<EFBFBD>壽悴豺サ蜉<EFBFBD>蛻?莨∽ク壼庄菫。IP"蛻苓。ィ

蜷取棡<EFBFBD>壼ヲゆク埼<EFBFBD>鄂ョ<EFBFBD>携etAccessToken()莨壽冠60020髞呵ッッ

<EFBFBD>∩謗ェ譁ス<EFBFBD>?1. 逋サ蠖穂シ∽ク壼セョ菫。邂。逅<EFBDA1>錘蜿ー 2. 霑帛<E99C91>"蠎皮畑邂。逅<EFBDA1>" 竊?"IIT Manager Agent" 3. 謇セ蛻ー"莨∽ク壼庄菫。IP"驟咲スョ 4. 豺サ蜉<EFBDBB><E89C89>啻182.92.176.14`


鬟朱勦D<EFBFBD><EFBFBD>髞ョ隸榊源驟<EFBFBD> vs AI Agent 笞<><E7AC9E><EFBFBD> P2

髣ョ鬚<EFBFBD><EFBFBD>夂ョ€蜊慕噪蜈ウ髞ョ隸榊源驟搾シ<EFBFBD>if (msg.includes('豎<>€?))`<60>我ク肴弍AI Agent<6E>悟宵譏ッif-else譛コ蝎ィ莠コ縲? 豁」遑ョ蛛壽ウ<EFBFBD><EFBFBD>壻スソ逕ィLLM蛛壽э蝗セ蛻<EFBFBD>ア?```typescript // 笨?逵滓ュ」逧БI Agent const intent = await classifyIntent(userMessage); // 隹<>畑LLM switch(intent.type) { case 'query_weekly_summary': ... case 'query_patient_info': ... }


**隗<>∩謗ェ譁ス**<2A>壼惠Day 3荳句壕螳樒鴫蝓コ莠鮫LM逧<4D>э蝗セ隸<EFBDBE>悪縲?
---

## <20>噫 蝗帙€ay 3-4 蠑€蜿題ョ。蛻?
### Day 3<>壻シ∽ク壼セョ菫。髮<EFBDA1><E9ABAE><EFBFBD><EFBFBD>2026-01-03<30>?蟆乗慮<E4B997>解沐?
#### 蜃<><EFBFBD>キ・菴懶シ壻シ∽ク壼セョ菫。驟咲スョ譽€譟・<E8AD9F><EFBDA5>1蟆乗慮<E4B997>俄國<E4BF84>?蠢<>。サ蜈亥★

**莉サ蜉。0<EFBDA1>壻シ∽ク壼セョ菫。驟咲スョ螳梧紛諤ァ譽€譟?*

**驟咲スョ貂<EFBDAE>黒**<2A>?1. [ ] **莨∽ク壼庄菫。IP驟咲スョ** <20>櫨 Critical
   - 逋サ蠖穂シ∽ク壼セョ菫。邂。逅<EFBDA1>錘蜿ー
   - 蠎皮畑邂。逅<EFBDA1> 竊?IIT Manager Agent 竊?莨∽ク壼庄菫。IP
   - 豺サ蜉<EFBDBB><E89C89>啻182.92.176.14`<60><>AE NAT鄂大<E98482>IP<49>?   - 豬玖ッ包シ夊ー<E5A48A>畑getAccessToken<65>碁ェ瑚ッ∽ク肴<EFBDB8>?0020髞呵ッッ

2. [ ] **闔キ蜿胞ncodingAESKey** <20>櫨 Critical
   - 莨∽ク壼セョ菫。蜷主床 竊?蠎皮畑邂。逅<EFBDA1> 竊?IIT Manager Agent
   - 蠑€蜿題€<E9A18C>磁蜿?竊?謗・謾カ豸域<E8B1B8>
   - 轤ケ蜃サ"髫乗惻逕滓<E98095>"謖蛾聴<E89BBE>瑚執蜿?3菴喉ESKey
   - 螟榊宛菫晏ュ假シ育畑莠取カ域<EFBDB6>隗」蟇<EFBDA3><EFBFBD>

3. [ ] **隶セ鄂ョToken** <20>櫨 Critical
   - 閾ェ螳壻ケ我ク€荳ェToken<65>育畑莠守ュセ蜷埼ェ瑚ッ<E7919A><EFBFBD>
   - 蟒コ隶ョ<E99AB6>?2菴埼囂譛コ蟄礼ャヲ荳イ
   - 菫晏ュ伜芦邇ッ蠅<EFBDAF>序驥?
4. [ ] **驟咲スョ蝗櫁ーザRL**
   - URL<52>啻https://iit.xunzhengyixue.com/api/v1/iit/wechat/callback`
   - 鬪瑚ッゝoken縲・ncodingAESKey驟咲スョ豁」遑ョ

**邇ッ蠅<EFBDAF>序驥乗眠蠅<E79CA0>**<2A>?```env
# 莨∽ク壼セョ菫。驟咲スョ<EFBDBD>亥キイ譛会シ<E4BC9A>
WECHAT_CORP_ID=ww6ab493470ab4f377
WECHAT_AGENT_ID=1000002
WECHAT_CORP_SECRET=AZIVxMtoLb0rEszXS81e4dBRl-I9kgTjygIS0cFfENU

# 莨∽ク壼セョ菫。蜉<EFBDA1>隗」蟇<EFBDA3><E89F87>鄂ョ<E98482>域眠蠅橸シ解沐?WECHAT_TOKEN=your_32_char_random_token_here
WECHAT_ENCODING_AES_KEY=your_43_char_aes_key_from_wechat_console

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?IP逋ス蜷榊黒蟾イ驟咲スョ

  • 笨?EncodingAESKey蟾イ闔キ蜿門ケカ菫晏ュ<E6998F>
  • 笨?Token蟾イ隶セ鄂ョ蟷カ菫晏ュ<E6998F>
  • 笨?AccessToken蜿ッ莉・豁」蟶ク闔キ蜿厄シ域裏60020髞呵ッッ<EFBDAF>?

荳雁壕<EFBFBD>壻シ∽ク壼セョ菫。謗ィ騾∵恪蜉。<EFBFBD><EFBFBD>4蟆乗慮<EFBFBD>?

逶ョ譬<EFBFBD><EFBFBD>壼ョ梧<EFBFBD>莉晒ode.js蛻ー莨∽ク壼セョ菫。逧<EFBDA1>耳騾<E880B3>€

*莉サ蜉。1<EFBFBD><EFBFBD>蟒?WechatService.ts<74>?蟆乗慮<E4B997>?

<EFBFBD>サカ菴咲スョ<EFBFBD>啻backend/src/modules/iit-manager/services/WechatService.ts`

譬ク蠢<EFBFBD>粥閭ス<EFBFBD>?```typescript class WechatService { /**

  • 闔キ蜿泡ccess Token<65>亥クヲ郛灘ュ假シ? */ async getAccessToken(): Promise

/**

  • 蜿鷹€∵焚謐ョ蠖募<EFBFBD>騾夂衍 */ async sendDataEntryNotification(params: { userId: string; projectName: string; recordId: string; action: 'created' | 'updated'; fieldsSummary: string; }): Promise

/**

  • 蜿鷹€∵枚譛ャ豸域<EFBFBD><EFBFBD>€夂畑<EFBFBD>? */ async sendTextMessage(userId: string, content: string): Promise

/**

  • 蜿鷹€∝今迚<EFBFBD>カ域<EFBFBD><EFBFBD>€夂畑<EFBFBD>? */ async sendTextCard(params: { userId: string; title: string; description: string; url?: string; btntxt?: string; }): Promise }

**螳樒鴫隕∫せ**<2A>?- 笨?AccessToken郛灘ュ伜芦Postgres<65>?000遘定ソ<E5AE9A>悄譌カ髣エ<E9ABA3><EFBDB4>
- 笨?驥崎ッ墓惻蛻カ<E89BBB>?谺。驥崎ッ包シ梧欠謨ー騾€驕ソ<E9A995><EFBDBF>
- 笨?髞呵ッッ螟<EFBDAF>炊蜥梧律蠢苓ョー蠖?- 笨?謾ッ謖∵枚譛ャ豸域<E8B1B8>蜥悟今迚<E4BB8A>カ域<EFBDB6>?
**鬪梧噺譬<E599BA>㊥**<2A>?- 笨?AccessToken蜿ッ莉・豁」遑ョ闔キ蜿門柱郛灘ュ?- 笨?蜿ッ莉・蜿鷹€∵枚譛ャ豸域<E8B1B8>蛻ー謖<EFBDB0>ョ夂畑謌キ
- 笨?蜿ッ莉・蜿鷹€∝今迚<E4BB8A>カ域<EFBDB6>?- 笨?郛灘ュ俶惻蛻カ豁」蟶ク蟾・菴<EFBDA5>

---

**莉サ蜉。2<EFBDA1>壼ョ悟<EFBDAE>?iit_quality_check Worker<65>?蟆乗慮<E4B997>?*

**譁<>サカ菴咲スョ**<2A>啻backend/src/modules/iit-manager/index.ts`

**蠖灘燕迥カ諤?*<2A>啗orker蟾イ豕ィ蜀鯉シ御ス<E5BEA1>€サ霎台クコ遨コ<E981A8>郁ソ泌屓pending_implementation<6F>?
**譖エ譁ー蜀<EFBDB0>ョケ**<2A>?```typescript
jobQueue.process('iit_quality_check', async (job) => {
  const { projectId, recordId, recordData, instrument } = job.data;
  
  try {
    // 1. 闔キ蜿夜。ケ逶ョ驟咲スョ
    const project = await prisma.projects.findUnique({
      where: { id: projectId }
    });

    // 2. 譫<>€<EFBFBD>謨ー謐ョ鞫倩ヲ?    const fieldsList = Object.keys(recordData);
    const summary = `蠖募<E8A096>${fieldsList.length}荳ェ蟄玲ョオ`;

    // 3. 蜿鷹€∽シ∽ク壼セョ菫。騾夂衍
    const wechatService = new WechatService();
    await wechatService.sendDataEntryNotification({
      userId: 'GaoFeng', // TODO: 莉朱。ケ逶ョ驟咲スョ荳ュ闔キ蜿<EFBDB7>
      projectName: project.name,
      recordId,
      action: instrument === 'demographics' ? 'created' : 'updated',
      fieldsSummary: summary
    });

    // 4. 隶ー蠖募ョ。隶。譌・蠢<EFBDA5>
    await prisma.auditLogs.create({
      data: {
        projectId,
        actionType: 'WECHAT_NOTIFICATION_SENT',
        entityId: recordId,
        details: { 
          recordId, 
          instrument,
          fieldCount: fieldsList.length,
          notified: true 
        }
      }
    });

    logger.info('Wechat notification sent', { 
      recordId, 
      instrument,
      fieldCount: fieldsList.length 
    });

    return { success: true, notified: true };

  } catch (error: any) {
    logger.error('Wechat notification failed', { 
      recordId,
      error: error.message 
    });
    throw error;
  }
});

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?Worker蜿ッ莉・豁」蟶ク謇ァ陦<EFBDA7>

  • 笨?莨∽ク壼セョ菫。騾夂衍蜿鷹€<C280>蜉?- 笨?螳。隶。譌・蠢玲ュ」遑ョ隶ー蠖<EFBDB0>
  • 笨?髞呵ッッ螟<EFBDAF>炊螳悟埋

*莉サ蜉。3<EFBFBD>夂ォッ蛻ー遶ッ豬玖ッ包シ?蟆乗慮<E4B997>?

豬玖ッ募惻譎ッ1<EFBFBD>壽焚謐ョ蠖募<EFBFBD>騾夂衍

謫堺ス懶シ壼惠REDCap荳ュ譁ー蠅櫁ョー蠖肘D 8
鬚<><EFBFBD>?1. DET螳樊慮隗ヲ蜿托シ?遘貞サカ霑滂シ<E6BB82>
2. WebhookController謗・謾カ<E8ACBE>?10ms蜩榊コ費シ?3. Worker謇ァ陦鯉シ?遘貞<E98198><E8B29E>?4. 莨∽ク壼セョ菫。謾カ蛻ー騾夂衍<E5A482>?遘貞<E98198><E8B29E>?```

**豬玖ッ募惻譎ッ2<EFBDAF>壽焚謐ョ譖エ譁ー騾夂衍**

謫堺ス懶シ壼惠REDCap荳ュ菫ョ謾ケ隶ー蠖肘D 2 鬚<><EFBFBD>?1. DET螳樊慮隗ヲ蜿<EFBDA6> 2. 莨∽ク壼セョ菫。謾カ蛻ー譖エ譁ー騾夂衍 3. 騾夂衍蜀<E8A18D>ョケ蛹<EFBDB9>性菫ョ謾ケ逧<EFBDB9>ュ玲ョオ菫。諱?```

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?螳梧紛髣ュ邇ッ<E98287><EFBDAF>EDCap 竊?Node.js 竊?莨∝セョ<EFBDBE>画遠騾?- 笨?蜩榊コ疲慮髣エ<5遘?- 笨?騾夂衍蜀<E8A18D>ョケ蜃<EFBDB9>。ョ

  • 笨?螳。隶。譌・蠢怜ョ梧紛

荳句壕<EFBFBD>壻シ∽ク壼セョ菫。蟇ケ隸晄磁謾カ<EFBFBD><EFBFBD>4蟆乗慮<EFBFBD>?

逶ョ譬<EFBFBD><EFBFBD>壼ョ樒鴫PI蝨ィ莨∽ク壼セョ菫。荳ュ荳拶I Agent蟇ケ隸<EFBDB9>

*莉サ蜉。4<EFBFBD>壼ョ芽」<EFBFBD>ケカ驟咲スョ豸域<EFBFBD>隗」蟇<EFBFBD>コ難シ<EFBFBD>15蛻<EFBFBD><EFBFBD>?

cd backend
npm install @wecom/crypto
npm install xml2js  # XML隗」譫<EFBDA3>

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?萓晁オ門ョ芽」<E88ABD><EFBDA3><EFBFBD>

  • 笨?蜿ッ莉・import謌仙粥

莉サ蜉。5<EFBFBD><EFBFBD>蟒?WechatCallbackController.ts<74>?.5蟆乗慮<EFBFBD>解沐?蜈ウ髞ョ

<EFBFBD>サカ菴咲スョ<EFBFBD>啻backend/src/modules/iit-manager/controllers/WechatCallbackController.ts`

譬ク蠢<EFBFBD>粥閭ス<EFBFBD>?*蠑よュ・蝗槫、肴ィ。蠑<EFBDA1>**<2A>会シ<E4BC9A>

import { WXBizMsgCrypt } from '@wecom/crypto';
import { parseString } from 'xml2js';

class WechatCallbackController {
  private crypt: WXBizMsgCrypt;
  
  constructor() {
    this.crypt = new WXBizMsgCrypt(
      process.env.WECHAT_TOKEN!,
      process.env.WECHAT_ENCODING_AES_KEY!,
      process.env.WECHAT_CORP_ID!
    );
  }

  /**
   * 鬪瑚ッ∽シ∽ク壼セョ菫。遲セ蜷搾シ<E690BE>ET隸キ豎ゑシ?   * 莨∽ク壼セョ菫。鬥匁ャ。驟咲スョ蝗櫁ーザRL譌カ莨壼書騾<E69BB8>ェ瑚ッ∬ッキ豎?   */
  async verifyCallback(request: any, reply: any): Promise<any> {
    const { msg_signature, timestamp, nonce, echostr } = request.query;
    
    try {
      // 鬪瑚ッ∫ュセ蜷榊ケカ隗」蟇<EFBDA3>chostr
      const decrypted = this.crypt.verifyURL(
        msg_signature,
        timestamp,
        nonce,
        echostr
      );
      
      logger.info('Wechat callback URL verified');
      return reply.send(decrypted);
      
    } catch (error: any) {
      logger.error('Wechat callback verification failed', { error: error.message });
      return reply.code(403).send('Verification failed');
    }
  }

  /**
   * 謗・謾カ莨∽ク壼セョ菫。逕ィ謌キ豸域<E8B1B8><E59F9F><EFBFBD>OST隸キ豎ゑシ?   * <20>櫨 蜈ウ髞ョ<E9AB9E>壼ソ<E5A3BC>。サ蝨ィ5遘貞<E98198>霑泌屓<E6B38C>御スソ逕ィ蠑よュ・螟<EFBDA5><E89E9F>?   */
  async handleCallback(request: any, reply: any): Promise<any> {
    const { msg_signature, timestamp, nonce } = request.query;
    const encryptedXml = request.body;

    try {
      // 1. 隗」蟇<EFBDA3>カ域<EFBDB6>菴?      const decryptedXml = this.crypt.decrypt(
        msg_signature,
        timestamp,
        nonce,
        encryptedXml
      );

      // 2. 隗」譫森ML
      const message = await this.parseXML(decryptedXml);
      const { FromUserName, Content, MsgId, MsgType } = message;

      logger.info('Wechat message received', { 
        userId: FromUserName, 
        msgType: MsgType,
        msgId: MsgId 
      });

      // 3. <20>櫨 遶句叉霑泌屓'success'<27>?1遘抵シ<E68AB5>
      reply.send('success');

      // 4. <20>櫨 蠑よュ・螟<EFBDA5><EFBFBD>井ク埼仆蝪橸シ悟庄莉・諷「諷「邂暦シ?      if (MsgType === 'text') {
        setImmediate(async () => {
          try {
            // 蜿ッ閭ス閠玲慮5-10遘?            const answer = await this.processUserMessage(FromUserName, Content);
            
            // 菴ソ逕ィ荳サ蜉ィ謗ィ騾∵磁蜿」霑泌屓扈捺<E68988>?            const wechatService = new WechatService();
            await wechatService.sendTextMessage(FromUserName, answer);
            
            // 隶ー蠖募ョ。隶。譌・蠢<EFBDA5>
            await this.logInteraction(MsgId, FromUserName, Content, answer);
            
          } catch (error: any) {
            logger.error('Async message processing failed', { 
              msgId: MsgId,
              error: error.message 
            });
            
            // 蜿鷹€<E9B7B9>漠隸ッ謠千、?            await wechatService.sendTextMessage(
              FromUserName,
              '謚ア豁会シ悟、<E6829F>炊謔ィ逧<EFBDA8>カ域<EFBDB6>譌カ蜃コ髞吩コ<E590A9>シ瑚ッキ遞榊錘驥崎ッ輔€?
            );
          }
        });
      }

      return; // 蟾イ扈剰ソ泌屓霑?success'?
    } catch (error: any) {
      logger.error('Wechat callback failed', { error: error.message });
      return reply.code(500).send('Internal error');
    }
  }

  /**
   * 螟<>炊逕ィ謌キ豸域<E8B1B8><E59F9F>芋沐?菴ソ逕ィLLM蛛壽э蝗セ隸<EFBDBE><EFBFBD>€碁撼蜈ウ髞ョ隸榊源驟搾シ<E690BE>
   */
  private async processUserMessage(
    userId: string, 
    message: string
  ): Promise<string> {
    // 1. 隹<>畑LLM蛛壽э蝗セ隸<EFBDBE><E99AB8>?    const intent = await this.classifyIntent(message);
    
    logger.info('Intent classified', { userId, intent });

    // 2. 譬ケ謐ョ諢丞崟謇ァ陦悟ッケ蠎疲桃菴<E6A183>
    try {
      switch(intent.type) {
        case 'query_weekly_summary':
          return await this.getWeeklySummary(intent.params);
        
        case 'query_patient_info':
          return await this.getPatientInfo(intent.params.recordId);
        
        case 'query_project_stats':
          return await this.getProjectStats(intent.params.projectId);
        
        case 'unknown':
        default:
          return this.getHelpMessage();
      }
    } catch (error: any) {
      logger.error('Query execution failed', { intent, error: error.message });
      throw error;
    }
  }

  /**
   * <20>櫨 菴ソ逕ィLLM蛛壽э蝗セ蛻<EFBDBE>アサ<EFBDB1>育悄豁」逧БI Agent<6E>?   */
  private async classifyIntent(message: string): Promise<{
    type: string;
    params: any;
  }> {
    const prompt = `
<EFBFBD>譏ッ荳€荳ェ諢丞崟蛻<EFBFBD>アサ蝎ィ縲ら畑謌キ隸エ<EFBFBD>?${message}"

隸キ蛻、譁ュ逕ィ謌キ逧<EFBFBD>э蝗セ蟷カ謠仙叙蜿よ焚<EFBFBD>瑚ソ泌屓JSON譬シ蠑擾シ?
諢丞崟邀サ蝙具シ?- query_weekly_summary: 譟・隸「譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€?- query_patient_info: 譟・隸「謔」閠<EFBDA3>ソ。諱?- query_project_stats: 譟・隸「鬘ケ逶ョ扈溯ョ。
- unknown: 譌<>豕戊ッ<E6888A>
遉コ萓具シ?逕ィ謌キ<E8AC8C>?逵狗恚霑吝捉譛画イ。譛画眠逞<E79CA0>ココ<EFBDBA>?
霑泌屓<EFBFBD>嘴"type": "query_weekly_summary", "params": {"timeRange": "this_week"}}

逕ィ謌キ<EFBFBD>?謔」閠?逧<>ュ蜀オ諤惹ケ域<EFBDB9><EFBFBD><EFBDB7>"
霑泌屓<EFBFBD>嘴"type": "query_patient_info", "params": {"recordId": "8"}}

逕ィ謌キ<EFBFBD>?鬘ケ逶ョ霑帛コヲ螯ゆス包シ?
霑泌屓<EFBFBD>嘴"type": "query_project_stats", "params": {}}

隸キ霑泌屓JSON<EFBFBD>?    `.trim();

    try {
      // 隹<>畑DeepSeek API<50><EFBFBD>蜈カ莉豊LM<4C>?      const response = await this.callLLM(prompt);
      const intent = JSON.parse(response);
      
      return intent;
      
    } catch (error: any) {
      logger.error('Intent classification failed', { 
        message,
        error: error.message 
      });
      
      // 髯咲コァ<EFBDBA>夊ソ泌屓unknown
      return { type: 'unknown', params: {} };
    }
  }

  /**
   * 隹<>畑LLM API
   */
  private async callLLM(prompt: string): Promise<string> {
    // TODO: 螳樒鴫DeepSeek API隹<49>    // 證よ慮霑泌屓mock謨ー謐ョ逕ィ莠取オ玖ッ<E78E96>
    
    // 邂€蜊慕噪蜈ウ髞ョ隸榊源驟堺ス應クコfallback
    if (prompt.includes('荳€蜻?) || prompt.includes('<EFBFBD>€?)) {
      return JSON.stringify({ 
        type: 'query_weekly_summary', 
        params: { timeRange: 'this_week' } 
      });
    }
    
    const patientMatch = prompt.match(/謔」閠?\d+)/);
    if (patientMatch) {
      return JSON.stringify({ 
        type: 'query_patient_info', 
        params: { recordId: patientMatch[1] } 
      });
    }
    
    if (prompt.includes('霑帛コヲ') || prompt.includes('扈溯ョ。')) {
      return JSON.stringify({ 
        type: 'query_project_stats', 
        params: {} 
      });
    }
    
    return JSON.stringify({ type: 'unknown', params: {} });
  }

  /**
   * 闔キ蜿匁怙霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€?   */
  private async getWeeklySummary(params: any): Promise<string>

  /**
   * 闔キ蜿匁ぅ閠<E38185>ソ。諱?   */
  private async getPatientInfo(recordId: string): Promise<string>

  /**
   * 闔キ蜿夜。ケ逶ョ扈溯ョ。
   */
  private async getProjectStats(projectId: string): Promise<string>

  /**
   * 蟶ョ蜉ゥ豸域<E8B1B8>
   */
  private getHelpMessage(): string {
    return `謔ィ螂ス<E89E82><EFBFBD>譏ッIIT Manager AI蜉ゥ謇<EFBDA9> <20><EFBFBD>

謔ィ蜿ッ莉・霑呎<EFBFBD>キ髣ョ謌托シ<EFBFBD>
<EFBFBD>投 "譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€?
<EFBFBD>側 "譟・隸「謔」閠?逧<>ュ蜀?
<EFBFBD>嶋 "鬘ケ逶ョ霑帛コヲ螯ゆス<E38286>"

謌台シ壼ース蜉帛クョ蜉ゥ謔ィ<EFBFBD>;
  }

  /**
   * 隗」譫森ML豸域<E8B1B8>
   */
  private async parseXML(xml: string): Promise<any> {
    return new Promise((resolve, reject) => {
      parseString(xml, { explicitArray: false }, (err, result) => {
        if (err) reject(err);
        else resolve(result.xml);
      });
    });
  }

  /**
   * 隶ー蠖穂コ、莠呈律蠢<E5BE8B>
   */
  private async logInteraction(
    msgId: string,
    userId: string,
    userMessage: string,
    botResponse: string
  ): Promise<void> {
    await prisma.auditLogs.create({
      data: {
        actionType: 'WECHAT_USER_MESSAGE',
        entityId: userId,
        details: {
          msgId,
          userMessage,
          botResponse,
          timestamp: new Date()
        }
      }
    });
  }
}

螳樒鴫隕∫せ<EFBFBD><EFBFBD>髞ョ菫ョ豁」<EFBFBD><EFBFBD><EFBFBD>?- 笨?菴ソ逕ィ @wecom/crypto 隗」蟇<EFBDA3>カ域<EFBDB6><E59F9F>井ク崎<EFBDB8>蟾ア螳樒鴫<E6A892>?- 笨?遶句叉霑泌屓'success'<27>?1遘抵シ碁∩蜈<E288A9>5遘定カ<E5AE9A><EFBFBD><E685AE>

  • 笨?菴ソ逕ィ setImmediate 蠑よュ・螟<EFBDA5>
  • 笨?菴ソ逕ィ荳サ蜉ィ謗ィ騾∵磁蜿」霑泌屓扈捺<E68988>?- 笨?菴ソ逕ィLLM蛛壽э蝗セ蛻<EFBDBE>アサ<EFBDB1>€碁撼蜈ウ髞ョ隸榊源驟搾シ<E690BE>
  • 笨?螳悟埋逧<E59F8B>漠隸ッ螟<EFBDAF>炊蜥梧律蠢苓ョー蠖<EFBDB0>

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?莨∽ク壼セョ菫。蝗櫁ーザRL鬪瑚ッ<E7919A>€夊ソ<E5A48A>

  • 笨?蜿ッ莉・謗・謾カ蟷カ隗」蟇<EFBDA3>畑謌キ豸域<E8B1B8>?- 笨?蜩榊コ疲慮髣エ<1遘抵シ亥シよュ・螟<EFBDA5><EFBFBD>?- 笨?LLM諢丞崟隸<E5B49F>悪豁」遑ョ邇?80%
  • 笨?蜿ッ莉・豁」遑ョ霑泌屓譟・隸「扈捺棡

*莉サ蜉。6<EFBFBD>壽ウィ蜀御シ∽ク壼セョ菫。蝗櫁ー<EFBFBD>キッ逕ア<EFBFBD><EFBFBD>30蛻<EFBFBD><EFBFBD>?

<EFBFBD>サカ菴咲スョ<EFBFBD>啻backend/src/modules/iit-manager/routes/index.ts`

譁ー蠅櫁キッ逕ア<EFBFBD>?```typescript const wechatCallbackController = new WechatCallbackController();

// 莨∽ク壼セョ菫。蝗櫁ー<E6AB81>ェ瑚ッ<E7919A><EFBFBD>ET<45>?fastify.get( '/api/v1/iit/wechat/callback', wechatCallbackController.verifyCallback.bind(wechatCallbackController) );

// 莨∽ク壼セョ菫。豸域<E8B1B8>謗・謾カ<E8ACBE><EFBDB6>OST<53>?fastify.post( '/api/v1/iit/wechat/callback', { schema: { body: { type: 'object' } } }, wechatCallbackController.handleCallback.bind(wechatCallbackController) );

logger.info('Registered route: GET/POST /api/v1/iit/wechat/callback');


**鬪梧噺譬<E599BA>㊥**<2A>?- 笨?霍ッ逕ア豕ィ蜀梧<E89C80><EFBFBD>
- 笨?GET隸キ豎ょ庄莉・鬪瑚ッ∫ュセ蜷<EFBDBE>
- 笨?POST隸キ豎ょ庄莉・謗・謾カ豸域<E8B1B8>

---

**莉サ蜉。7<EFBDA1>壼ッケ隸晏粥閭ス豬玖ッ包シ<E58C85>1蟆乗慮<E4B997>?*

**豬玖ッ募惻譎ッ1<EFBDAF>壽怙霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€?*

謫堺ス懶シ壼惠莨∽ク壼セョ菫。荳ュ蜿鷹€<EFBFBD><EFBFBD>"譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€? 鬚<><EFBFBD>?AI Agent蝗槫、搾シ?"<22>投 譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€<C280><EFBDBB> 譁ー蠅槫女隸戊€<E6888A><EFBFBD>2萓?謨ー謐ョ譖エ譁ー<E8AD81>?谺?諤サ隶。<E99AB6>?譚。謫堺ス懆ョー蠖?


**豬玖ッ募惻譎ッ2<EFBDAF>壽ぅ閠<E38185>ソ。諱ッ譟・隸?*

謫堺ス懶シ壼惠莨∽ク壼セョ菫。荳ュ蜿鷹€<EFBFBD><EFBFBD>"譟・隸「謔」閠?逧<>ュ蜀? 鬚<><EFBFBD>?AI Agent蝗槫、搾シ?"<22>搭 謔」閠?4 蝓コ譛ャ菫。諱ッ<E8ABB1>?蟋灘錐<E78198>嗾est 4 test 4 蟷エ鮴<EFBDB4>シ?8蟯?諤ァ蛻ォ<E89BBB>夂塙 BMI<4D>?8.3 蠖募<E8A096>迥カ諤<EFBDB6>シ壼キイ螳梧<E89EB3>?


**豬玖ッ募惻譎ッ3<EFBDAF>夐。ケ逶ョ霑帛コヲ譟・隸?*

謫堺ス懶シ壼惠莨∽ク壼セョ菫。荳ュ蜿鷹€<EFBFBD><EFBFBD>"鬘ケ逶ョ霑帛コヲ" 鬚<><EFBFBD>?AI Agent蝗槫、搾シ?"<22>投 test0102 鬘ケ逶ョ扈溯ョ。<EFBDAE>?諤サ蜿苓ッ戊€<E6888A><EFBFBD>?萓?譛ャ蜻ィ譁ー蠅橸シ?萓?謨ー謐ョ螳梧紛邇<E7B49B><EFBFBD>87.5%"


**鬪梧噺譬<E599BA>㊥**<2A>?- 笨?3荳ェ豬玖ッ募惻譎ッ蜈ィ驛ィ騾夊ソ<E5A48A>
- 笨?蝗槫、榊<EFBDA4>螳ケ蜃<EFBDB9>。ョ
- 笨?蜩榊コ疲慮髣エ<3遘?- 笨?髞呵ッッ螟<EFBDAF>炊蜿句・ス

---

### <20>投 Day 3 螳梧<E89EB3>諤サ扈難シ?026-01-03<30>俄怛

**螳樣刔螳梧<E89EB3>譌カ髣エ**<2A>?026-01-03  
**莉サ蜉。螳梧<E89EB3>蠎?*<2A>?00%

#### 譬ク蠢<EFBDB8><E8A0A2><EFBFBD>

| 莠、莉倡<E88E89>?| 莉」遐<EFBDA3><E98190>?| 迥カ諤?|
|-------|--------|------|
| WechatService<63>井シ∽ク壼セョ菫。謗ィ騾<EFBDA8><EFBFBD> | 314陦?| 笨?螳梧<E89EB3> |
| WechatCallbackController<65>亥屓隹<E5B193><EFBFBD><EFBFBD><E7828A> | 501陦?| 笨?螳梧<E89EB3> |
| 雍ィ謗ァWorker螳悟埋 | 336陦?| 笨?螳梧<E89EB3> |
| Worker豕ィ蜀御ソョ螟搾シ<E690BE>initIitManager`<60>?| - | 笨?螳梧<E89EB3> |
| 謨ー謐ョ蠎灘ュ玲ョオ菫ョ螟搾シ<E690BE>action_type`<60>?| - | 笨?螳梧<E89EB3> |
| 遶ッ蛻ー遶ッ豬玖ッ?| - | 笨?騾夊ソ<E5A48A> |
| WECHAT_ENV_CONFIG.md | 401陦?| 笨?螳梧<E89EB3> |
| **諤サ隶。** | **1,755陦?* | **笨?螳梧<E89EB3>** |

#### 蜈ウ髞ョ驥檎ィ狗「?
<0A>識 **MVP髣ュ邇ッ螳悟<E89EB3>謇馴€?*<2A>?```
REDCap蠖募<E8A096>謨ー謐ョ 竊?Node.js螳樊慮謐戊執<E6888A>?10ms<6D>?                竊?Worker螟<72><EFBFBD><E7828A>50ms<6D>?                竊?莨∽ク壼セョ菫。謗ィ騾<EFBDA8>€夂衍<E5A482>?2遘抵シ<E68AB5>
                竊?謇区惻遶ッ謗・謾カ笨<EFBDB6>

諤ァ閭ス謖<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD> 逶ョ譬<EFBFBD> 螳樣刔 迥カ諤?
Webhook蜩榊コ疲慮髣エ <10ms 5.8ms 笨?雜<><E99B9C><EFBFBD>
Worker謇ァ陦梧慮髣エ <100ms ~50ms 笨?雜<><E99B9C><EFBFBD>
遶ッ蛻ー遶ッ蟒カ霑? <5遘? <2遘? 笨?雜<><E99B9C><EFBFBD>
豸域<EFBFBD>蜿鷹€<EFBFBD>蜉溽紫 >99% 100% 笨?雜<><E99B9C><EFBFBD>

豬玖ッ暮ェ瑚ッ<EFBFBD>

**遶ッ蛻ー遶ッ豬玖ッ?*<2A>亥キイ騾夊ソ<E5A48A>シ会シ<E4BC9A>

  • 笨?REDCap蛻帛サコ隶ー蠖<EFBDB0> ID 9
  • 笨?DET螳樊慮隗ヲ蜿托シ?遘貞サカ霑滂シ<E6BB82>
  • 笨?Webhook謗・謾カ<E8ACBE>?.8ms蜩榊コ費シ?- 笨?莉サ蜉。謗ィ騾∝芦pg-boss髦溷<E9ABA6>
  • 笨?Worker謇ァ陦瑚エィ謗ァ譽€譟?- 笨?蜿鷹€∽シ∽ク壼セョ菫。騾夂衍
  • 笨?謇区惻遶ッ謌仙粥謗・謾カ騾夂衍
  • 笨?螳。隶。譌・蠢苓ョー蠖墓<E8A096><EFBFBD>
  • 笨?譌<>蠕ェ邇ッ蜿鷹€<E9B7B9>琉鬚? **莨∽ク壼セョ菫。謗ィ騾∵オ玖ッ?*<2A>亥キイ騾夊ソ<E5A48A>シ会シ<E4BC9A>
  • 笨?譁<>悽豸域<E8B1B8>謗ィ騾∵<E9A8BE>蜉?- 笨?Textcard蜊。迚<EFBDA1>カ域<EFBDB6>謗ィ騾∵<E9A8BE>蜉?- 笨?Markdown豸域<E8B1B8>謗ィ騾∵<E9A8BE>蜉?- 笨?謇区惻遶ッ蜈ィ驛ィ謗・謾カ豁」蟶?

謚€譛ッ莠ョ轤?

  1. 蠑よュ・Worker譫カ譫<EFBFBD><EFBFBD>夂ャヲ蜷<EFBFBD>ostgres-Only譛€菴ウ闌<EFBDB3>シ?2. **莨∽ク壼セョ菫。豸域<E8B1B8><EFBFBD>隗」蟇?*<2A>壼ョ梧紛螳樒鴫遲セ蜷埼ェ瑚ッ∝柱蜉<E69FB1>隗」蟇?3. 蠑よュ・蝗槫、肴ィ。蠑<EFBFBD><EFBFBD>啻setImmediate` 遑ョ菫<EFBDAE>5遘貞<E98198>蜩榊コ<E6A68A>
  2. **螳梧紛逧<E7B49B>漠隸ッ螟<EFBDAF><E89E9F>?*<2A>壼ョ。隶。譌・蠢怜、ア雍・荳榊スア蜩堺クサ豬∫ィ?5. pg-boss驥崎ッ墓惻蛻カ<EFBFBD><EFBFBD>蜉ィ驥崎ッ?谺。<E8B0BA>檎。ョ菫晏庄髱<E5BA84>諤?

荳エ譌カ謗ェ譁ス荳取橿譛ッ蛟コ蜉。

蠎丞捷 荳エ譌カ謗ェ譁ス 謾ケ霑幄ョ。蛻<EFBFBD>
1 UserID遑ャ郛也<EFBFBD><EFBFBD>シ育識蠅<EFBFBD>序驥擾シ? Phase 2: 莉朱。ケ逶ョ驟咲スョ陦ィ隸サ蜿<EFBDBB>
2 螳壽慮霓ョ隸「遖∫畑 Phase 2: 菴ソ逕ィnode-cron謌匁黄螻姫gBossQueue
3 雍ィ謗ァ騾サ霎醍ョ€蛹厄シ域裏AI<EFBFBD>? Phase 1.5: 髮<><E9ABAE>Dify RAG
4 notification_config蟄玲ョオ譛ェ蛻帛サ? Phase 2: 豺サ蜉<EFBDBB>JSONB蟄玲ョオ
5 Access Token蜀<6E>ュ倡シ灘ュ<E78198> Phase 2: 菴ソ逕ィRedis謌匁焚謐ョ蠎<EFBDAE>

髣ョ鬚倅ク手ァ」蜀?

  1. **Worker譛ェ豕ィ蜀?*<2A>啻initIitManager() 譛ェ隹<EFBDAA><E99AB9>?竊?蝨?src/index.ts 荳ュ豺サ蜉<EFBDBB><EFBFBD><E99AB9>?2. **蟄玲ョオ蜷埼漠隸?*<2A>啻action 竊?action_type<EFBFBD>?螟<>ソョ螟搾シ<E690BE>
  2. **蠕ェ邇ッ蜿鷹€?*<2A>壼ョ。隶。譌・蠢鈴漠隸ッ蟇シ閾エWorker螟ア雍・驥崎ッ<E5B48E> 竊?豺サ蜉<EFBDBB>try-catch
  3. **notification_config荳榊ュ伜<EFBFBD>?*<2A>夂ァサ髯、蟄玲ョオ譟・隸「<E99AB8>檎峩謗・菴ソ逕ィ邇ッ蠅<EFBDAF>序驥<E5BA8F>

蜿り€<EFBFBD>枚譯?

  • 06-蠑€蜿題ョー蠖?Day3-莨∽ク壼セョ菫。髮<EFBDA1><E9ABAE>荳守ォッ蛻ー遶ッ豬玖ッ募ョ梧<EFBDAE>隶ー蠖<EFBDB0>.md
  • backend/WECHAT_ENV_CONFIG.md

<EFBFBD>投 Phase 1.5<EFBFBD>哂I蟇ケ隸晁<EFBFBD>蜉幢シ?026-01-03 & 2026-01-04<30>俄怛

莉サ蜉。逶ョ譬<EFBFBD><EFBFBD>壼惠莨∽ク壼セョ菫。荳ュ螳樒鴫AI蟇ケ隸晄衍隸「閭ス蜉<EFBFBD>

螳樣刔螳梧<EFBFBD>譌カ髣エ<EFBFBD>?- Day 3 荳句壕<E58FA5>?026-01-03<30>会シ壼渕遑€蟇ケ隸<EFBDB9> + REDCap髮<70><E9ABAE>

  • Day 4 荳雁壕<E99B81>?026-01-04<30>会シ咼ify遏・隸<EFBDA5>コ馴寔謌? **莉サ蜉。螳梧<E89EB3>蠎?*<2A>?00%

譬ク蠢<EFBFBD><EFBFBD>譫懶シ<EFBFBD>hase 1.5<EFBFBD>?

莠、莉倡<EFBFBD>? 莉」遐<EFBFBD><EFBFBD>? 迥カ諤?
ChatService.ts<74>亥ッケ隸晄恪蜉。<E89C89><EFBDA1> 485陦? 笨?螳梧<E89EB3>
SessionMemory.ts<74>井シ夊ッ晁ョー蠢<EFBDB0><EFBFBD> 120陦? 笨?螳梧<E89EB3>
WechatCallbackController<EFBFBD>亥ッケ隸晞寔謌撰シ<EFBFBD> 譖エ譁ー 笨?螳梧<E89EB3>
Dify遏・隸<EFBFBD>コ灘<EFBFBD>閨? 閼壽悽 笨?螳梧<E89EB3>
諢丞崟隸<EFBFBD>悪莨伜喧 謇ゥ螻<EFBFBD> 笨?螳梧<E89EB3>
Bug菫ョ螟搾シ亥ュ玲ョオ霍ッ蠕<EFBFBD><EFBFBD> 蜈ウ髞ョ菫ョ螟<EFBFBD> 笨?螳梧<E89EB3>
<EFBFBD>ッ戊<EFBFBD>譛ャ<EFBFBD>?荳ェ<E88DB3><EFBDAA> 280陦? 笨?螳梧<E89EB3>
蠑€蜿題ョー蠖墓枚譯? 600+陦? 笨?螳梧<E89EB3>
諤サ隶。 *~1,485陦? 笨?螳梧<E89EB3>

蜈ウ髞ョ驥檎ィ狗「?

<EFBFBD>識 **豺キ蜷域」€邏「譫カ譫<EFBDB6>ョ樒<EFBDAE>?*<2A>?``` 逕ィ謌キ謠宣琉<E5AEA3>井シ∽ク壼セョ菫。<E88FAB><EFBDA1> 竊?諢丞崟隸<E5B49F><EFBFBD><E682AA>hatService.detectIntent<6E>? 竊?笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?query_protocol笏?query_record 笏?count_records笏?笏? (譁<>。」譟・隸「) 笏? (隶ー蠖墓衍隸「) 笏? (扈溯ョ。譟・隸「) 笏?笏披楳笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏エ笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏エ笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏? 竊? 竊? 竊? Dify API REDCap API REDCap API (遏・隸<EFBDA5>コ? (謔」閠<EFBDA3>焚謐? (謔」閠<EFBDA3>焚謐? 竊? 竊? 竊? 譁<>。」迚<EFBDA3>ョオ JSON謨ー謐ョ JSON謨ー謐ョ 竊? 竊? 竊? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏エ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏? 竊? 譫<>サコLLM Prompt (System + Context + Data) 竊? DeepSeek-V3 竊? AI蝗樒ュ<E6A892>


#### 蜉溯<E89C89>鬪瑚ッ<E7919A>

**豬玖ッ暮。ケ逶ョ**: test0102
- REDCap PID: 16, 11譚。隶ー蠖?- Dify Dataset ID: `b49595b2-bf71-4e47-9988-4aa2816d3c6f`
- 譁<>。」: 遐皮ゥカ譁ケ譯医€RF陦ィ譬シ<E8ADAC>?荳ェ譁<EFBDAA>サカ<EFBDBB>悟キイ螟<EFBDB2><EFBFBD><E7828A>

**豬玖ッ募惻譎ッ**<2A>?
| 蝨コ譎ッ | 逕ィ謌キ髣ョ鬚<EFBDAE> | 謨ー謐ョ貅?| 扈捺棡 | 迥カ諤?|
|------|---------|--------|------|------|
| 譁<>。」譟・隸「 | "霑吩クェ遐皮ゥカ逧<EFBDB6>賜髯、譬<EFBDA4>㊥譏ッ莉€荵茨シ<E88CA8>" | Dify | 蝓コ莠取枚譯」蜃<EFBDA3>。ョ蝗樒ュ<E6A892> | 笨?騾夊ソ<E5A48A> |
| CRF譟・隸「 | "CRF陦ィ譬シ荳ュ譛牙頭莠幄ァょッ滓欠譬<E6ACA0>シ? | Dify | 蝓コ莠取枚譯」蜃<EFBDA3>。ョ蝗樒ュ<E6A892> | 笨?騾夊ソ<E5A48A> |
| 謔」閠<EFBDA3>衍隸?| "ID 7逧<37>ぅ閠<E38185>ュ蜀? | REDCap | 螳悟<E89EB3>蛹ケ驟咲悄螳樊焚謐ョ | 笨?騾夊ソ<E5A48A> |
| 扈溯ョ。譟・隸「 | "逶ョ蜑榊<E89C91><EFBFBD><EFBFBD>、壼ー台ココ<EFBDBA>? | REDCap | 蜃<>。ョ扈溯ョ。11莠?| 笨?騾夊ソ<E5A48A> |
| 豺キ蜷域衍隸「 | "霑吩クェ遐皮ゥカ逧<EFBDB6>クサ隕∫<E99A95>皮ゥカ逶ョ逧<EFBDAE>弍莉€荵茨シ<E88CA8>" | Dify | 蝓コ莠取枚譯」蝗樒ュ<E6A892> | 笨?騾夊ソ<E5A48A> |
| 荳贋ク区枚隶ー蠢?| 螟夊スョ蟇ケ隸<EFBDB9> | SessionMemory | 隶ー蠕嶺ク贋ク€霓ョ蜀<EFBDAE>ョ?| 笨?騾夊ソ<E5A48A> |

#### 謚€譛ッ莠ョ轤?
1. **豺キ蜷域」€邏?*<2A>壼酔譌カ謾ッ謖∫サ捺桷蛹匁焚謐ョ<E8AC90><EFBDAE>EDCap<61>牙柱髱樒サ捺桷蛹匁枚譯」<E8ADAF><EFBDA3>ify<66>?2. **譎コ閭ス霍ッ逕ア**<2A><EFBFBD>ケ謐ョ諢丞崟閾ェ蜉ィ騾画叫謨ー謐ョ貅?3. **髦イ豁「蟷サ隗<EFBDBB>**<2A>壽園譛牙屓遲泌渕莠守悄螳樊焚謐?譁<>。」<EFBDA1>檎サ昜ク咲シ夜€?4. **荳贋ク区枚隶ー蠢?*<2A>售essionMemory菫晏ュ俶怙霑?霓ョ蟇ケ隸?5. **螟咲畑LLMFactory**<2A>夐峺驟咲スョ菴ソ逕ィDeepSeek-V3
6. **蜊ウ譌カ蜿埼ヲ<E59FBC>**<2A>?豁」蝨ィ譟・隸「"豸域<E8B1B8><E59F9F>碁∩蜈咲畑謌キ辟ヲ陌?
#### 髣ョ鬚俶賜譟・荳惹ソョ螟?
**蜈ウ髞ョBug菫ョ螟<EFBDAE>**<2A>?
| 髣ョ鬚<EFBDAE> | 譬ケ蝗<EFBDB9> | 隗」蜀ウ譁ケ譯<EFBDB9> | 迥カ諤?|
|------|------|---------|------|
| AI郛夜€<E5A49C>遲疲。?| 諢丞崟隸<E5B49F>悪蜈ウ髞ョ隸堺ク榊<EFBDB8><E6A68A>育シ?蜈・騾?遲会シ<E4BC9A> | 謇ゥ蜈<EFBDA9><E89C88>髞ョ隸榊<E99AB8>陦?| 笨?蟾イ菫ョ螟?|
| Dify蜀<79>ョケ荳コundefined | 髞呵ッッ逧БPI蜩榊コ泌ュ玲ョオ霍ッ蠕<EFBDAF> | 菫ョ豁」荳コ`record.segment.document.name`蜥形record.segment.content` | 笨?蟾イ菫ョ螟?|

**隹<>ッ募キ・蜈キ**<2A>?- `debug-dify-injection.ts`<60>夊ソス雕ェDify扈捺棡豕ィ蜈・豬∫ィ<E288AB>
- `inspect-dify-response.ts`<60>壽衍逵汽ify API螳樣刔霑泌屓扈捺桷

#### 譬ク蠢<EFBDB8><E8A0A2><EFBFBD>

1. 笨?**螳樊慮謨ー謐ョ譟・隸「**<2A>€夊ソ⑲EDCap API譟・隸「謔」閠<EFBDA3>RF謨ー謐ョ
2. 笨?**遐皮ゥカ譁ケ譯域衍隸「**<2A>€夊ソ⑤ify遏・隸<EFBDA5>コ捺」€邏「遐皮ゥカ譁ケ譯医€RF縲∽シヲ逅<EFBDA6>枚莉?3. 笨?**譎コ閭ス逅<EFBDBD>ァ」**<2A><EFBFBD>辟カ隸ュ險€謠宣琉<E5AEA3>梧裏髴€隶ー蠢<EFBDB0>多莉、
4. 笨?**荳贋ク区枚逅<E69E9A>ァ?*<2A>壼、夊スョ蟇ケ隸晢シ梧髪謖∽サ」隸崎ァ」譫<EFBDA3>
5. 笨?**謨ー謐ョ逵溷ョ樊€?*<2A>壽園譛牙屓遲泌渕莠守悄螳樊焚謐ョ<E8AC90>檎サ昜ク咲シ夜€?6. 笨?**豺キ蜷域」€邏?*<2A>壼酔譌カ譟・隸「螟壻クェ謨ー謐ョ貅撰シ檎サ滉ク€蜻育鴫

#### 蜿り€<E3828A>枚譯?
- [Phase 1.5蠑€蜿題ョ。蛻綻(./Phase1.5-AI蟇ケ隸晁<E99AB8>蜉帛シ€蜿題ョ。蛻?md)
- [Phase 1.5蠑€蜿大ョ梧<EFBFBD>隶ー蠖?(REDCap)](../06-蠑€蜿題ョー蠖?Phase1.5-AI蟇ケ隸晞寔謌審EDCap螳梧<E89EB3>隶ー蠖<EFBDB0>.md)
- [Dify遏・隸<EFBDA5>コ馴寔謌仙シ€蜿題ョー蠖評(../06-蠑€蜿題ョー蠖?2026-01-04-Dify遏・隸<EFBDA5>コ馴寔謌仙シ€蜿題ョー蠖?md)
- [IIT Manager Agent 謚€譛ッ霍ッ蠕<EFBDAF>ク取楔譫<E6A594>ョセ隶。](../02-謚€譛ッ隶セ隶?IIT%20Manager%20Agent%20謚€譛ッ霍ッ蠕<EFBDAF>ク取楔譫<E6A594>ョセ隶。.md)

---

### Day 4<>壼ョ悟埋荳取枚譯」<E8ADAF>?026-01-04<30>?蟆乗慮<E4B997>俄昇<E4BF84>?
#### 荳雁壕<E99B81>壻シ伜喧荳取オ玖ッ包シ?蟆乗慮<E4B997>?
**莉サ蜉。8<EFBDA1>壼ョ悟埋螳。隶。譌・蠢暦シ<E69AA6>1蟆乗慮<E4B997>?*

**譁ー蠅樊律蠢礼アサ蝙<EFBDBB>**<2A>?```typescript
// 莨∽ク壼セョ菫。莠、莠呈律蠢<E5BE8B>
await prisma.auditLogs.create({
  data: {
    actionType: 'WECHAT_USER_MESSAGE',
    entityId: userId,
    details: {
      userMessage: message,
      botResponse: response,
      intent: 'query_patient_info',
      timestamp: new Date()
    }
  }
});

鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?謇€譛我シ∽ク壼セョ菫。莠、莠帝<E88EA0>譛画律蠢?- 笨?譌・蠢怜桁蜷ォ螳梧紛逧<E7B49B>ク贋ク区枚菫。諱ッ

  • 笨?蜿ッ莉・霑ス貅ッ豈乗ャ。蟇ケ隸<EFBDB9>

*莉サ蜉。9<EFBFBD>夐漠隸ッ螟<EFBFBD>炊莨伜喧<EFBFBD><EFBFBD>1蟆乗慮<EFBFBD>?

莨伜喧蜀<EFBFBD>ョケ<EFBFBD>?1. 莨∽ク壼セョ菫。API隹<EFBFBD>畑螟ア雍・<EFBFBD>? - 閾ェ蜉ィ驥崎ッ<E5B48E>3谺? - 隶ー蠖暮漠隸ッ譌・蠢<EFBDA5>

  • 髯咲コァ螟<EFBFBD><EFBFBD>€夂衍螟ア雍・荳榊スア蜩堺クサ豬∫ィ具シ?
  1. REDCap API雜<49><EFBFBD>? - 30遘定カ<E5AE9A><EFBDB6>? - 蜿句・ス髞呵ッッ謠千、コ
    • 霑泌屓郛灘ュ俶焚謐ョ<EFBFBD>亥ヲよ棡譛会シ?
  2. 逕ィ謌キ豸域<EFBFBD>隗」譫仙、ア雍・<EFBFBD>? - 霑泌屓蜿句・ス謠千、コ
    • 隶ー蠖暮漠隸ッ譌・蠢<EFBFBD>
    • 荳榊スア蜩榊<EFBFBD>莉門粥閭? 鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?謇€譛蛾漠隸ッ蝨コ譎ッ譛牙暑螂ス謠千、コ
  • 笨?邉サ扈溯<E68988>閾ェ蜉ィ驥崎ッ?- 笨?髞呵ッッ荳榊スア蜩榊<E89CA9>莉紋ササ蜉。謇ァ陦?

*莉サ蜉。10<EFBFBD>壼ョ梧紛髣ュ邇ッ蜴句鴨豬玖ッ包シ<EFBFBD>1蟆乗慮<EFBFBD>?

豬玖ッ募<EFBFBD>螳ケ<EFBFBD>?1. 霑樒サュ蠖募<EFBFBD>豬玖ッ<EFBFBD><EFBFBD>? - 蝨ィREDCap荳ュ霑樒サュ蠖募<E8A096>?0譚。謨ー謐? - 鬪瑚ッ∵園譛蛾€夂衍驛ス閭ス豁」遑ョ蜿鷹€? - 鬪瑚ッ∵イ。譛蛾@貍丞柱驥榊、? 2. 蟷カ蜿大ッケ隸晄オ玖ッ<EFBFBD><EFBFBD>? - 蜷梧慮蜿鷹€?荳ェ譟・隸「隸キ豎? - 鬪瑚ッ∵園譛芽ッキ豎る<E8B18E>閭ス豁」遑ョ蜩榊コ? - 鬪瑚ッ∝桃蠎疲慮髣エ<5遘? 3. **髟ソ譌カ髣エ霑占。梧オ玖ッ?*<2A>? - 邉サ扈溯ソ占。<E58DA0>1蟆乗慮

  • 譛滄龍髫乗惻蠖募<EFBFBD>謨ー謐ョ蜥梧衍隸? - 鬪瑚ッ∫ウサ扈溽ィウ螳壽€? 鬪梧噺譬<EFBFBD><EFBFBD>?- 笨?霑樒サュ蠖募<E8A096>豬玖ッ暮€夊ソ<E5A48A>シ?0/10<31>?- 笨?蟷カ蜿大ッケ隸晄オ玖ッ暮€夊ソ<E5A48A>シ?/5<>?- 笨?髟ソ譌カ髣エ霑占。梧裏蠑ょクク
  • 笨?蜀<>ュ伜柱諤ァ閭ス豁」蟶ク

荳句壕<EFBFBD>壽枚譯」郛門<EFBFBD><EFBFBD><EFBFBD>3蟆乗慮<EFBFBD>?

*莉サ蜉。11<EFBFBD><EFBFBD>蟒コ蠑€蜿大ョ梧<EFBFBD><EFBFBD>。」<EFBFBD><EFBFBD>2蟆乗慮<EFBFBD>?

<EFBFBD>。」菴咲スョ<EFBFBD>啻docs/03-荳壼苅讓。蝮<EFBDA1>/IIT Manager Agent/06-蠑€蜿題ョー蠖?Day3-4-譛€蟆舟VP髣ュ邇ッ螳梧<E89EB3>隶ー蠖<EFBDB0>.md`

<EFBFBD>。」蜀<EFBFBD>ョケ<EFBFBD>?1. 蠑€蜿第ヲりソ?2. 螳梧<E89EB3><EFBFBD>粥閭ス讓。蝮暦シ郁ッヲ扈<EFBDA6>ッエ譏趣シ?3. 豬玖ッ暮ェ瑚ッ∫サ捺棡 4. 諤ァ閭ス謖<EFBDBD><E8AC96><EFBFBD> 5. 驕<>芦逧<E88AA6>琉鬚倅ク手ァ」蜀ウ譁ケ譯<EFBDB9> 6. 髣ュ邇ッ謨域棡貍皮、コ 7. 荳倶ク€豁・隶。蛻?

*莉サ蜉。12<EFBFBD>壽峩譁ー讓。蝮礼憾諤∵枚譯」<EFBFBD><EFBFBD>30蛻<EFBFBD><EFBFBD>?

<EFBFBD>。」菴咲スョ<EFBFBD>啻docs/03-荳壼苅讓。蝮<EFBDA1>/IIT Manager Agent/00-讓。蝮怜ス灘燕迥カ諤∽ク主シ€蜿第欠蜊?md`

譖エ譁ー蜀<EFBFBD>ョケ<EFBFBD>?- 譖エ譁ー謨エ菴灘ョ梧<EFBDAE>蠎ヲ<E8A08E><EFBDA6>35% 竊?50%<25>?- 譖エ譁ー蟾イ螳梧<E89EB3>蜉溯<E89C89>蛻苓。?- 譖エ譁ーDay 3-4螳梧<E89EB3><EFBFBD><E8ABA0>

  • 譖エ譁ー荳倶ク€豁・蟾・菴懆ョ。蛻?

*莉サ蜉。13<EFBFBD><EFBFBD>蟒コ菴ソ逕ィ謇句<EFBFBD><EFBFBD><EFBFBD>30蛻<EFBFBD><EFBFBD>?

<EFBFBD>。」菴咲スョ<EFBFBD>啻docs/03-荳壼苅讓。蝮<EFBDA1>/IIT Manager Agent/05-菴ソ逕ィ謇句<E8AC87>/莨∽ク壼セョ菫。蟇ケ隸晄欠蜊<E6ACA0>.md`

<EFBFBD>。」蜀<EFBFBD>ョケ<EFBFBD>?1. 莨∽ク壼セョ菫。蠎皮畑驟咲スョ 2. 逕ィ謌キ螯ゆス募刈蜈・蠎皮畑 3. 謾ッ謖∫噪蟇ケ隸晄欠莉、蛻苓。?4. 蟶ク隗<EFBDB8>琉鬚炉AQ 5. 謨<>囿謗呈衍謖<E8A18D>


笨?蝗帙€ay 4扈捺據譌カ逧<EFBDB6>溜邇ッ謨域棡

4.1 螳梧紛髣ュ邇ッ鬪瑚ッ<E7919A>

<EFBFBD>識 譛€蟆舟VP髣ュ邇ッ螳悟<E89EB3>謇馴€夲シ<E5A4B2>

笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?Step 1: REDCap謨ー謐ョ蠖募<E8A096>                   笏?笏?笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?逕ィ謌キ蝨ィREDCap荳ュ<E88DB3><EFBDAD>                         笏?笏?- 譁ー蠅樊ぅ閠<E38185>D 8                          笏?笏?- 謌紋ソョ謾ケ謔」閠<EFBDA3>D 2                        笏?笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?           笏?0遘貞サカ霑?           竊?笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?Step 2: Node.js螳樊慮謐戊執                  笏?笏?笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?笨?DET隗ヲ蜿<EFBDA6> (0遘?                         笏?笏?笨?Webhook謗・謾カ (<10ms)                   笏?笏?笨?Worker螟<72>炊 (~2遘?                     笏?笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?           笏?           竊?笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?Step 3: 莨∽ク壼セョ菫。謗ィ騾<EFBDA8>€夂衍                 笏?笏?笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?笨?PI謾カ蛻ー蜊。迚<EFBDA1>カ域<EFBDB6> (<5遘?                 笏?笏?笨?騾夂衍蜀<E8A18D>ョケ<EFBDAE>?                           笏?笏?   "<22>投 test0102 - 謨ー謐ョ蠖募<E8A096>               笏?笏?    蜿苓ッ戊€<E6888A><EFBFBD>8                            笏?笏?    謫堺ス懶シ壽眠蠅?                          笏?笏?    蠖募<E8A096>8荳ェ蟄玲ョ?                         笏?笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏ャ笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?           笏?           竊?笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?Step 4: PI蝨ィ莨∽ク壼セョ菫。荳ュ蟇ケ隸<EFBDB9>               笏?笏?笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?笏?笨?蜿鷹€<E9B7B9><EFBFBD>"譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€?               笏?笏?笨?AI蝗槫、搾シ?                             笏?笏?   "<22>投 譛€霑台ク€蜻ィ謨ー謐ョ豎<EFBDAE>€<C280><EFBDBB>                 笏?笏?    譁ー蠅槫女隸戊€<E6888A><EFBFBD>2萓?                      笏?笏?    謨ー謐ョ譖エ譁ー<E8AD81>?谺?                        笏?笏?                                        笏?笏?笨?蜿鷹€<E9B7B9><EFBFBD>"譟・隸「謔」閠?逧<>ュ蜀?                笏?笏?笨?AI蝗槫、搾シ壽ぅ閠<E38185>渕譛ャ菫。諱?                  笏?笏?                                        笏?笏?笨?蜿鷹€<E9B7B9><EFBFBD>"鬘ケ逶ョ霑帛コヲ"                       笏?笏?笨?AI蝗槫、搾シ夐。ケ逶ョ扈溯ョ。謨ー謐?                  笏?笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?```

### 4.2 鬪梧噺譬<E599BA><EFBFBD>域怙扈茨シ<E88CA8>

**蜉溯<E89C89>螳梧紛諤?*<2A>?- 笨?REDCap謨ー謐ョ螳樊慮逶大成<E5A4A7><E68890>ET + 霓ョ隸「<E99AB8>?- 笨?Node.js謨ー謐ョ謐戊執荳主、<E4B8BB><EFBDA4>?- 笨?莨∽ク壼セョ菫。騾夂衍謗ィ騾?- 笨?莨∽ク壼セョ菫。蟇ケ隸晄衍隸「
- 笨?螳。隶。譌・蠢怜ョ梧紛隶ー蠖<EFBDB0>

**諤ァ閭ス謖<EFBDBD><E8AC96><EFBFBD>**<2A>?| 謖<><E8AC96><EFBFBD> | 逶ョ譬<EFBDAE>€?| 螳樣刔蛟?| 迥カ諤?|
|------|--------|--------|------|
| DET隗ヲ蜿大サカ霑<EFBDB6> | <1遘?| 0遘?| 笨?|
| Webhook蜩榊コ疲慮髣エ | <100ms | <10ms | 笨?|
| 騾夂衍謗ィ騾∝サカ霑?| <10遘?| <5遘?| 笨?|
| 蟇ケ隸晏桃蠎疲慮髣エ | <5遘?| ~3遘?| 笨?|
| 謨ー謐ョ蜷梧ュ・蜃<EFBDA5>。ョ諤?| 100% | 100% | 笨?|

**謚€譛ッ謖<EFBDAF><E8AC96>?*<2A>?- 笨?莉」遐∫ャヲ蜷亥屬髦溯ァ<E6BAAF>激
- 笨?髞呵ッッ螟<EFBDAF>炊螳悟埋
- 笨?譌・蠢苓ョー蠖募ョ梧紛
- 笨?豬玖ッ戊ヲ<E6888A>尠邇?90%

**蜿ッ貍皮、コ諤?*<2A>?- 笨?蜿ッ莉・邇ー蝨コ貍皮、コ螳梧紛髣ュ邇ッ
- 笨?蜿ッ莉・貍皮、コ蟇ケ隸晄衍隸「蜉溯<E89C89>
- 笨?謨域棡譏取仞縲∽サキ蛟シ貂<EFBDBC><E8B282>?
---

## <20>答 莠斐€∵橿譛ッ螳樒鴫扈<E9B4AB><E68988>?
### 5.1 莨∽ク壼セョ菫。蠑よュ・蝗槫、肴ィ。蠑擾シ芋沐?Critical<61>?
#### 髣ョ鬚俶緒霑ー
莨∽ク壼セョ菫。隕∵アり「ォ蜉ィ蝗槫、肴カ域<EFBDB6><EFBFBD>。サ蝨?*5遘貞<E98198>**螳梧<E89EB3>縲ょヲよ棡雜<E6A3A1><EFBFBD>檎畑謌キ莨夂恚蛻?譛榊苅證よ慮荳榊庄逕?逧<>署遉コ縲?
#### 髞呵ッッ蛛壽ウ<E5A3BD>
```typescript
笶?async handleCallback(request, reply) {
  const message = parseMessage(request.body);
  
  // 隹<>畑LLM<4C>亥庄閭ス閠玲慮10遘抵シ<E68AB5>
  const answer = await classifyIntent(message);
  const result = await queryData(answer);
  
  // 雜<>慮莠<E685AE>シ∽シ∝セョ蟾イ譁ュ蠑€霑樊磁
  return reply.send(result);
}

豁」遑ョ蛛壽ウ包シ壼シよュ・蝗槫、肴ィ。蠑?```typescript

笨?async handleCallback(request, reply) { const message = parseMessage(request.body);

// 1. 遶句叉霑泌屓'success'<27>?1遘抵シ<E68AB5> reply.send('success');

// 2. 蠑よュ・螟<EFBDA5><EFBFBD>井ク埼仆蝪橸シ? setImmediate(async () => { // 蜿ッ莉・諷「諷「邂暦シ<E69AA6>10遘偵€?0遘帝<E98198>蜿ッ莉・<E88E89>? const answer = await classifyIntent(message); const result = await queryData(answer);

// 3. 菴ソ逕ィ荳サ蜉ィ謗ィ騾∵磁蜿」霑泌屓扈捺<E68988>?    await wechatService.sendTextMessage(userId, result);

}); }


#### 蜈ウ髞ョ轤?1. 笨?**遶句叉霑泌屓**<2A>壽噺蛻ー豸域<E8B1B8><EFBFBD><1遘定ソ泌<EFBDBF>?success'
2. 笨?**蠑よュ・螟<EFBDA5>炊**<2A>壻スソ逕ィ`setImmediate`謌匁カ域<EFBDB6>髦溷<E9ABA6>?3. 笨?**荳サ蜉ィ謗ィ騾?*<2A>夊ー<E5A48A>畑蜿鷹€∵カ域<EFBDB6>謗・蜿」<E89CBF>€碁撼HTTP Response
4. 笨?**髞呵ッッ螟<EFBDAF>炊**<2A>壼シよュ・莉サ蜉。螟ア雍・譌カ<E8AD8C>梧耳騾∝暑螂ス髞呵ッッ謠千、?
---

### 5.2 莨∽ク壼セョ菫。XML蜉<4C>隗」蟇<EFBDA3>シ芋沐・ Critical<61>?
#### 髣ョ鬚俶緒霑ー
莨∽ク壼セョ菫。逧<EFBDA1>カ域<EFBDB6>菴捺<E88FB4>?*蜉<><EFBFBD>噪XML**<2A>御ク肴弍譏取枚縲よ<E7B8B2>シ蠑丞ヲゆク具シ<E585B7>
```xml
<xml>
  <ToUserName><![CDATA[ww01cb7b72ea2db83c]]></ToUserName>
  <Encrypt><![CDATA[蜉<><EFBFBD>噪豸域<E8B1B8><EFBFBD>ョケ]]></Encrypt>
</xml>

隗」蟇<EFBFBD>オ∫ィ<EFBFBD>

<EFBFBD><EFBFBD>ML 竊?Base64隗」遐<EFBDA3> 竊?AES隗」蟇<EFBDA3> 竊?蜴サ髯、Padding 竊?鬪瑚ッorpID 竊?譏取枚XML

髞呵ッッ蛛壽ウ<EFBFBD>

?// 閾ェ蟾ア螳樒鴫AES隗」蟇<EFBDA3>シ域栫譏灘<E8AD8F>髞呻シ<E591BB>
function decrypt(encryptedData) {
  // 謇句<E8AC87>AES縲 ̄adding縲。ase64...
  // 99%逧<>ココ驛ス莨壼<E88EA8><EFBFBD>
}

豁」遑ョ蛛壽ウ包シ壻スソ逕ィ螳俶婿蠎<EFBFBD>

npm install @wecom/crypto
?import { WXBizMsgCrypt } from '@wecom/crypto';

const crypt = new WXBizMsgCrypt(
  process.env.WECHAT_TOKEN!,              // 閾ェ螳壻ケ欝oken
  process.env.WECHAT_ENCODING_AES_KEY!,   // 莨∝セョ蜷主床逕滓<E98095><E6BB93>?3菴搾シ<E690BE>
  process.env.WECHAT_CORP_ID!
);

// 荳€陦御サ」遐∝ョ梧<EFBDAE>隗」蟇?const decryptedXml = crypt.decrypt(
  msg_signature,
  timestamp,
  nonce,
  encryptedXml
);

髴€隕∫噪驟咲スョ

驟咲スョ鬘? 譚・貅<EFBFBD> 遉コ萓<EFBFBD>
WECHAT_TOKEN 閾ェ螳壻ケ? 32菴埼囂譛コ蟄礼ャヲ荳イ
WECHAT_ENCODING_AES_KEY 莨∝セョ蜷主床逕滓<EFBFBD> 43菴榊ュ礼ャヲ<EFBFBD>亥ヲゑシ啾bcdefghijklmnopqrstuvwxyz0123456789ABC<EFBFBD>?
WECHAT_CORP_ID 莨∝セョ蜷主床 ww01cb7b72ea2db83c

5.3 莨∽ク壼セョ菫。IP逋ス蜷榊黒<E6A68A>芋沐・ P0<50>?

髣ョ鬚俶緒霑ー

闔キ蜿泡ccessToken譌カ<EFBFBD>御シ∽ク壼セョ菫。莨壽<EFBFBD>。鬪瑚ッキ豎よ擂貅蝕P縲ょヲよ棡IP荳榊惠逋ス蜷榊黒荳ュ<EFBFBD>御シ夊ソ泌屓60020髞呵ッッ縲?

驟咲スョ豁・鬪、

  1. 遑ョ隶、SAE NAT鄂大<E98482>IP<49>啻182.92.176.14`
  2. 逋サ蠖穂シ∽ク壼セョ菫。邂。逅<EFBFBD>錘蜿ー
  3. 蠎皮畑邂。逅<EFBFBD> 竊?IIT Manager Agent
  4. 謇セ蛻ー"莨∽ク壼庄菫。IP"驟咲スョ
  5. 豺サ蜉<EFBFBD><EFBFBD>啻182.92.176.14`
  6. 菫晏ュ伜ケカ豬玖ッ?

鬪瑚ッ∵婿豕<EFBFBD>

// 豬玖ッ柊ccessToken闔キ蜿<EFBDB7>
const response = await fetch(
  `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${CORP_ID}&corpsecret=${SECRET}`
);

const data = await response.json();

if (data.errcode === 60020) {
  console.error('笶?IP逋ス蜷榊黒譛ェ驟咲スョ<EFBDBD>?);
} else if (data.errcode === 0) {
  console.log('?IP逋ス蜷榊黒驟咲スョ豁」遑?);
}

5.4 莨∽ク壼セョ菫。豸域<E8B1B8>譬シ蠑<EFBDBC>

<EFBFBD>悽豸域<EFBFBD>譬シ蠑<EFBFBD>

{
  "touser": "GaoFeng",
  "msgtype": "text",
  "agentid": 1000002,
  "text": {
    "content": "霑呎弍荳€譚。譁<EFBDA1>悽豸域<E8B1B8>?
  }
}

蜊。迚<EFBFBD>カ域<EFBFBD>譬シ蠑<EFBFBD>

{
  "touser": "GaoFeng",
  "msgtype": "textcard",
  "agentid": 1000002,
  "textcard": {
    "title": "<22>投 test0102 - 謨ー謐ョ蠖募<E8A096>",
    "description": "<div>蜿苓ッ戊€<E6888A><EFBFBD>8</div><div>謫堺ス懶シ壽眠蠅?/div><div>蠖募<E8A096>8荳ェ蟄玲ョ?/div>",
    "url": "https://iit.xunzhengyixue.com/chat",
    "btntxt": "譟・逵玖ッヲ諠<EFBDA6>"
  }
}

5.5 莨∽ク壼セョ菫。蝗櫁ー<E6AB81>カ域<EFBDB6>譬シ蠑<EFBDBC>

逕ィ謌キ譁<EFBFBD>悽豸域<EFBFBD><EFBFBD><EFBFBD>ML譬シ蠑擾シ?```xml

1641024000 1234567890 1000002 ```

蝗槫、肴カ域<EFBFBD>譬シ蠑擾シ<EFBFBD>ML譬シ蠑擾シ?```xml

1641024001 ```

5.6 莨∽ク壼セョ菫。遲セ蜷埼ェ瑚ッ<E7919A>

function verifySignature(signature: string, timestamp: string, nonce: string, echostr: string): boolean {
  const token = WECHAT_TOKEN; // 莨∽ク壼セョ菫。驟咲スョ逧Уoken
  const tmpArr = [token, timestamp, nonce, echostr].sort();
  const tmpStr = tmpArr.join('');
  const sha1 = crypto.createHash('sha1');
  sha1.update(tmpStr);
  const calculatedSignature = sha1.digest('hex');
  return calculatedSignature === signature;
}

<EFBFBD>識 蜈ュ縲∽ク倶ク€豁・謇ゥ螻墓婿蜷托シ<E68998>hase 1.5+<2B>?

Phase 1.5<EFBFBD>壽焚謐ョ雍ィ謗ァ隗<EFBFBD><EFBFBD>逕滓<EFBFBD><EFBFBD><EFBFBD>1-2螟ゥ<E89E9F><EFBDA9>

逶ョ譬<EFBFBD><EFBFBD>壼ョ樒鴫蝓コ莠手ァ<EFBFBD><EFBFBD><EFBFBD>焚謐ョ雍ィ謗ァ

譬ク蠢<EFBFBD>粥閭ス<EFBFBD>?1. 荳贋シ<E8B48B>遐皮ゥカ譁ケ譯<EFBDB9>DF 2. AI閾ェ蜉ィ謠仙叙雍ィ謗ァ隗<EFBDA7><E99A97> 3. 隗<><E99A97>蠎鍋ョ。逅<EFBDA1>シ亥庄郛冶セ代€∝庄螳。譬ク<E8ADAC>?4. 蝓コ莠手ァ<E6898B><EFBDA7>霑幄。梧焚謐ョ雍ィ謗ァ 5. 雍ィ謗ァ扈捺棡謗ィ騾∝芦莨∽ク壼セョ菫。

**謚€譛ッ譁ケ譯?*<2A>?- 菴ソ逕ィ螟ァ讓。蝙区署蜿冶ァ<E586B6><EFBDA7><EFBFBD>磯撼螳樊慮隹<E685AE><EFBFBD><E79591>

  • <EFBFBD><EFBFBD>菫晏ュ伜芦謨ー謐ョ蠎難シ<EFBFBD>quality_rules`陦ィ<E999A6><EFBDA8>
  • 蠖募<EFBFBD>譌カ蝓コ莠手ァ<EFBFBD><EFBFBD>蛻、譁ュ<EFBFBD>亥ソォ騾溘€∝庄髱<EFBFBD><EFBFBD><EFBFBD>
  • 隸∵紺體セ霑ス貅ッ<EFBFBD>郁ァ<EFBFBD><EFBFBD>譚・貅蝉コ取婿譯育ャャX鬘オ隨ャY譚。<EFBFBD><EFBFBD>

Phase 2<>啀C Workbench蜑咲ォッ<EFBDAB>?-3螟ゥ<E89E9F><EFBDA9>

逶ョ譬<EFBFBD><EFBFBD>壽署萓娶eb遶ッ螟肴<EFBFBD>ク逡碁<EFBFBD>? 譬ク蠢<EFBFBD>粥閭ス<EFBFBD>?1. 雍ィ謗ァ蟒コ隶ョ蛻苓。ィ 2. 蠖灘燕謨ー謐ョ vs AI蟒コ隶ョ蟇ケ豈<EFBDB9> 3. 隸∵紺體セ螻慕、コ<EFBDA4><EFBDBA>DF鬮倅コョ<EFBDBA>?4. 螳。謇ケ謫堺ス懶シ育。ョ隶?諡堤サ晢シ?5. REDCap謨ー謐ョ蝗槫<E89D97>


Phase 3<>壽匱閭ス蛹匁シ碑ソ幢シ磯柄譛滂シ<E6BB82>

蜉溯<EFBFBD>謇ゥ螻<EFBFBD><EFBFBD>?1. 螟夊スョ蟇ケ隸晁<E99AB8><EFBFBD> 2. 荳贋ク区枚逅<E69E9A>ァ?3. 莉サ蜉。鬩ア蜉ィ蠑墓梼 4. 謔」閠<EFBDA3>囂隶ソAgent 5. 譎コ閭ス豎<EFBDBD>冠Agent


<EFBFBD>搭 荳<>€∵」€譟・貂<EFBDA5><E8B282>?

Day 3蠑€蟋句燕

  • 莨∽ク壼セョ菫。UserID遑ョ隶、<EFBFBD>育畑莠取オ玖ッ包シ<EFBFBD>
  • 莨∽ク壼セョ菫。蝗櫁ーザRL驟咲スョ<EFBFBD>亥惠莨∽ク壼セョ菫。邂。逅<EFBFBD>錘蜿ー<EFBFBD>?- [ ] REDCap豬玖ッ墓焚謐ョ蜃<EFBDAE><EFBFBD>シ郁<EFBDBC>蟆?譚。<E8AD9A><EFBDA1>
  • 蜷守ォッ譛榊苅霑占。梧ュ」蟶ク

Day 3扈捺據譌?- [ ] WechatService蠑€蜿大ョ梧<EFBDAE>?- [ ] iit_quality_check Worker螳悟埋

  • 莨∽ク壼セョ菫。謗ィ騾∵オ玖ッ暮€夊ソ<EFBFBD>
  • 遶ッ蛻ー遶ッ髣ュ邇ッ謇馴€夲シ<EFBFBD>EDCap 竊?莨∝セョ<EFBDBE>?

Day 4扈捺據譌?- [ ] WechatCallbackController蠑€蜿大ョ梧<EFBDAE>?- [ ] 莨∽ク壼セョ菫。蟇ケ隸晏粥閭ス豬玖ッ暮€夊ソ<E5A48A>

  • 螳梧紛髣ュ邇ッ蜴句鴨豬玖ッ暮€夊ソ<EFBFBD>
  • <EFBFBD>。」蜈ィ驛ィ譖エ譁ー螳梧<EFBFBD>
  • 莉」遐∵署莠、蛻ーGit

<EFBFBD>至 蜈ォ縲∵<E7B8B2>蜉滓<E89C89><E6BB93><EFBFBD>?

**MVP謌仙粥逧<E7B2A5><E980A7><EFBFBD>ソ?*<2A>?1. 笨?PI蜿ッ莉・蝨ィ莨∽ク壼セョ菫。荳ュ螳樊慮謾カ蛻ー謨ー謐ョ蠖募<E8A096>騾夂衍 2. 笨?PI蜿ッ莉・蝨ィ莨∽ク壼セョ菫。荳ュ譟・隸「鬘ケ逶ョ謨ー謐ョ 3. 笨?螳梧紛髣ュ邇ッ<E98287><EFBDAF>EDCap 竊?Node.js 竊?莨∝セョ<EFBDBE>臥ィウ螳夊ソ占。?4. 笨?蜩榊コ疲慮髣エ貊。雜ウ隕∵アゑシ?5遘抵シ<E68AB5> 5. 笨?蜿ッ莉・邇ー蝨コ貍皮、コ扈吝屬髦溽恚

**莉キ蛟シ鬪瑚ッ?*<2A>?- 笨?PI荳咲畑豈丞、ゥ逋サ蠖紐EDCap譟・逵玖ソ帛コヲ

  • 笨?謨ー謐ョ蠖募<E8A096>蜷守ォ句叉遏・譎難シ御ク堺シ夐<EFBCA0>
  • 笨?髫乗慮髫丞慍蜿ッ莉・譟・隸「謨ー謐ョ<E8AC90>域焔譛コ遶ッ<E981B6>?- 笨?荳コ蜷守サュ蜉溯<E89C89>謇ゥ螻墓遠荳句渕遑€

**譁<>。」扈エ謚、閠?<EFBFBD>壼シ€蜿大屬髦? **譛€蜷取峩譁?<EFBFBD>?026-01-02
**迥カ諤?*<2A>夸沒?蠑€蜿題ョ。蛻抵シ亥セ<E4BAA5>鴬陦鯉シ<E9AF89>