Files
AIclinicalresearch/docs/03-业务模块/Redcap/00-模块概览/02-REDCap对接总体方案.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

39 KiB
Raw Blame History

REDCap荳拶Iclinicalresearch蟷ウ蜿ー蟇ケ謗・諤サ菴捺婿譯<EFBFBD>

*<EFBFBD>。」迚域悽<EFBFBD>? v1.0
*蛻帛サコ譌・譛滂シ? 2025-12-30
€蜷取峩譁ー<EFBFBD><EFBFBD> 2025-12-30
<EFBFBD>。」迥カ諤<EFBFBD><EFBFBD><><E99A97>荳? 菴懆€<EFBFBD><EFBFBD>€譛ッ譫カ譫<EFBDB6><EFBFBD>


<EFBFBD>搭 譁<>。」隸エ譏<EFBDB4>

譛ャ譁<EFBFBD>。」螳壻ケ嘘EDCap<EFBFBD>?5.8.0<EFBFBD>我ク主」ケ隸∝セェAI遘醍<EFBFBD>泌ケウ蜿ー逧?*螳梧紛蟇ケ謗・譁ケ譯<EFBDB9>**<2A>悟桁諡ャ<E8ABA1><EFBDAC>

  1. 蟇ケ謗・譫カ譫<EFBFBD>ョセ隶。
  2. External Module蠑€蜿第婿譯?
  3. API髮<EFBFBD><EFBFBD>譁ケ譯<EFBFBD>
  4. 謨ー謐ョ豬∬ョセ隶?
  5. 蠑€蜿題ョ。蛻剃ク主ョ樊命豁・鬪、

*蜑咲スョ譚。莉カ<EFBFBD>?

  • 笨?蟾イ闔キ蠕由EDCap螳俶婿謗域揀
  • 笨?諡・譛嘘EDCap 15.8.0貅蝉サ」遐?
  • 笨?諡・譛右xternal Module Framework譁<6B>。」

*逶ク蜈ウ譁<EFBFBD>。」<EFBFBD>?


<EFBFBD>識 蟇ケ謗・逶ョ譬<EFBDAE>ク惹サキ蛟?

譬ク蠢<EFBFBD>岼譬<EFBFBD>

*<EFBFBD>EDCap逧<EFBFBD>シコ螟ァEDC閭ス蜉帑ク拶I遘醍<EFBFBD>泌ケウ蜿ー逧БI蠅槫€シ蜉溯<EFBFBD>豺ア蠎ヲ陞榊<EFBFBD>?

REDCap (謨ー謐ョ驥<EFBDAE>寔)  +  AIclinicalresearch (AI閭ス蜉<EFBDBD>)
    竊?                          竊?
荳エ蠎頑焚謐ョ蠖募<E8A096>              AI譎コ閭ス螟<EFBDBD>炊縲∝<E7B8B2>譫舌€∵エ槫ッ?
    竊?                          竊?
        螳梧紛逧БI鬩ア蜉ィ荳エ蠎顔<E8A08E>皮ゥカ髣ュ邇ッ

荳壼苅莉キ蛟?

蜉溯<EFBFBD>讓。蝮<EFBFBD> REDCap蝓コ遑€閭ス蜉<EFBFBD> AI蟷ウ蜿ー蠅槫€シ閭ス蜉? 蜊丞酔莉キ蛟?
謨ー謐ョ驥<EFBFBD> 笨?陦ィ蜊戊ョセ隶。縲∵焚謐ョ蠖募<E8A096><EFBFBD>ェ瑚ッ? <EFBFBD>氏 AI霎<49>勧蠖募<E8A096>縲∵匱閭ス雍ィ謗? 謠仙合蠖募<EFBFBD>謨育紫50%
謨ー謐ョ貂<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD> 謇句勘譟・隸「縲∝ッシ蜃コExcel <EFBFBD>氏 DC讓。蝮苓<E89DAE>蜉ィ貂<EFBDA8>エ励€¨ER謠仙叙 蜃丞ー第焚謐ョ螟<EFBFBD>炊譌カ髣エ80%
扈溯ョ。蛻<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>€蟇シ蜃コ蛻ーR/SPSS <EFBFBD>氏 SSA讓。蝮嶺ク€髞ョ蛻<EFBDAE>梵縲∝庄隗<E5BA84> 髯堺ス守サ溯ョ。髣ィ讒幢シ悟<EFBFBD>譫宣€溷コヲ謠仙合10蛟?
<EFBFBD>鍵謾ッ謖<EFBFBD> 笶?譌? <EFBFBD>氏 ASL讓。蝮玲匱閭ス譁<EFBDBD>鍵遲幃€? 邉サ扈溯ッ<EFBFBD>サキ謨育紫謠仙合5蛟?
AI髣ョ遲<EFBFBD> 笶?譌? <EFBFBD>氏 AIA讓。蝮<EFBDA1>10+譎コ閭ス菴楢セ<E6A5A2><EFBDBE>? 蜈ィ豬∫ィ帰I霎<EFBFBD>
*遏・隸<EFBFBD>コ? 笶?譌? <EFBFBD>氏 PKB讓。蝮由AG髣ョ遲<EFBDAE> 鬘ケ逶ョ遏・隸<EFBFBD>イ画キ€

<EFBFBD><EFBFBD>?蟇ケ謗・譫カ譫<EFBDB6>ョセ隶。

謨エ菴捺楔譫<EFBFBD>

笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏?                  逕ィ謌キ螻ゑシ育<EFBDBC>皮ゥカ莠コ蜻<EFBDBA>/蛹サ逕滂シ?                          笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                              竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏?                     蜑咲ォッ螻慕、コ螻?                                  笏?
笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?             笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?  笏?
笏? 笏? REDCap Web UI 笏?             笏?AIclinicalresearch      笏?  笏?
笏? 笏? (蜴溽函逡碁擇)     笏や淀笏€€€€€€€€€€€€笆コ笏<EFBDBA> Frontend (React)        笏?  笏?
笏? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?             笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?  笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                              竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏?                    髮<><E9ABAE>螻ゑシ域<EFBDBC>ク蠢<EFBDB8>シ?                                笏?
笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?   笏?
笏? 笏? REDCap External Module: "AI Research Assistant"       笏?   笏?
笏? 笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?   笏?
笏? 笏? 笏懌楳笏€ 謨ー謐ョ蜷梧ュ・譛榊苅 (Data Sync Service)                   笏?   笏?
笏? 笏? 笏懌楳笏€ AI蜉溯<E89C89>闖懷黒 (AI Menu Links)                        笏?   笏?
笏? 笏? 笏懌楳笏€ Hooks螟<73>炊蝎?(Hook Handlers)                       笏?   笏?
笏? 笏? 笏披楳笏€ API莉」逅<EFBDA3>ア?(API Proxy)                             笏?   笏?
笏? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?   笏?
笏?                             竊?                                 笏?
笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?   笏?
笏? 笏? AIclinicalresearch Backend RESTful API                笏?   笏?
笏? 笏? /api/v1/redcap/*                                       笏?   笏?
笏? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?   笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                              竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏?                 荳壼苅螟<E88B85>炊螻ゑシ<E38291>I閭ス蜉幢シ?                             笏?
笏? 笏娯楳笏€笏€笏€笏€笏€笏? 笏娯楳笏€笏€笏€笏€笏€笏? 笏娯楳笏€笏€笏€笏€笏€笏? 笏娯楳笏€笏€笏€笏€笏€笏? 笏娯楳笏€笏€笏€笏€笏€笏?           笏?
笏? 笏?DC   笏? 笏?SSA  笏? 笏?ASL  笏? 笏?AIA  笏? 笏?PKB  笏? ...       笏?
笏? 笏よ焚謐? 笏? 笏らサ溯ョ? 笏? 笏よ枚迪? 笏? 笏る琉遲? 笏? 笏ら衍隸<E8A18D>コ凪<EFBDBA>?           笏?
笏? 笏よク<E38288>エ? 笏? 笏ょ<E7AC8F>譫? 笏? 笏らュ幃€? 笏? 笏?     笏? 笏?     笏?           笏?
笏? 笏披楳笏€笏€笏€笏€笏€笏? 笏披楳笏€笏€笏€笏€笏€笏? 笏披楳笏€笏€笏€笏€笏€笏? 笏披楳笏€笏€笏€笏€笏€笏? 笏披楳笏€笏€笏€笏€笏€笏?           笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                              竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏?                   謨ー謐ョ蟄伜お螻?                                    笏?
笏? 笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?        笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?           笏?
笏? 笏? REDCap MySQL    笏?        笏? AI Platform     笏?           笏?
笏? 笏? (荳エ蠎頑焚謐ョ)       笏や淀笏€€€€€€€笆コ笏<EFBDBA>  PostgreSQL      笏?           笏?
笏? 笏? - 謔」閠<EFBDA3>焚謐?      笏? 蜷梧ュ・   笏? (蛻<>梵扈捺棡)       笏?           笏?
笏? 笏? - 陦ィ蜊募<E89C8A>謨ー謐?    笏?        笏? - 貂<>エ怜錘謨ー謐?    笏?           笏?
笏? 笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?        笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?           笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?

譬ク蠢<EFBFBD>ッケ謗・讓。蠑<EFBFBD>

謌台サャ驥<EFBFBD>畑**蜿悟髄蟇ケ謗・**遲也払<E4B99F>?

讓。蠑就<EFBFBD>啌EDCap 竊?AI蟷ウ蜿ー<E89CBF>域焚謐ョ謗ィ騾<EFBDA8><EFBFBD>

逕ィ謌キ蝨ィREDCap蠖募<EFBFBD>謨ー謐ョ
         竊?
   redcap_save_record Hook隗ヲ蜿<EFBDA6>
         竊?
External Module謗ィ騾∵焚謐ョ蛻ーAI蟷ウ蜿ーAPI
         竊?
AI蟷ウ蜿ー螟<EFBDB0><EFBFBD>域ク<E59F9F>エ?蛻<>梵/AI螟<49><EFBFBD>?
         竊?
    扈捺棡霑泌屓REDCap蟄伜お

讓。蠑州<EFBFBD>哂I蟷ウ蜿ー 竊?REDCap<61>域焚謐ョ諡牙叙<E78999><E58F99>

逕ィ謌キ蝨ィAI蟷ウ蜿ー蜿題オキ蛻<EFBFBD>梵
         竊?
AI蟷ウ蜿ー隹<EFBDB0>畑REDCap API闔キ蜿匁焚謐ョ
         竊?
AI蟷ウ蜿ー謇ァ陦悟<E999A6>譫撰シ<E692B0>C/SSA/AIA遲会シ<E4BC9A>
         竊?
扈捺棡螻慕、コ蝨ィAI蟷ウ蜿ー蜑咲ォッ
         竊?
<0A>亥庄騾会シ臥サ捺棡蝗槫<E89D97>REDCap

<EFBFBD>肌 謚€譛ッ譁ケ譯郁ッヲ隗?

譁ケ譯<EFBFBD>1<EFBFBD>啌EDCap External Module蠑€蜿?

讓。蝮怜多蜷堺ク守サ捺<EFBFBD>?

讓。蝮怜錐遘ー: ai_research_assistant
迚域悽: v1.0.0
螳梧紛逶ョ蠖<EFBDAE>: <redcap-root>/modules/ai_research_assistant_v1.0.0/

逶ョ蠖慕サ捺桷:
ai_research_assistant_v1.0.0/
笏懌楳笏€ config.json                    # 讓。蝮鈴<E89DAE>鄂ョ
笏懌楳笏€ AiResearchAssistantModule.php  # 荳サ騾サ霎醍ア?
笏懌楳笏€ README.md                      # 隸エ譏取枚譯」
笏懌楳笏€ LICENSE                        # MIT隶ク蜿ッ
笏懌楳笏€ pages/                         # 閾ェ螳壻ケ蛾。オ髱?
笏?  笏懌楳笏€ dashboard.php             # AI蜉溯<E89C89>莉ェ陦ィ逶?
笏?  笏懌楳笏€ data_sync.php             # 謨ー謐ョ蜷梧ュ・邂。逅<EFBDA1>
笏?  笏懌楳笏€ analysis_center.php       # 蛻<>梵荳ュ蠢<EFBDAD>
笏?  笏披楳笏€ settings.php              # 讓。蝮苓ョセ鄂ョ
笏懌楳笏€ js/                           # JavaScript譁<74>サカ
笏?  笏懌楳笏€ dashboard.js
笏?  笏披楳笏€ data_sync.js
笏懌楳笏€ css/                          # 譬キ蠑乗枚莉カ
笏?  笏披楳笏€ style.css
笏披楳笏€ services/                     # 譛榊苅邀?
    笏懌楳笏€ ApiClient.php             # AI蟷ウ蜿ーAPI螳「謌キ遶?
    笏懌楳笏€ DataMapper.php            # 謨ー謐ョ譏<EFBDAE><EFBFBD>スャ謐「
    笏披楳笏€ SyncService.php           # 蜷梧ュ・譛榊苅

config.json譬ク蠢<EFBDB8><E8A0A2>鄂ョ

{
  "name": "AI Research Assistant",
  "description": "螢ケ隸∝セェAI遘醍<E98198>泌ケウ蜿ー髮<EFBDB0><E9ABAE>讓。蝮<EFBDA1> - 謠蝉セ帶焚謐ョ譎コ閭ス貂<EFBDBD>エ励€∫サ溯ョ。蛻<EFBDA1>梵縲∵枚迪ョ謾ッ謖∫ュ陰I蠅槫€シ蜉溯<E89C89>?,
  "authors": [
    {
      "name": "螢ケ隸∝セェ遘第橿",
      "email": "support@yizx.ai",
      "institution": "螢ケ隸∝セェ遘第橿"
    }
  ],
  "framework-version": 16,
  "permissions": [],
  "links": {
    "project": [
      {
        "name": "<EFBFBD><EFBFBD> AI蜉溯<EFBFBD>荳ュ蠢<EFBFBD>",
        "icon": "fas fa-brain",
        "url": "pages/dashboard.php",
        "show-header-and-footer": true
      },
      {
        "name": "<EFBFBD> 謨ー謐ョ蜷梧ュ・",
        "icon": "fas fa-sync-alt",
        "url": "pages/data_sync.php",
        "show-header-and-footer": true
      },
      {
        "name": "<EFBFBD> AI蛻<EFBFBD>梵荳ュ蠢<EFBFBD>",
        "icon": "fas fa-chart-line",
        "url": "pages/analysis_center.php",
        "show-header-and-footer": true
      }
    ],
    "control-center": [
      {
        "name": "AI蟷ウ蜿ー驟咲スョ",
        "icon": "fas fa-cog",
        "url": "pages/settings.php"
      }
    ]
  },
  "system-settings": [
    {
      "key": "ai_platform_url",
      "name": "AI蟷ウ蜿ー蝨ー蝮€",
      "type": "text",
      "required": true,
      "default": "https://ai.yizx.com"
    },
    {
      "key": "ai_platform_api_key",
      "name": "API蟇<49>徴",
      "type": "password",
      "required": true
    },
    {
      "key": "enable_auto_sync",
      "name": "蜷ッ逕ィ閾ェ蜉ィ蜷梧ュ・",
      "type": "checkbox",
      "default": true
    }
  ],
  "project-settings": [
    {
      "key": "sync_mode",
      "name": "蜷梧ュ・讓。蠑<EFBDA1>",
      "type": "dropdown",
      "choices": [
        {"value": "manual", "name": "謇句勘蜷梧ュ・"},
        {"value": "realtime", "name": "螳樊慮蜷梧ュ・"},
        {"value": "scheduled", "name": "螳壽慮蜷梧ュ・"}
      ],
      "default": "realtime"
    },
    {
      "key": "enable_dc_module",
      "name": "蜷ッ逕ィ謨ー謐ョ貂<EFBDAE>エ玲ィ。蝮<EFBDA1>",
      "type": "checkbox",
      "default": true
    },
    {
      "key": "enable_ssa_module",
      "name": "蜷ッ逕ィ扈溯ョ。蛻<EFBDA1>梵讓。蝮<EFBDA1>",
      "type": "checkbox",
      "default": true
    },
    {
      "key": "enable_asl_module",
      "name": "蜷ッ逕ィ譎コ閭ス譁<EFBDBD>鍵讓。蝮<EFBDA1>",
      "type": "checkbox",
      "default": false
    }
  ],
  "crons": [
    {
      "cron_name": "data_sync_cron",
      "cron_description": "螳壽慮蜷梧ュ・謨ー謐ョ蛻ーAI蟷ウ蜿ー",
      "method": "syncDataToAIPlatform",
      "cron_frequency": "3600",
      "cron_max_run_time": "600"
    }
  ]
}

荳サ騾サ霎醍アサ<EFBFBD><EFBFBD>iResearchAssistantModule.php<68>?

<?php
namespace YiZhengXun\AiResearchAssistant;

use ExternalModules\AbstractExternalModule;
use REDCap;

class AiResearchAssistantModule extends AbstractExternalModule {
    
    // API螳「謌キ遶ッ螳樔セ?
    private $apiClient;
    
    /**
     * 譫<>€<EFBFBD>蜃ス謨?- 蛻晏ァ句喧API螳「謌キ遶?
     */
    public function __construct() {
        parent::__construct();
        require_once __DIR__ . '/services/ApiClient.php';
        $this->apiClient = new ApiClient(
            $this->getSystemSetting('ai_platform_url'),
            $this->getSystemSetting('ai_platform_api_key')
        );
    }
    
    /**
     * Hook: 謨ー謐ョ菫晏ュ俶慮隗ヲ蜿?
     * 譬ク蠢<EFBDB8>粥閭ス<E996AD>壼ョ樊慮謗ィ騾∵焚謐ョ蛻ーAI蟷ウ蜿ー
     */
    public function redcap_save_record(
        $project_id, 
        $record, 
        $instrument, 
        $event_id, 
        $group_id, 
        $survey_hash, 
        $response_id, 
        $repeat_instance
    ) {
        // 譽€譟・譏ッ蜷ヲ蜷ッ逕ィ螳樊慮蜷梧ュ?
        $syncMode = $this->getProjectSetting('sync_mode');
        if ($syncMode !== 'realtime') {
            return;
        }
        
        // 髦イ豁「譌<EFBDA2>髯仙セェ邇ッ
        static $is_syncing = false;
        if ($is_syncing) return;
        $is_syncing = true;
        
        try {
            // 闔キ蜿冶ョー蠖墓焚謐ョ
            $data = REDCap::getData($project_id, 'array', $record);
            
            // 霓ャ謐「謨ー謐ョ譬シ蠑<EFBDBC>
            require_once __DIR__ . '/services/DataMapper.php';
            $mapper = new DataMapper();
            $mappedData = $mapper->redcapToAIPlatform($data, $project_id, $record);
            
            // 謗ィ騾∝芦AI蟷ウ蜿ー
            $result = $this->apiClient->post('/api/v1/redcap/records', $mappedData);
            
            // 隶ー蠖墓律蠢<E5BE8B>
            $this->log("謨ー謐ョ蜷梧ュ・謌仙粥", [
                'project_id' => $project_id,
                'record' => $record,
                'instrument' => $instrument,
                'ai_platform_response' => $result
            ]);
            
            // 螯よ棡蜷ッ逕ィ莠<EFBDA8>I謨ー謐ョ貂<EFBDAE>エ暦シ瑚ァヲ蜿第ク<E7ACAC>エ嶺ササ蜉?
            if ($this->getProjectSetting('enable_dc_module')) {
                $this->triggerDataCleaning($project_id, $record);
            }
            
        } catch (\Exception $e) {
            // 髞呵ッッ螟<EFBDAF>            $this->log("謨ー謐ョ蜷梧ュ・螟ア雍・", [
                'project_id' => $project_id,
                'record' => $record,
                'error' => $e->getMessage()
            ]);
        }
        
        $is_syncing = false;
    }
    
    /**
     * Hook: 豈丈クェ鬘オ髱「鬘カ驛ィ
     * 蜉溯<E89C89><E6BAAF>壽ウィ蜈・AI霎<49>勧蠖募<E8A096>逧ЙavaScript
     */
    public function redcap_every_page_top($project_id) {
        // 莉<>惠謨ー謐ョ蠖募<E8A096>鬘オ髱「逕滓譜
        if (strpos(PAGE, 'DataEntry/index.php') !== false) {
            $this->injectAIAssistant();
        }
    }
    
    /**
     * Hook: 謨ー謐ョ蟇シ蜃コ蜑?
     * 蜉溯<E89C89><E6BAAF>壼庄莉・豺サ蜉<EFBDBB>AI蛻<49>梵扈捺棡蟄玲ョオ蛻ー蟇シ蜃?
     */
    public function redcap_custom_verify_username($username) {
        // 鬪瑚ッ<E7919A>€サ霎<EFBDBB>
    }
    
    /**
     * Cron莉サ蜉。: 螳壽慮蜷梧ュ・謨ー謐ョ
     */
    public function syncDataToAIPlatform($cron_info) {
        $projects = $this->getEnabledProjects();
        
        foreach ($projects as $project_id) {
            try {
                // 闔キ蜿夜。ケ逶ョ謇€譛画焚謐?
                $data = REDCap::getData($project_id, 'array');
                
                // 謇ケ驥乗耳騾?
                $result = $this->apiClient->post('/api/v1/redcap/batch-sync', [
                    'project_id' => $project_id,
                    'data' => $data,
                    'timestamp' => time()
                ]);
                
                $this->log("螳壽慮蜷梧ュ・螳梧<E89EB3>", [
                    'project_id' => $project_id,
                    'records_count' => count($data)
                ]);
                
            } catch (\Exception $e) {
                $this->log("螳壽慮蜷梧ュ・螟ア雍・", [
                    'project_id' => $project_id,
                    'error' => $e->getMessage()
                ]);
            }
        }
        
        return "蜷梧ュ・螳梧<E89EB3>";
    }
    
    /**
     * 隗ヲ蜿羨I謨ー謐ョ貂<EFBDAE><EFBFBD>
     */
    private function triggerDataCleaning($project_id, $record) {
        $result = $this->apiClient->post('/api/v1/redcap/dc/clean', [
            'project_id' => $project_id,
            'record' => $record,
            'auto_mode' => true
        ]);
        
        return $result;
    }
    
    /**
     * 豕ィ蜈・AI霎<49>勧蠖募<E8A096>JavaScript
     */
    private function injectAIAssistant() {
        ?>
        <script src="<?= $this->getUrl('js/ai_assistant.js') ?>"></script>
        <script>
            const aiConfig = {
                apiUrl: '<?= $this->getSystemSetting('ai_platform_url') ?>',
                projectId: <?= PROJECT_ID ?>,
                enableAutoComplete: true,
                enableSmartValidation: true
            };
            AiAssistant.init(aiConfig);
        </script>
        <?php
    }
    
    /**
     * 闔キ蜿門星逕ィ讓。蝮礼噪鬘ケ逶ョ蛻苓。?
     */
    private function getEnabledProjects() {
        $sql = "SELECT project_id FROM redcap_external_modules 
                WHERE external_module_id = ? 
                AND directory_prefix = ?";
        $result = $this->query($sql, [
            $this->getModuleId(),
            $this->PREFIX
        ]);
        
        $projects = [];
        while ($row = $result->fetch_assoc()) {
            $projects[] = $row['project_id'];
        }
        
        return $projects;
    }
}

譁ケ譯<EFBFBD>2<EFBFBD>哂I蟷ウ蜿ーBackend API蠑€蜿?

譁ー蠅朿EDCap荳鍋畑讓。蝮<EFBFBD>

// backend/src/modules/redcap/ 逶ョ蠖慕サ捺桷
backend/src/modules/redcap/
笏懌楳笏€ controllers/
?  笏懌楳笏€ RedcapController.ts        // 荳サ謗ァ蛻カ蝎ィ
?  笏懌楳笏€ SyncController.ts          // 謨ー謐ョ蜷梧ュ・謗ァ蛻カ蝎?
?  笏披楳笏€ WebhookController.ts       // Webhook謗ァ蛻カ蝎?
笏懌楳笏€ services/
?  笏懌楳笏€ RedcapApiClient.ts         // REDCap API螳「謌キ遶?
?  笏懌楳笏€ DataTransformService.ts    // 謨ー謐ョ霓ャ謐「譛榊苅
?  笏懌楳笏€ SyncService.ts             // 蜷梧ュ・譛榊苅
?  笏披楳笏€ ProjectMappingService.ts   // 鬘ケ逶ョ譏<EFBDAE><EFBFBD>恪蜉。
笏懌楳笏€ models/
?  笏披楳笏€ redcap.prisma              // Prisma Schema
笏懌楳笏€ routes/
?  笏披楳笏€ redcap.routes.ts           // 霍ッ逕ア螳壻ケ<E5A3BB>
笏披楳笏€ types/
    笏披楳笏€ redcap.types.ts            // TypeScript邀サ蝙句ョ壻ケ<E5A3BB>

Prisma Schema隶セ隶。

// backend/prisma/schema.prisma

// REDCap Schema
datasource redcap_schema {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  schemas  = ["redcap_schema"]
}

// REDCap鬘ケ逶ョ譏<EFBDAE><EFBFBD>。?
model RedcapProject {
  id                String   @id @default(cuid())
  redcapProjectId   Int      @unique         // REDCap鬘ケ逶ョID
  redcapUrl         String                   // REDCap譛榊苅蝎ィ蝨ー蝮€
  redcapApiToken    String   @db.VarChar(64) // API Token (蜉<><EFBFBD>ュ伜お)
  
  // 譏<><EFBFBD><E89F86>邉サ
  dcProjectId       String?  // 蜈ウ閨皮噪DC鬘ケ逶ョID
  ssaProjectId      String?  // 蜈ウ閨皮噪SSA鬘ケ逶ョID
  aslProjectId      String?  // 蜈ウ閨皮噪ASL鬘ケ逶ョID
  
  // 蜷梧ュ・驟咲スョ
  syncEnabled       Boolean  @default(true)
  syncMode          String   @default("realtime") // realtime, scheduled, manual
  lastSyncAt        DateTime?
  
  // 蜈<>焚謐?
  projectName       String
  projectDescription String? @db.Text
  
  createdAt         DateTime @default(now())
  updatedAt         DateTime @updatedAt
  
  // 蜈ウ閨泌<E996A8>邉サ
  syncRecords       RedcapSyncRecord[]
  fieldMappings     RedcapFieldMapping[]
  
  @@map("redcap_projects")
  @@schema("redcap_schema")
}

// REDCap蜷梧ュ・隶ー蠖戊。?
model RedcapSyncRecord {
  id              String   @id @default(cuid())
  projectId       String
  project         RedcapProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
  
  recordId        String   // REDCap隶ー蠖肘D
  eventId         String?  // REDCap莠倶サカID
  instrument      String?  // 陦ィ蜊募錐遘ー
  
  // 蜷梧ュ・迥カ諤?
  status          String   // pending, syncing, success, failed
  direction       String   // redcap_to_ai, ai_to_redcap
  
  // 謨ー謐ョ蠢ォ辣ァ
  redcapData      Json     // REDCap蜴溷ァ区焚謐ョ
  aiPlatformData  Json?    // AI蟷ウ蜿ー螟<EFBDB0>炊蜷取焚謐?
  
  // 髞呵ッッ菫。諱ッ
  errorMessage    String?  @db.Text
  retryCount      Int      @default(0)
  
  syncedAt        DateTime @default(now())
  
  @@map("redcap_sync_records")
  @@schema("redcap_schema")
  @@index([projectId, recordId])
  @@index([status])
}

// REDCap蟄玲ョオ譏<EFBDB5><EFBFBD>。?
model RedcapFieldMapping {
  id              String   @id @default(cuid())
  projectId       String
  project         RedcapProject @relation(fields: [projectId], references: [id], onDelete: Cascade)
  
  // REDCap蟄玲ョオ菫。諱ッ
  redcapFieldName String
  redcapFieldLabel String?
  redcapFieldType String   // text, radio, checkbox, dropdown, etc.
  
  // AI蟷ウ蜿ー蟄玲ョオ譏<EFBDB5><EFBFBD>
  aiPlatformField String?  // 譏<><EFBFBD>芦AI蟷ウ蜿ー逧<EFBDB0>ュ玲ョオ蜷<EFBDB5>
  transformRule   Json?    // 霓ャ謐「隗<EFBDA2><E99A97><EFBFBD><EFBFBD>SON<4F>?
  
  // 譏<><EFBFBD><E89F86>鄂ョ
  isRequired      Boolean  @default(false)
  isIdentifier    Boolean  @default(false)  // 譏ッ蜷ヲ荳コ荳サ髞ョ蟄玲ョ?
  
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
  
  @@map("redcap_field_mappings")
  @@schema("redcap_schema")
  @@unique([projectId, redcapFieldName])
}

REDCap API霍ッ逕ア螳壻ケ<E5A3BB>

// backend/src/modules/redcap/routes/redcap.routes.ts

import { FastifyInstance } from 'fastify';
import { RedcapController } from '../controllers/RedcapController';
import { SyncController } from '../controllers/SyncController';
import { WebhookController } from '../controllers/WebhookController';

export async function redcapRoutes(fastify: FastifyInstance) {
  const redcapController = new RedcapController();
  const syncController = new SyncController();
  const webhookController = new WebhookController();
  
  // ========== 鬘ケ逶ョ邂。逅<EFBDA1> ==========
  
  // 蛻帛サコREDCap鬘ケ逶ョ譏<EFBDAE><EFBFBD>
  fastify.post('/api/v1/redcap/projects', 
    redcapController.createProject
  );
  
  // 闔キ蜿夜。ケ逶ョ蛻苓。ィ
  fastify.get('/api/v1/redcap/projects', 
    redcapController.listProjects
  );
  
  // 闔キ蜿夜。ケ逶ョ隸ヲ諠<EFBDA6>
  fastify.get('/api/v1/redcap/projects/:id', 
    redcapController.getProject
  );
  
  // 譖エ譁ー鬘ケ逶ョ驟咲スョ
  fastify.put('/api/v1/redcap/projects/:id', 
    redcapController.updateProject
  );
  
  // 蛻<>髯、鬘ケ逶ョ譏<EFBDAE><EFBFBD>
  fastify.delete('/api/v1/redcap/projects/:id', 
    redcapController.deleteProject
  );
  
  // ========== 謨ー謐ョ蜷梧ュ・ ==========
  
  // 謇句勘隗ヲ蜿大酔豁・<E8B181><EFBDA5>EDCap 竊?AI蟷ウ蜿ー<E89CBF>?
  fastify.post('/api/v1/redcap/sync/import/:projectId', 
    syncController.importFromRedcap
  );
  
  // 謗ィ騾∵焚謐ョ蛻ーREDCap<61><70>I蟷ウ蜿ー 竊?REDCap<61>?
  fastify.post('/api/v1/redcap/sync/export/:projectId', 
    syncController.exportToRedcap
  );
  
  // 譟・隸「蜷梧ュ・迥カ諤?
  fastify.get('/api/v1/redcap/sync/status/:projectId', 
    syncController.getSyncStatus
  );
  
  // 譟・隸「蜷梧ュ・蜴<EFBDA5>  fastify.get('/api/v1/redcap/sync/history/:projectId', 
    syncController.getSyncHistory
  );
  
  // ========== Webhook謗・謾カ ==========
  
  // REDCap External Module謗ィ騾∵焚謐ョ<E8AC90>亥ョ樊慮蜷梧ュ・<EFBDAD>?
  fastify.post('/api/v1/redcap/webhook/records', 
    webhookController.receiveRecordUpdate
  );
  
  // 謇ケ驥丞酔豁・<E8B181>亥ョ壽慮莉サ蜉。<E89C89><EFBDA1>
  fastify.post('/api/v1/redcap/webhook/batch-sync', 
    webhookController.receiveBatchSync
  );
  
  // ========== 蟄玲ョオ譏<EFBDB5><EFBFBD>ョ。逅<EFBDA1> ==========
  
  // 闔キ蜿乏EDCap鬘ケ逶ョ蜈<EFBDAE>焚謐ョ<E8AC90>亥ュ玲ョオ蛻苓。ィ<EFBDA1>?
  fastify.get('/api/v1/redcap/projects/:id/metadata', 
    redcapController.getProjectMetadata
  );
  
  // 蛻帛サコ/譖エ譁ー蟄玲ョオ譏<EFBDB5><EFBFBD>
  fastify.post('/api/v1/redcap/projects/:id/field-mappings', 
    redcapController.upsertFieldMappings
  );
  
  // 闔キ蜿門ュ玲ョオ譏<EFBDB5><EFBFBD>
  fastify.get('/api/v1/redcap/projects/:id/field-mappings', 
    redcapController.getFieldMappings
  );
  
  // ========== AI蜉溯<E89C89><EFBFBD><E9ABAE> ==========
  
  // 隗ヲ蜿第焚謐ョ貂<EFBDAE>エ暦シ<E69AA6>C讓。蝮暦シ?
  fastify.post('/api/v1/redcap/dc/clean', 
    redcapController.triggerDataCleaning
  );
  
  // 隗ヲ蜿醍サ溯ョ。蛻<EFBDA1><EFBFBD><E6A2B5>SA讓。蝮暦シ?
  fastify.post('/api/v1/redcap/ssa/analyze', 
    redcapController.triggerStatisticalAnalysis
  );
  
  // 闔キ蜿泡I蛻<49>梵扈捺棡
  fastify.get('/api/v1/redcap/analysis/:recordId', 
    redcapController.getAnalysisResults
  );
}

譬ク蠢イontroller螳樒鴫

// backend/src/modules/redcap/controllers/SyncController.ts

import { FastifyRequest, FastifyReply } from 'fastify';
import { prisma } from '@/config/database';
import { logger } from '@/common/logging';
import { RedcapApiClient } from '../services/RedcapApiClient';
import { DataTransformService } from '../services/DataTransformService';

export class SyncController {
  
  /**
   * 莉山EDCap蟇シ蜈・謨ー謐ョ蛻ーAI蟷ウ蜿ー
   */
  async importFromRedcap(
    req: FastifyRequest<{ Params: { projectId: string } }>,
    res: FastifyReply
  ) {
    const { projectId } = req.params;
    
    try {
      // 1. 闔キ蜿夜。ケ逶ョ驟咲スョ
      const project = await prisma.redcapProject.findUnique({
        where: { id: projectId },
        include: { fieldMappings: true }
      });
      
      if (!project) {
        return res.status(404).send({ 
          success: false, 
          error: '鬘ケ逶ョ荳榊ュ伜<EFBDAD>? 
        });
      }
      
      // 2. 隹<>畑REDCap API闔キ蜿匁焚謐ョ
      const redcapClient = new RedcapApiClient(
        project.redcapUrl,
        project.redcapApiToken
      );
      
      const redcapData = await redcapClient.exportRecords({
        format: 'json',
        type: 'flat'
      });
      
      logger.info('莉山EDCap闔キ蜿匁焚謐ョ謌仙粥', { 
        projectId, 
        recordCount: redcapData.length 
      });
      
      // 3. 謨ー謐ョ霓ャ謐「
      const transformer = new DataTransformService();
      const transformedData = await transformer.redcapToAIPlatform(
        redcapData,
        project.fieldMappings
      );
      
      // 4. 蟄伜お蛻ーAI蟷ウ蜿ー謨ー謐ョ蠎?
      // 譬ケ謐ョ鬘ケ逶ョ驟咲スョ<EFBDBD>梧耳騾∝芦DC/SSA/ASL遲画ィ。蝮?
      if (project.dcProjectId) {
        await this.importToDCModule(project.dcProjectId, transformedData);
      }
      
      if (project.ssaProjectId) {
        await this.importToSSAModule(project.ssaProjectId, transformedData);
      }
      
      // 5. 隶ー蠖募酔豁・蜴<EFBDA5>      await prisma.redcapSyncRecord.create({
        data: {
          projectId,
          recordId: 'batch_import',
          status: 'success',
          direction: 'redcap_to_ai',
          redcapData: redcapData as any,
          aiPlatformData: transformedData as any
        }
      });
      
      // 6. 譖エ譁ー蜷梧ュ・譌カ髣エ
      await prisma.redcapProject.update({
        where: { id: projectId },
        data: { lastSyncAt: new Date() }
      });
      
      return res.send({
        success: true,
        message: '謨ー謐ョ蟇シ蜈・謌仙粥',
        data: {
          recordCount: redcapData.length,
          transformedCount: transformedData.length
        }
      });
      
    } catch (error) {
      logger.error('REDCap謨ー謐ョ蟇シ蜈・螟ア雍・', { 
        projectId, 
        error: error.message 
      });
      
      return res.status(500).send({
        success: false,
        error: '謨ー謐ョ蟇シ蜈・螟ア雍・',
        details: error.message
      });
    }
  }
  
  /**
   * 蟇シ蜈・蛻ーDC讓。蝮<EFBDA1>
   */
  private async importToDCModule(dcProjectId: string, data: any[]) {
    // 隹<>畑DC讓。蝮礼噪蟇シ蜈・API
    // TODO: 螳樒鴫DC讓。蝮鈴寔謌宣€サ霎<EFBDBB>
  }
  
  /**
   * 蟇シ蜈・蛻ーSSA讓。蝮<EFBDA1>
   */
  private async importToSSAModule(ssaProjectId: string, data: any[]) {
    // 隹<>畑SSA讓。蝮礼噪蟇シ蜈・API
    // TODO: 螳樒鴫SSA讓。蝮鈴寔謌宣€サ霎<EFBDBB>
  }
}

<EFBFBD>投 謨ー謐ョ豬∬ョセ隶?

謨ー謐ョ豬?<3F>啌EDCap 竊?AI蟷ウ蜿ー<E89CBF>亥ョ樊慮蜷梧ュ・<EFBDAD><EFBDA5>

笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 1: 逕ィ謌キ蝨ィREDCap蠖募<E8A096>謨ー謐ョ                             笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? 遐皮ゥカ莠コ蜻伜惠REDCap陦ィ蜊穂クュ蠖募<E8A096>謔」閠<EFBDA3>焚謐?                       笏?
笏? 萓句ヲゑシ壽ぅ閠<E38185>D縲∝ケエ鮴<EFBDB4>€€ァ蛻ォ縲∬ッ頑妙縲∵」€鬪檎サ捺棡遲<E6A3A1>                 笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                       竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 2: REDCap隗ヲ蜿喪edcap_save_record Hook              笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? External Module謐戊執菫晏ュ倅コ倶サカ                              笏?
笏? 闔キ蜿厄シ嗔roject_id, record, instrument, event_id         笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                       竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 3: 謨ー謐ョ闔キ蜿紋ク取丐蟆?                                  笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? 1. 隹<>畑REDCap::getData()闔キ蜿門ョ梧紛隶ー蠖<EFBDB0>                     笏?
笏? 2. DataMapper霓ャ謐「REDCap EAV譬シ蠑鞘<E8A091>AI蟷ウ蜿ー譬<EFBDB0>㊥譬シ蠑<EFBDBC>           笏?
笏? 3. 蠎皮畑蟄玲ョオ譏<EFBDB5><EFBFBD><EFBFBD><EFBDA7><EFBFBD><EFBFBD>edcap_field_mappings陦ィ<E999A6><EFBDA8>           笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                       竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 4: HTTP POST謗ィ騾∝芦AI蟷ウ蜿ーAPI                        笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? URL: https://ai.yizx.com/api/v1/redcap/webhook/records 笏?
笏? Payload: {                                             笏?
笏?   project_id: 123,                                     笏?
笏?   record_id: "PAT001",                                 笏?
笏?   data: {...},                                         笏?
笏?   timestamp: 1735542000                                笏?
笏? }                                                      笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                       竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 5: AI蟷ウ蜿ー謗・謾カ蟷カ螟<EFBDB6><E89E9F>?                                笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? 1. WebhookController鬪瑚ッ∬ッキ豎らュセ蜷<EFBDBE>                         笏?
笏? 2. 蟄伜お蜴溷ァ区焚謐ョ蛻ーredcap_sync_records陦?                  笏?
笏? 3. 蠑よュ・隗ヲ蜿羨I螟<49>炊莉サ蜉。<E89C89><EFBDA1>C/SSA讓。蝮暦シ?                      笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
                       竊?
笏娯楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?
笏? Step 6: AI螟<49>炊荳守サ捺棡霑泌<E99C91>?                                笏?
笏? 笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€  笏?
笏? 1. DC讓。蝮暦シ壽焚謐ョ貂<EFBDAE>エ励€¨ER謠仙叙縲∫シコ螟ア蛟シ螟<EFBDBC><E89E9F>?                 笏?
笏? 2. SSA讓。蝮暦シ夊<EFBDBC>蜉ィ扈溯ョ。蛻<EFBDA1>梵縲∫函謌仙庄隗<E5BA84>喧蝗セ陦ィ                  笏?
笏? 3. 扈捺棡蟄伜お蛻ーAI蟷ウ蜿ー謨ー謐ョ蠎?                               笏?
笏? 4. <20>亥庄騾会シ牙屓蜀咏サ捺棡蛻ーREDCap<61>€夊ソ②PI<50>?                   笏?
笏披楳笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏€笏?

謨ー謐ョ豬?<3F>哂I蟷ウ蜿ー 竊?REDCap<61><EFBFBD>譫千サ捺棡蝗槫<E89D97><E6A7AB><EFBFBD>

AI蟷ウ蜿ー螳梧<EFBFBD><EFBFBD>梵
     竊?
逕滓<E98095><EFBFBD>梵扈捺棡<E68DBA><E6A3A1>SON<4F>?
     竊?
隹<>畑REDCap API: importRecords
     竊?
REDCap蟄伜お扈捺棡蛻ー迚ケ螳壼ュ玲ョ?
     竊?
遐皮ゥカ莠コ蜻伜惠REDCap荳ュ譟・逵帰I蛻<49>梵扈捺棡

<EFBFBD>噫 蠑€蜿題ョ。蛻剃ク主ョ樊命豁・鬪、

Phase 1: 蝓コ遑€蟇ケ謗・<E8AC97><EFBDA5>eek 1-2<>俄怛 莨伜<E88EA8>郤ァP0

逶ョ譬<EFBFBD><EFBFBD>壼サコ遶騎EDCap荳拶I蟷ウ蜿ー逧<EFBFBD>渕譛ャ霑樊<EFBFBD>?

Week 1: External Module鬪ィ譫カ

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • 蛻帛サコExternal Module逶ョ蠖慕サ捺桷
  • 郛門<EFBFBD>config.json驟咲スョ譁<EFBDAE>サカ
  • 螳樒鴫AiResearchAssistantModule.php蝓コ遑€邀?
  • 螳樒鴫redcap_save_record Hook<6F>亥渕遑€迚茨シ<E88CA8>
  • €蜿羨piClient.php<68><70>TTP螳「謌キ遶ッ<E981B6><EFBDAF>
  • 豬玖ッ包シ啌EDCap菫晏ュ俶焚謐ョ竊呈遠蜊ー譌・蠢?

**莠、莉倡<E88E89>?*<2A>?

  • ai_research_assistant_v1.0.0/ 螳梧紛逶ョ蠖<EFBDAE>
  • 蜿ッ蝨ィREDCap荳ュ蜷ッ逕ィ逧Еxternal Module
  • 蝓コ遑€譌・蠢苓ョー蠖募粥閭ス

Week 2: AI蟷ウ蜿ーAPI遶ッ轤ケ

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • 蛻帛サコredcap_schema謨ー謐ョ蠎鉄chema
  • 螳樒鴫Prisma讓。蝙具シ<EFBFBD>edcapProject遲?荳ェ陦ィ<E999A6>?
  • €蜿糎ebhookController謗・謾カ謨ー謐ョ
  • 螳樒鴫謨ー謐ョ霓ャ謐「譛榊苅DataTransformService
  • €蜿鷹。ケ逶ョ邂。逅<EFBFBD>PI<EFBFBD><EFBFBD>RUD<EFBFBD>?
  • 豬玖ッ包シ啌EDCap謗ィ騾≫<EFBFBD>AI蟷ウ蜿ー謗・謾カ竊貞ュ伜<EFBFBD>?

**莠、莉倡<E88E89>?*<2A>?

  • /api/v1/redcap/* API遶ッ轤ケ
  • PostgreSQL redcap_schema蛻帛サコ
  • Postman豬玖ッ暮寔蜷<EFBFBD>

Phase 2: 謨ー謐ョ蜷梧ュ・荳取丐蟆<E4B890><EFBFBD>eek 3-4<>俄ュ<E4BF84> 莨伜<E88EA8>郤ァP1

逶ョ譬<EFBFBD><EFBFBD>壼ョ樒鴫蜿悟髄謨ー謐ョ蜷梧ュ・蜥悟ュ玲ョオ譎コ閭ス譏<EFBFBD><EFBFBD>

Week 3: 蟄玲ョオ譏<EFBDB5><EFBFBD>ウサ扈<EFBDBB>

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • €蜿大ュ玲ョオ譏<EFBFBD><EFBFBD>ョ。逅<EFBFBD>I<EFBFBD>亥燕遶ッReact<EFBFBD>?
  • 螳樒鴫REDCap蜈<EFBFBD>焚謐ョ闔キ蜿泡PI
  • €蜿大ュ玲ョオ譏<EFBFBD><EFBFBD><EFBFBD>鄂ョ逡碁<EFBFBD>?
  • 螳樒鴫譏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蠑墓梼<EFBFBD><EFBFBD>ataMapper<EFBFBD>?
  • 謾ッ謖∝、肴揩霓ャ謐「<EFBFBD>亥ヲゑシ壼黒菴崎スャ謐「縲∫シ也<EFBFBD>∵丐蟆<EFBFBD><EFBFBD>
  • 豬玖ッ包シ壽丐蟆<EFBFBD><EFBFBD>鄂ョ竊呈焚謐ョ霓ャ謐「鬪瑚ッ<EFBFBD>

**莠、莉倡<E88E89>?*<2A>?

  • 蟄玲ョオ譏<EFBFBD>蟆ФI鬘オ髱「
  • <EFBFBD><EFBFBD><EFBFBD><EFBFBD>蠑墓梼
  • 驟咲スョ譁<EFBFBD>。」

Week 4: 蜿悟髄蜷梧ュ・

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • 螳樒鴫謇ケ驥乗焚謐ョ蟇シ蜈・<EFBFBD><EFBFBD>EDCap 竊?AI<41>?
  • 螳樒鴫蛻<EFBFBD>梵扈捺棡蝗槫<EFBFBD><EFBFBD><EFBFBD>I 竊?REDCap<61>?
  • €蜿舛ron螳壽慮蜷梧ュ・莉サ蜉。
  • 螳樒鴫蜷梧ュ・迥カ諤∫尅謗ァ逡碁<EFBFBD>?
  • 髞呵ッッ螟<EFBFBD>炊荳朱㍾隸墓惻蛻?
  • 豬玖ッ包シ壼ョ梧紛蜷梧ュ・豬∫ィ?

**莠、莉倡<E88E89>?*<2A>?

  • 蜿悟髄蜷梧ュ・蜉溯<EFBFBD>
  • 蜷梧ュ・逶第而Dashboard
  • 髞呵ッッ螟<EFBFBD>炊譛コ蛻カ

Phase 3: AI蜉溯<E89C89><EFBFBD><E9ABAE><EFBFBD><EFBFBD>eek 5-6<>解沁?莨伜<E88EA8>郤ァP1

逶ョ譬<EFBFBD><EFBFBD>夐寔謌織C縲ヾSA縲、IA遲陰I讓。蝮<EFBFBD>

Week 5: DC讓。蝮鈴寔謌<E5AF94>

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • REDCap謨ー謐ョ竊奪C讓。蝮苓<EFBFBD>蜉ィ貂<EFBFBD><EFBFBD>
  • <EFBFBD>エ礼サ捺棡竊坦EDCap蝗槫<EFBFBD>
  • 蝨ィREDCap荳ュ螻慕、コ貂<EFBFBD>エ玲冠蜻?
  • 謾ッ謖∵焔蜉ィ隗ヲ蜿第ク<EFBFBD><EFBFBD>
  • 豬玖ッ包シ壼ス募<EFBFBD>竊呈ク<EFBFBD>エ冷<EFBFBD>譟・逵狗サ捺<EFBFBD>?

**莠、莉倡<E88E89>?*<2A>?

  • DC髮<EFBFBD><EFBFBD>API
  • REDCap貂<EFBFBD>エ玲冠蜻企。オ髱「

Week 6: SSA讓。蝮鈴寔謌<E5AF94>

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • REDCap謨ー謐ョ竊担SA讓。蝮苓<EFBFBD>蜉ィ蛻<EFBFBD>
  • 謾ッ謖∽ク牙、ァ蛻<EFBFBD>梵霍ッ蠕<EFBFBD>シ磯弌蛻?鬚<><EFBFBD>/RCT<43>?
  • 蝨ィREDCap荳ュ蠏悟<EFBFBD>扈溯ョ。謚・蜻?
  • 蜿ッ隗<EFBFBD>喧蝗セ陦ィ螻慕、?
  • 豬玖ッ包シ壽焚謐ョ蠖募<EFBFBD>竊定<EFBFBD>蜉ィ蛻<EFBFBD>梵竊呈冠蜻顔函謌?

**莠、莉倡<E88E89>?*<2A>?

  • SSA髮<EFBFBD><EFBFBD>API
  • 扈溯ョ。謚・蜻雁オ悟<EFBFBD>鬘オ髱「

Phase 4: 鬮倡コァ蜉溯<E89C89><E6BAAF><EFBFBD>eek 7-8<>解沍?莨伜<E88EA8>郤ァP2

逶ョ譬<EFBFBD><EFBFBD>哂I霎<EFBFBD>勧蠖募<EFBFBD>縲∵匱閭ス雍ィ謗ァ遲牙「槫€シ蜉溯<EFBFBD>?

Week 7: AI霎<49>勧蠖募<E8A096>

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • €蜿第匱閭ス閾ェ蜉ィ螳梧<EFBFBD><EFBFBD>亥渕莠主紙蜿イ謨ー謐ョ<EFBFBD>?
  • 蠑ょクク蛟シ鬚<EFBFBD>ュヲ<EFBFBD>亥ョ樊慮AI蛻、譁ュ<EFBFBD>?
  • 蟄玲ョオ蜈ウ閨疲耳闕撰シ<EFBFBD>I鬚<EFBFBD>オ具シ?
  • 蠖募<EFBFBD>謨育紫謠仙合扈溯ョ。
  • 豬玖ッ包シ壼ス募<EFBFBD>菴馴ェ御シ伜喧鬪瑚ッ?

**莠、莉倡<E88E89>?*<2A>?

  • AI霎<EFBFBD>勧蠖募<EFBFBD>JS謠剃サカ
  • 譎コ閭ス雍ィ謗ァ隗<EFBFBD><EFBFBD>蠑墓梼

Week 8: 扈シ蜷域オ玖ッ穂ク惹シ伜<EFBDBC>?

莉サ蜉。貂<EFBFBD><EFBFBD>?

  • 諤ァ閭ス豬玖ッ包シ?00荳<30>擅隶ー蠖募酔豁・<E8B181>?
  • 螳牙<EFBFBD>豬玖ッ包シ<EFBFBD>PI隶、隸√€∵焚謐ョ蜉<EFBFBD><EFBFBD><EFBFBD>
  • 逕ィ謌キ鬪梧噺豬玖ッ包シ<EFBFBD>AT<EFBFBD>?
  • <EFBFBD>。」郛門<EFBFBD><EFBFBD>育畑謌キ謇句<EFBFBD>?蠑€蜿第枚譯」<E8ADAF><EFBDA3>
  • 驛ィ鄂イ蛻ー逕滉コァ邇ッ蠅?

**莠、莉倡<E88E89>?*<2A>?

  • 諤ァ閭ス豬玖ッ墓冠蜻<EFBFBD>
  • 螳梧紛譁<EFBFBD>。」
  • 逕滉コァ邇ッ蠅<EFBFBD>Κ鄂イ

<EFBFBD>白 螳牙<E89EB3>諤ァ隶セ隶?

API隶、隸∵惻蛻カ

// 菴ソ逕ィHMAC-SHA256遲セ蜷埼ェ瑚ッ<E7919A>

// REDCap External Module蜿鷹€∬ッキ豎よ慮
const timestamp = Date.now();
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(`${timestamp}${JSON.stringify(payload)}`)
  .digest('hex');

// Headers:
{
  'X-API-Key': apiKey,
  'X-Timestamp': timestamp,
  'X-Signature': signature
}

// AI蟷ウ蜿ー鬪瑚ッ<E7919A>
function verifySignature(req) {
  const { timestamp, signature } = req.headers;
  const expectedSignature = crypto
    .createHmac('sha256', apiSecret)
    .update(`${timestamp}${JSON.stringify(req.body)}`)
    .digest('hex');
  
  return signature === expectedSignature;
}

謨ー謐ョ蜉<EFBFBD><EFBFBD>

  • REDCap API Token<65>壻スソ逕ィAES-256蜉<36><EFBFBD>ュ伜お
  • <EFBFBD>霎灘刈蟇<EFBFBD>シ壼シコ蛻カHTTPS
  • 謨乗─蟄玲ョオ<EFBFBD>壽髪謖∝ュ玲ョオ郤ァ蜉<EFBFBD><EFBFBD><EFBFBD>HI謨ー謐ョ<EFBFBD>?

<EFBFBD>剞謗ァ蛻カ

// REDCap逕ィ謌キ譚<EFBDB7>剞蜷梧ュ・蛻ーAI蟷ウ蜿ー
interface UserPermission {
  userId: string;
  redcapRights: {
    data_entry: boolean;
    data_export: boolean;
    data_analysis: boolean;
  };
  aiPlatformRights: {
    dc_access: boolean;
    ssa_access: boolean;
    asl_access: boolean;
  };
}

<EFBFBD>答 謚€譛ッ譬域€サ扈<EFBDBB>

螻らコァ REDCap萓? AI蟷ウ蜿ー萓?
郛也ィ玖ッュ險€ PHP 7.4+ TypeScript/Node.js 22
<EFBFBD> REDCap EM Framework v16 Fastify v4
*謨ー謐ョ蠎? MySQL 5.7+ PostgreSQL 15
謨ー謐ョ讓。蝙<EFBFBD> EAV讓。蝙<EFBFBD> 蜈ウ邉サ蝙?JSONB
蜑咲ォッ jQuery + Bootstrap 5 React 19 + Ant Design 6
API REDCap RESTful API Fastify RESTful API
隶、隸<EFBFBD> API Token HMAC-SHA256遲セ蜷<EFBDBE>
譌・蠢<EFBFBD> REDCap譌・蠢苓。? Winston + SLS
莉サ蜉。髦溷<EFBFBD> REDCap Cron pg-boss (Postgres-Only)

<EFBFBD>統 荳倶ク€豁・陦悟<E999A6>?

遶句叉陦悟勘<EFBFBD>域悽蜻ィ<EFBFBD><EFBFBD>

  1. **遑ョ隶、髴€豎?*<2A>?

    • 遑ョ隶、莨伜<EFBFBD>郤ァ<EFBFBD><EFBFBD>C莨伜<EFBFBD><EFBFBD>溯ソ俶弍SSA莨伜<EFBFBD><EFBFBD>滂シ<EFBFBD>
    • 遑ョ隶、驛ィ鄂イ蠖「諤<EFBFBD>シ井コ醍ォッSaaS<EFBFBD>溯ソ俶弍遘∵怏蛹夜Κ鄂イ<EFBFBD>滂シ<EFBFBD>
    • 遑ョ隶、REDCap譛榊苅蝎ィ菫。諱ッ<EFBFBD><EFBFBD>RL縲∫沿譛ャ縲∬ョソ髣ョ譚<EFBFBD><EFBFBD><EFBFBD>
  2. 邇ッ蠅<EFBFBD>㊥螟<EFBFBD><EFBFBD>?

    • 謳ュ蟒コREDCap豬玖ッ慕識蠅<EFBFBD>シ井スソ逕ィDocker<EFBFBD>?
    • 蛻帛サコ豬玖ッ暮。ケ逶ョ蜥梧オ玖ッ墓焚謐?
    • 驟咲スョAI蟷ウ蜿ー豬玖ッ柊PI
  3. **蜷ッ蜉ィ蠑€蜿?*<2A>?

    • 蛻帛サコExternal Module逶ョ蠖<EFBDAE>
    • 蛻晏ァ句喧Git莉灘コ<EFBFBD>
    • 郛門<EFBFBD>config.json

€譛ッ鬚<EFBFBD><EFBFBD>?

  1. REDCap API豺ア蜈・豬玖ッ<E78E96>
  2. External Module Hook譛コ蛻カ鬪瑚ッ<E7919A>
  3. 螟ァ謨ー謐ョ驥丞酔豁・諤ァ閭ス豬玖ッ<EFBFBD>
  4. *遘サ蜉ィ遶ッ<EFBFBD><EFBFBD>EDCap Mobile App<70>蛾寔謌仙庄陦梧€?

<EFBFBD>識 謌仙粥譬<E7B2A5>

**MVP迚域悽<E59F9F><E682BD>hase 1-2螳梧<E89EB3><E6A2A7>?*<2A>?

  • 笨?REDCap謨ー謐ョ閭ス謗ィ騾∝芦AI蟷ウ蜿ー
  • 笨?AI蟷ウ蜿ー閭ス謗・謾カ蟷カ蟄伜お謨ー謐ョ
  • 笨?蟄玲ョオ譏<EFBDB5><EFBFBD><E89F86>鄂ョ蜉溯<E89C89>蜿ッ逕ィ
  • 笨?蝓コ遑€蜷梧ュ・逶第而蜿ッ逕ィ

**譬<>㊥迚域悽<E59F9F><E682BD>hase 3螳梧<E89EB3><E6A2A7>?*<2A>?

  • 笨?DC讓。蝮鈴寔謌仙ョ梧<EFBDAE><E6A2A7><EFBFBD>蜉ィ貂<EFBDA8>エ暦シ<E69AA6>
  • 笨?SSA讓。蝮鈴寔謌仙ョ梧<EFBDAE><E6A2A7><EFBFBD>蜉ィ蛻<EFBDA8><EFBFBD><E6A2B5>
  • 笨?蛻<>梵扈捺棡蜿ッ蝨ィREDCap荳ュ譟・逵?
  • 笨?逕ィ謌キ菴馴ェ梧オ∫腐

**莨∽ク夂沿譛ャ<E8AD9B><EFBDAC>hase 4螳梧<E89EB3><E6A2A7>?*<2A>?

  • 笨?AI霎<49>勧蠖募<E8A096>謠仙合謨育紫50%+
  • 笨?譎コ閭ス雍ィ謗ァ蜃丞ー鷹漠隸ッ邇?0%+
  • 笨?謾ッ謖<EFBDAF>100荳?隶ー蠖募酔豁・
  • 笨?螳牙<E89EB3>蜷郁ァ<E98381>シ育ャヲ蜷<EFBDA6>DA 21 CFR Part 11<31>?

<EFBFBD>。」迚域悽<EFBFBD>嘛1.0
**譛€蜷取峩譁?*<2A>?025-12-30
荳区ャ。譖エ譁ー<EFBFBD>啀hase 1蜷ッ蜉ィ蜷取峩譁ー蠑€蜿題ソ帛コ?


<EFBFBD>噫 蜃<><EFBFBD>・ス蠑€蟋倶コ<E580B6><EFBFBD>溯ョゥ謌台サャ蠑€蜷ッREDCap荳拶I逧<49>檮蜷井ケ区羅<E58CBA><E7BE85>