Files
AIclinicalresearch/docs/03-业务模块/Redcap/00-模块概览/03-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

32 KiB
Raw Blame History

REDCap撖寞𦻖憌𡡞埯霂<EFBFBD>摯銝擧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>䀹楛摨血<EFBFBD><EFBFBD>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗? v1.0
<EFBFBD>𥕦遣<EFBFBD><EFBFBD>嚗? 2025-12-30
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗? <20><><EFBFBD><EFBFBD>萘輕<E89098><E8BC95><EFBFBD>REDCap撖寞𦻖<E5AF9E><F0A6BB96><EFBFBD><EFBFBD>舫𠗕<E888AB><EFBFBD><E5AB98><EFBFBD><EFBFBD>舀綉<E88880><EFBFBD><E588A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E588B8>? <EFBFBD><EFBFBD><EFBFBD>園𡢿嚗? 20<32><30><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 潃鐥<E6BD83>潃鐥<E6BD83>潃?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>


<EFBFBD><EFBFBD> <20><>﹝霂湔<E99C82>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<EFBFBD><EFBFBD><EFBFBD><EFBFBD>萘輕<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞉䲮瘜𤏪<EFBFBD><EFBFBD><EFBFBD>REDCap撖寞𦻖憿寧𤌍<EFBFBD><EFBFBD><EFBFBD>

  1. **<2A><><EFBFBD>舫𠗕<E888AB>?*嚗?憭扳瓲敹<E793B2>𠗕憸矋<E686B8>
  2. **銝滚虾<E6BB9A><EFBFBD>蝝?*嚗?銝芷<E98A9D><E88AB7><EFBFBD><E398BE><EFBFBD>
  3. **憭齿<E686AD>摨西<E691A8>隡?*嚗<><E59A97><EFBFBD><EFBFBD>EDC撖寞<E69296>嚗?
  4. **憭梯揖獢<E68F96><E78DA2><EFBFBD><EFBFBD><EFBFBD>**嚗<><E59A97><EFBFBD>諹萱<E8ABB9>𤑳<EFBFBD>撉䕘<E69289>
  5. <EFBFBD><EFBFBD>蝑𣇉裦<EFBFBD><EFBFBD>雿閖<EFBFBD>雿𡡞<EFBFBD><EFBFBD><EFBFBD>

**<2A><EFBFBD><E8A9A8><EFBFBD>**嚗?

  • <EFBFBD>?REDCap<61><70>AV璅<E79285><E288AA>臬炏隡𡁏<E99AA1>銝箸<E98A9D><EFBFBD><E689AF><EFBFBD>嚗?
  • <EFBFBD>?External Module獢<65><EFBFBD><E6B2B2><EFBFBD><EFBFBD><EFBFBD>憭𡁜之嚗?
  • <EFBFBD>?<3F><>𧋦<EFBFBD><F0A78BA6>漣隡帋<E99AA1>隡𡁶聦<F0A181B6>𤩺<EFBFBD>隞祉<E99A9E><E7A589><EFBFBD><EFBFBD>嚗?
  • <EFBFBD>?<3F>唳旿銝<E697BF><E98A9D><EFBFBD><EFBFBD>雿蓥<E99BBF><EFBFBD><E99C82>
  • <EFBFBD>?<3F>臬炏<E887AC><EFBFBD><E6BE86><EFBFBD>嚗㇌OI<4F><49><EFBFBD>嚗㚁<E59A97>

<EFBFBD><20><EFBFBD>憌𡡞埯璁<E59FAF><E79281><EFBFBD><EFBFBD>航郎<E888AA>𠺪<EFBFBD>

憌𡡞埯蝑厩漣<EFBFBD><EFBFBD>

憌𡡞埯蝐餃<EFBFBD> 憌𡡞埯蝑厩漣 敶勗<EFBFBD><EFBFBD><EFBFBD> <EFBFBD>舀綉<EFBFBD>? 撱箄悅
EAV璅<EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? <EFBFBD>唳旿<EFBFBD>?10銝<30><EFBFBD>? <EFBFBD>𩤃<EFBFBD> <20><EFBFBD><E585B8>舀綉 <EFBFBD>◆霈曇恣蝻枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
*REDCap<EFBFBD><EFBFBD><EFBFBD>澆捆<EFBFBD>? <EFBFBD>𣞁 擃? 瘥𤩺活REDCap<EFBFBD><EFBFBD> <EFBFBD>?銝滚虾<E6BB9A>? 銝交聢<EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD>+<2B>𧼮<EFBFBD>瘚贝<E7989A>
*<EFBFBD>唳旿銝<EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>椬 銝? <EFBFBD><EFBFBD><EFBFBD><EFBFBD>峕郊<EFBFBD>箸艶 <EFBFBD>?<3F>舀綉 霈曇恣撟<EFBFBD><EFBFBD><EFBFBD>?<3F><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>
API<EFBFBD><EFBFBD> <EFBFBD>椬 銝? <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>?<3F>舀綉 摰䂿緵<EFBFBD><EFBFBD><EFBFBD>𣂼<EFBFBD><EFBFBD>峕鸌憭<EFBFBD><EFBFBD>
摰匧<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? PHI<EFBFBD>唳旿瘜<EFBFBD> <EFBFBD>?<3F>舀綉 銝交聢摰∟恣+<2B><EFBFBD>+HIPAA<41><41><EFBFBD>
蝏湔擪<EFBFBD>鞉𧋦 <EFBFBD>椬 銝? <EFBFBD><EFBFBD>餈鞱𨯫 <EFBFBD>𩤃<EFBFBD> <20><EFBFBD><E585B8>舀綉 <EFBFBD>遣銝㮖<EFBFBD><EFBFBD><EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摨? <EFBFBD>叚 雿? <EFBFBD><EFBFBD><EFBFBD>寡悌 <EFBFBD>?<3F>舀綉 皜鞱<EFBFBD>撘𤩺綫撟?

<EFBFBD>𣞁 <20><><EFBFBD><EFBFBD><E88880>?嚗鍃AV璅<E79285><E288AA><EFBFBD><EFBFBD><EFBFBD>瘛望<E7989B>

<EFBFBD><EFBFBD><EFBFBD>讛膩

REDCap雿輻鍂Entity-Attribute-Value (EAV)<E79285>摮睃<E691AE><E79D83>唳旿嚗諹<E59A97><E8ABB9><EFBFBD>憭抒<E686AD><E68A92><EFBFBD><EFBFBD><EFBFBD><E88880><EFBFBD>?

REDCap<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>冽䲮撘?

-- redcap_data銵函<E98AB5><E587BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵剁<E98AB5>
CREATE TABLE redcap_data (
  project_id INT,
  event_id INT,
  record VARCHAR(100),
  field_name VARCHAR(100),
  value TEXT,
  PRIMARY KEY (project_id, event_id, record, field_name)
);

-- 摮睃<E691AE>蝷箔<E89DB7>嚗帋<E59A97>銝芣<E98A9D><E88AA3><EFBFBD><EFBFBD>3銝芸<E98A9D>畾菟<E795BE>閬?銵?
| project_id | event_id | record  | field_name | value    |
|------------|----------|---------|------------|----------|
| 123        | 1        | PAT001  | age        | 45       |
| 123        | 1        | PAT001  | gender     | male     |
| 123        | 1        | PAT001  | diagnosis  | diabetes |

撖寞<EFBFBD>**隡删<E99AA1><E588A0>喟頂<E5969F>𧢲芋<F0A7A2B2>?*嚗?

-- 隡删<E99AA1>摰質”摮睃<E691AE><EFBFBD><E59A97>銵峕<E98AB5>摰𡄯<E691B0>
CREATE TABLE patients (
  record_id VARCHAR(100) PRIMARY KEY,
  age INT,
  gender VARCHAR(10),
  diagnosis VARCHAR(100)
);

| record_id | age | gender | diagnosis |
|-----------|-----|--------|-----------|
| PAT001    | 45  | male   | diabetes  |

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰𧼮㦤<EFBFBD><EFBFBD>

<EFBFBD>箸艶1嚗𡁏䰻霂<EFBFBD>銝芣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰峕㟲<EFBFBD>唳旿

-- EAV璅<E79285>嚗𡁻<E59A97><EFBFBD><EFBFBD><EFBFBD>JOIN嚗<4E><E59A97>嚗?
SELECT 
  MAX(CASE WHEN field_name = 'age' THEN value END) AS age,
  MAX(CASE WHEN field_name = 'gender' THEN value END) AS gender,
  MAX(CASE WHEN field_name = 'diagnosis' THEN value END) AS diagnosis
FROM redcap_data
WHERE project_id = 123 
  AND record = 'PAT001'
GROUP BY record;

-- <20><EFBFBD><E689AF>園𡢿嚗?00銝芸<E98A9D>畾蛛<E795BE>嚗鰺50-200ms
-- 摰質”<E8B3AA><EFBFBD><E689AF>園𡢿嚗鰺1-5ms嚗<73>翰40-200<30><EFBFBD>

<EFBFBD>箸艶2嚗𡁏鸌<EFBFBD>誩紡<EFBFBD>?000銝芣<E98A9D><E88AA3>?

-- EAV璅<E79285>嚗𡁶<E59A97><F0A181B6><EFBFBD><EFBFBD><E68A92><EFBFBD>
SELECT * FROM redcap_data 
WHERE project_id = 123 
  AND record IN ('PAT001', 'PAT002', ..., 'PAT1000');

-- 蝏𤘪<E89D8F>嚗朞<E59A97><E69C9E>?00銝<30><E98A9D>嚗?000<30><30><EFBFBD>?<3F> 100摮埈挾 <20> 10鈭衤辣嚗?
-- <20><EFBFBD><E689AF>園𡢿嚗?0-60蝘?
-- <20><><EFBFBD><EFBFBD>删鍂嚗?00MB - 2GB
-- 蝵𤑳<E89DB5>隡㰘<E99AA1>嚗𡁜楊憭抒<E686AD>JSON payload

<EFBFBD>箸艶3嚗𡁶<EFBFBD><EFBFBD><EFBFBD>鞉䰻霂?

-- <20>亥砭撟湧<E6929F>>50撗<30><E69297><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
SELECT COUNT(DISTINCT record)
FROM redcap_data
WHERE project_id = 123
  AND field_name = 'age'
  AND CAST(value AS UNSIGNED) > 50;

-- <20><EFBFBD>嚗𡁜<E59A97>銵冽醌<E586BD>𧶏<EFBFBD><F0A7B68F><EFBFBD><E4ADBE>拍鍂蝝<E89D9D>
-- <20><EFBFBD><E689AF>園𡢿嚗?0銝<30><E98A9D><EFBFBD><EFBFBD><EFBFBD>嚗?-30蝘?

撖農I撟喳蝱<EFBFBD><EFBFBD><EFBFBD>?

  1. **DC璅<E79285><EFBFBD><EFBFBD><EFBFBD>瘣梹<E798A3>**嚗?

    • <EFBFBD>?<3F><EFBFBD><E4ADBE>湔𦻖撖遂AV<41>唳旿<E594B3>𡁶<EFBFBD><E99C88><E288AA>?
    • <EFBFBD>?瘥𤩺活皜<E6B4BB><E79A9C><EFBFBD><EFBFBD><EFBFBD><E996AC>"<22>匧像"<22>唳旿嚗𠄌TL餈<4C><E9A488>嚗?
    • <EFBFBD><EFBFBD> 1000<30>∟扇敶閧<E695B6><EFBFBD><E79A9C><EFBFBD><EFBFBD><EFBFBD>閬?-10<31><30><EFBFBD><EFBFBD><E686B8><EFBFBD>?
  2. **SSA璅<E79285><EFBFBD><E59A97><E99C88><E288AA><EFBFBD>**嚗?

    • <EFBFBD>?R/Python<6F>𡁏𧋦<F0A1818F><EFBFBD><E4ADBE>湔𦻖<E6B994><EFBFBD>EAV銵?
    • <EFBFBD>?敹<><EFBFBD><E29786><EFBFBD>蛹DataFrame<6D><EFBFBD>
    • <EFBFBD>𩤃<EFBFBD> <20><><EFBFBD><EFBFBD><E798A8>堒楊憭改<E686AD>10銝<30>扇敶𨰝<E695B6>2-5GB嚗?
  3. 摰墧𧒄<EFBFBD>峕郊嚗?

    • <EFBFBD>?瘥𤩺活靽嘥<E99DBD><E598A5>質圻<E8B3AA><EFBFBD><E7A983>渲扇敶閙䰻霂<E99C82><EFBD87><EFBFBD>
    • <EFBFBD>𩤃<EFBFBD> 擃㗛<E69383>敶訫<E695B6><E8A8AB>箸艶銝衤<E98A9D><E8A1A4>硋𡆇<E7A18B>唳旿摨?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

蝑𣇉裦A嚗𡁶<EFBFBD><EFBFBD>𤥁<EFBFBD><EFBFBD>?+ 摰𡁏𧒄<F0A1818F>瑟鰵

-- <20>𥕦遣摰質”<E8B3AA><EFBFBD><EFBFBD>㦛嚗<E3A69B><E59A97>撠𤩺𧒄<F0A4A9BA>瑟鰵銝<E9B0B5>甈∴<E79488>
CREATE MATERIALIZED VIEW patient_data_flat AS
SELECT 
  record,
  MAX(CASE WHEN field_name = 'age' THEN value END) AS age,
  MAX(CASE WHEN field_name = 'gender' THEN value END) AS gender,
  -- ... <20><EFBFBD>摮埈挾
FROM redcap_data
WHERE project_id = 123
GROUP BY record;

-- AI撟喳蝱<E596B3>亥砭摰質”嚗<E2809D>翰嚗?
SELECT * FROM patient_data_flat WHERE age > 50;

**<2A><EFBFBD>**嚗?

  • <EFBFBD>𩤃<EFBFBD> <20>唳旿撱嗉<E692B1><EFBFBD><E59A97>憭?撠𤩺𧒄嚗?
  • <EFBFBD>𩤃<EFBFBD> 摮睃<E691AE>蝛粹𡢿蝧餃<E89DA7>?
  • <EFBFBD>𩤃<EFBFBD> <20>瑟鰵餈<E9B0B5><E9A488>隡𡁻<E99AA1>銵?

蝑𣇉裦B嚗鋫I撟喳蝱靘抒<EFBFBD>摮?

// <20>杗I撟喳蝱PostgreSQL銝剔<E98A9D>摮?<3F>匧像"<22>𡒊<EFBFBD><F0A1928A>唳旿
model RedcapDataCache {
  id          String   @id
  projectId   String
  recordId    String
  flatData    Json     // 摮睃<E691AE>摰質”<E8B3AA><EFBFBD>
  lastSyncAt  DateTime
  
  @@unique([projectId, recordId])
  @@index([lastSyncAt])
}

// 憓鮋<E68693><E9AE8B>峕郊蝑𣇉裦
async function syncFromRedcap(projectId: string) {
  const lastSyncTime = await getLastSyncTime(projectId);
  
  // <20>芣䰻霂<E99C82><EFBCB7><EFBFBD><E8AAA9><EFBFBD><E6B99B><EFBFBD>redcap_log銵剁<E98AB5>
  const changedRecords = await redcapApi.getChangedRecords({
    projectId,
    since: lastSyncTime
  });
  
  // <20><EFBFBD><E5AFA5>湔鰵蝻枏<E89DBB>
  await batchUpdateCache(changedRecords);
}

隡睃飵嚗?

  • <EFBFBD>?<3F>亥砭<E4BAA5>笔漲敹恬<E695B9>PostgreSQL JSONB蝝<E89D9D>嚗?
  • <EFBFBD>?<3F><EFBFBD>REDCap<61>唳旿摨枏<E691A8><E69E8F>?
  • <EFBFBD>?<3F><EFBFBD><E88880><EFBFBD><E586BD>𦦵揣<F0A6A6B5><E68FA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>皛?

**<2A><EFBFBD>**嚗?

  • <EFBFBD>𩤃<EFBFBD> <20>唳旿<E594B3>𦯀<EFBFBD><EFBFBD><E59A97><EFBFBD>函蕃<E587BD><EFBFBD>
  • <EFBFBD>𩤃<EFBFBD> <20>峕郊撱嗉<E692B1>嚗?-30蝘𡜐<E89D98>
  • <EFBFBD>𩤃<EFBFBD> 蝏湔擪憭齿<E686AD>摨血<E691A8><E8A180>?

蝑𣇉裦C嚗鑹EDCap API<50><EFBFBD><E5ADB5><EFBFBD><EFBFBD><EFBFBD>?

// External Module銝哨<E98A9D><E593A8><EFBFBD><E5AFA5><EFBFBD><E79195>唳旿嚗<E697BF><E59A97>憿蛛<E686BF>
function getBatchRecords($projectId, $recordIds, $batchSize = 100) {
    $batches = array_chunk($recordIds, $batchSize);
    $allData = [];
    
    foreach ($batches as $batch) {
        // 雿輻鍂REDCap API嚗<49>歇隡睃<E99AA1>嚗?
        $data = REDCap::getData([
            'project_id' => $projectId,
            'return_format' => 'json',
            'records' => $batch,
            'exportDataAccessGroups' => false,
            'exportSurveyFields' => false
        ]);
        
        $allData = array_merge($allData, $data);
        
        // <20><EFBFBD><EFBFBD>𧒄
        usleep(100000); // 100ms撱嗉<E692B1>
    }
    
    return $allData;
}

憌𡡞埯霂<EFBFBD>

<EFBFBD><EFBFBD><EFBFBD> <EFBFBD> 霂湔<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃㗛<E69383><E3979B>? <EFBFBD>唳旿<EFBFBD>?5銝<35><EFBFBD><EFBFBD><E59786>?
*<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>2-3<>刻挽霈∠<E99C88>摮睃<E691AE>
餈鞟輕<EFBFBD>鞉𧋦 <EFBFBD>椬 銝? <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>甇亙辣餈?

<EFBFBD>𣞁 <20><><EFBFBD><EFBFBD><E88880>?嚗鑹EDCap<61><70>𧋦<EFBFBD><F0A78BA6><EFBFBD>?<3F><EFBFBD><E6B8B8>?

<EFBFBD><EFBFBD><EFBFBD>讛膩

REDCap<EFBFBD>?*敹恍<E695B9>蠘翮隞?*嚗<><E59A97>撟?-4銝芸之<E88AB8><E4B98B>𧋦嚗劐<E59A97>撣行䔉<E8A18C>澆捆<E6BE86>批埯璇艾<E79287>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘜芣<EFBFBD>霈哨<EFBFBD>

<EFBFBD><EFBFBD>1嚗䥅ook<EFBFBD>賣㺭蝑曉<EFBFBD><EFBFBD>䀹凒

// REDCap 10.x<><78>𧋦
function redcap_save_record($project_id, $record, $instrument, $event_id) {
    // 4銝芸<E98A9D><E88AB8>?
}

// REDCap 11.0<EFBFBD><EFBFBD>𧋦嚗?021撟湛<E6929F>
function redcap_save_record($project_id, $record, $instrument, $event_id, 
                            $group_id, $survey_hash, $response_id, $repeat_instance) {
    // 蝒<><E89D92><EFBFBD><EFBFBD>8銝芸<E98A9D><E88AB8><EFBFBD>
}

**敶勗<E695B6>**嚗?

  • <EFBFBD>?<3F><><EFBFBD><EFBFBD>韏𡝗迨Hook<6F><6B>xternal Module<6C><EFBFBD>撏拇<E6928F>
  • <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>乩耨憭滚僎瘚贝<E7989A>
  • <EFBFBD><EFBFBD><><E68692>瘝⊥<E7989D>銝交聢<E4BAA4><E881A2><EFBFBD><EFBFBD><EFBFBD>摰𡄯<E691B0><F0A184AF>煺漣<E785BA><EFBFBD><E887AC>湔𦻖<E6B994><F0A6BB96><EFBFBD>

<EFBFBD><EFBFBD>2嚗鋫PI<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䀹凒

// REDCap 12.x API<50><EFBFBD>
{
  "record_id": "PAT001",
  "age": "45",
  "gender": "1"  // 摮㛖泵銝脩掩<E884A9>?
}

// REDCap 13.0 API<50><EFBFBD><EFBFBD><E59A97><EFBFBD>亦掩<E4BAA6>贝蓮<E8B49D><EFBFBD>
{
  "record_id": "PAT001",
  "age": 45,      // <20><EFBFBD><E480B9>湔㺭蝐餃<E89D90>
  "gender": "1"   // 隞齿糓摮㛖泵銝?
}

**敶勗<E695B6>**嚗?

  • <EFBFBD>?蝐餃<E89D90><E9A483><EFBFBD>憭梯揖嚗㇍ypeScript銝交聢璅<E79285>嚗?
  • <EFBFBD>?<3F>唳旿撉諹<E69289><E8ABB9><EFBFBD>憭望<E686AD>
  • <EFBFBD><EFBFBD> <20>鞱𤪖<E99EB1><F0A4AA96>ug嚗?0" vs 0 撣<><E692A3><EFBFBD>斗鱏<E69697><EFBFBD>嚗?

<EFBFBD><EFBFBD>3嚗𡁏㺭<EFBFBD><EFBFBD>銵函<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

-- REDCap 14.x銋见<E98A8B>
SELECT * FROM redcap_projects WHERE project_id = 123;

-- REDCap 15.0<EFBFBD><EFBFBD>摮埈挾
ALTER TABLE redcap_projects 
  ADD COLUMN project_language VARCHAR(10) DEFAULT 'English';

-- 憒<><E68692>雿删<E99BBF>External Module<6C>湔𦻖<E6B994><EFBFBD><E6BBA2>唳旿摨橒<E691A8>
INSERT INTO redcap_projects (project_id, app_title) 
VALUES (456, 'Test Project');
-- <20>?<3F>仿<EFBFBD>嚗䮝roject_language摮埈挾NOT NULL蝥行<E89DA5>憭梯揖

銝滚虾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

<EFBFBD><EFBFBD>漣蝐餃<EFBFBD> 憸𤑳<EFBFBD> 敶勗<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>曉漲 憌𡡞埯蝑厩漣
*憭抒<EFBFBD><EFBFBD><EFBFBD>蝥? 瘥誩僑3-4甈? <EFBFBD>𣞁 <20>券𢒰敶勗<E695B6> <EFBFBD>𣞁 <20>圈𠗕 <EFBFBD>𣞁<EFBFBD>𣞁<EFBFBD>𣞁<EFBFBD>𣞁<EFBFBD>𣞁
*撠讐<EFBFBD><EFBFBD>銝? 瘥𤩺<EFBFBD>1-2甈? <EFBFBD>椬 撅<><E69285>典蔣<E585B8>? <EFBFBD>椬 銝剔<E98A9D> <EFBFBD><EFBFBD><EFBFBD>
摰匧<EFBFBD>銵乩<EFBFBD> 蝝扳<EFBFBD><EFBFBD>撣? <EFBFBD>叚 頧餃凝敶勗<E695B6> <EFBFBD>叚 摰寞<E691B0> <EFBFBD><EFBFBD>

摨𥪜笆蝑𣇉裦嚗<EFBFBD><EFBFBD>雿𡡞<EFBFBD><EFBFBD><EFBFBD>

蝑𣇉裦1嚗帋艇<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD>

// config.json銝剜<E98A9D>蝖桀ㄟ<E6A180>𤾸<EFBFBD>摰寧<E691B0><E5AFA7>?
{
  "name": "AI Research Assistant",
  "framework-version": 16,
  "compatibility": {
    "redcap-version-min": "15.8.0",
    "redcap-version-max": "15.9.99",
    "php-version-min": "7.4",
    "php-version-max": "8.2"
  }
}
// <20>冽芋<E586BD><EFBFBD>憪见<E686AA><E8A781><EFBFBD><E59786><EFBFBD><E4BAA6>?
public function __construct() {
    $redcapVersion = REDCAP_VERSION;
    $minVersion = '15.8.0';
    $maxVersion = '15.9.99';
    
    if (version_compare($redcapVersion, $minVersion, '<') || 
        version_compare($redcapVersion, $maxVersion, '>')) {
        throw new Exception(
            "甇斗芋<E69697>𦯀<EFBFBD><F0A6AF80><EFBFBD>REDCap {$minVersion} - {$maxVersion}嚗? .
            "敶枏<EFBFBD><EFBFBD><EFBFBD>𧋦嚗㝯$redcapVersion}"
        );
    }
}

蝑𣇉裦2嚗𡁏<EFBFBD>撠誩<EFBFBD><EFBFBD>湔𦻖靘肽<EFBFBD>

// <20>?<3F>躰秤嚗𡁶凒<F0A181B6><EFBFBD>雿𨀣㺭<F0A880A3><EFBFBD>
$sql = "SELECT * FROM redcap_data WHERE project_id = $pid";
$result = db_query($sql);

// <20>?甇<>嚗帋蝙<E5B88B>沖EDCap撠<70><E692A0><EFBFBD><EFBFBD>PI
$data = REDCap::getData($pid, 'array');

**<2A><EFBFBD>**嚗?

  • REDCap API隡𡁜<E99AA1><F0A1819C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰寞<E691B0>?
  • <EFBFBD>湔𦻖<EFBFBD><EFBFBD><EFBFBD>唳旿摨梶<EFBFBD><EFBFBD><EFBFBD>REDCap<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

蝑𣇉裦3嚗𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧼮<EFBFBD>瘚贝<EFBFBD>

# CI/CD Pipeline嚗<65><E59A97><E79488>蝥批<E89DA5>頝𡢅<E9A09D>
tests/
<0A><EFBFBD><E98EBF><EFBFBD> integration/
<0A>?  <20><EFBFBD><E98EBF><EFBFBD> test_redcap_15.8.0.php    # 敶枏<E695B6><E69E8F><EFBFBD>𧋦瘚贝<E7989A>
<0A>?  <20><EFBFBD><E98EBF><EFBFBD> test_redcap_15.9.0.php    # 憸<><E686B8>霂蓥<E99C82><EFBFBD><E98A9D><EFBFBD>𧋦
<0A>?  <20><EFBFBD><E5A999><EFBFBD> test_redcap_16.0.0.php    # 憸<><E686B8>霂閙𧊋<E99699><EFBFBD><E4BAA6>?
<0A><EFBFBD><E98EBF><EFBFBD> api/
<0A>?  <20><EFBFBD><E98EBF><EFBFBD> test_export_records.php
<0A>?  <20><EFBFBD><E5A999><EFBFBD> test_import_records.php
<0A><EFBFBD><E5A999><EFBFBD> hooks/
    <20><EFBFBD><E98EBF><EFBFBD> test_save_record.php
    <20><EFBFBD><E5A999><EFBFBD> test_every_page_top.php
// <20>芸𢆡<E88AB8>𡝗<EFBFBD>霂閧內靘?
class RedcapCompatibilityTest extends TestCase {
    public function testSaveRecordHook() {
        // 璅⊥<E79285>REDCap靚<70>鍂Hook
        $result = $this->module->redcap_save_record(
            123, 'PAT001', 'demographics', 1, 
            null, null, null, null
        );
        
        $this->assertNotNull($result);
        $this->assertTrue($result['success']);
    }
}

蝑𣇉裦4嚗𡁜<EFBFBD>蝥折<EFBFBD>蝳餌㴓憓?

<EFBFBD>煺漣<EFBFBD><EFBFBD>嚗㇌EDCap 15.8.0嚗?
    <20>?
憸<><E686B8>鈭抒㴓憓<E3B493><E68693>REDCap 15.9.0嚗争<EFBFBD> <20><><EFBFBD>蝥扳<E89DA5>霂?
    <20>?
撘<><E69298>𤑳㴓憓<E3B493><E68693>REDCap 16.0.0嚗?  <20>?<3F>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD>

**瘚<><E7989A>**嚗?

  1. REDCap摰䀹䲮<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
  2. <EFBFBD><EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD><EFBFBD>僎瘚贝<EFBFBD>嚗?<3F><EFBFBD>
  3. <EFBFBD><EFBFBD>鈭抒㴓憓<EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>
  4. <EFBFBD>煺漣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>漣嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

憌𡡞埯霂<EFBFBD>

<EFBFBD><EFBFBD><EFBFBD> <EFBFBD> 霂湔<EFBFBD>
*銝滚虾<EFBFBD><EFBFBD>? <EFBFBD>𣞁 <20><><EFBFBD> REDCap<EFBFBD><EFBFBD><EFBFBD>園𡢿銝滨眏<EFBFBD>睲賑<EFBFBD><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>1-2<><EFBFBD>霂?
<EFBFBD><EFBFBD>蝏湔擪 <EFBFBD>𣞁 擃? <EFBFBD>澈隡湧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

<EFBFBD><20><><EFBFBD><EFBFBD><E88880>?嚗𡁏㺭<F0A1818F><EFBFBD><E6A190><EFBFBD><EFBFBD>"<22><><EFBFBD>?

<EFBFBD><EFBFBD><EFBFBD>讛膩

敶𣫮EDCap<EFBFBD>淾I撟喳蝱**<2A>峕𧒄摮睃<EFBFBD><EFBFBD>唳旿<EFBFBD><EFBFBD>隡𡁻𢒰銝渡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>撘譍<EFBFBD><EFBFBD><EFBFBD>折䔮憸?*<2A>?

<EFBFBD><EFBFBD><EFBFBD>批㦤<EFBFBD><EFBFBD><EFBFBD>?

<EFBFBD>箸艶1嚗𡁜<EFBFBD><EFBFBD><EFBFBD>甇亦<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD>園𡢿頧湛<EFBFBD>
T1: <20><EFBFBD>A<EFBFBD>沖EDCap靽格㺿<E6A0BC><E3BABF><EFBFBD><EFBFBD>AT001<30><31>僑樴<E58391>蛹45撗?
    <20>?External Module<6C><EFBFBD><E588B8><EFBFBD>AI撟喳蝱
    
T2: <20><EFBFBD>B<EFBFBD>杗I撟喳蝱DC璅<E79285><EFBFBD><E79A9C><EFBFBD>唳旿嚗<E697BF><E59A97><EFBFBD>啣僑樴<E58391><E6A8B4>撣賂<E692A3>靽格㺿銝?6撗?
    <20>?<3F>𧼮<EFBFBD><F0A7BCAE>訌EDCap嚗?
    
T3: REDCap銝剖僑樴<E58391><EFBFBD>冽糓嚗?5餈䀹糓46嚗?
    <20>?憒<><E68692>瘝⊥<E7989D><E28AA5><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>嚗峕㺭<E5B395><EFBFBD><EFBFBD><E98A9D><EFBFBD>

<EFBFBD>箸艶2嚗𡁜<EFBFBD>甇亙辣餈笔紡<EFBFBD><EFBFBD><EFBFBD>讛粉

T1: <20><EFBFBD><E586BD>沖EDCap敶訫<E695B6>摰峕㟲<E5B395><E39FB2><EFBFBD>嚗?0銝芾”<E88ABE>𤏪<EFBFBD>50銝芸<E98A9D>畾蛛<E795BE>
    <20>?瘥譍葵摮埈挾靽嘥<E99DBD><E598A5><EFBFBD>閫血<E996AB>redcap_save_record
    <20>?External Module<6C><EFBFBD>?0甈<E79488>AI撟喳蝱
    
T2: AI撟喳蝱<E596B3>交𤣰鈭<F0A4A3B0><E988AD>30銝芸<E98A9D>畾蛛<E795BE><E89B9B>?0銝芸<E98A9D>畾菔<E795BE><E88F94><EFBFBD>颲㮖葉
    <20>?<3F><EFBFBD><E586BD>杗I撟喳蝱<E596B3><EFBFBD><E4BAA6><EFBFBD><EFBFBD>嚗𡁏遬蝷箔<E89DB7>摰峕㟲<E5B395>唳旿
    <20>?<3F><EFBFBD>霂臭誑銝箸㺭<E7AEB8>桐腺憭梧<E686AD><E6A2A7>齿活敶訫<E695B6>
    
T3: <20>?0銝芸<E98A9D>畾萄<E795BE>颲橘<E9A2B2><EFBFBD><EFBFBD>瑕歇蝏誯<E89D8F>憭滚<E686AD><E6BB9A>?
    <20>?<3F>唳旿<E594B3><EFBFBD>嚗?

<EFBFBD>箸艶3嚗𡁶<EFBFBD>蝏𨀣<EFBFBD><EFBFBD>𨅯紡<EFBFBD><EFBFBD><EFBFBD>唳旿銝

T1: <20><EFBFBD><E586BD>沖EDCap靽嘥<E99DBD><E598A5>唳旿
    <20>?External Module<6C><EFBFBD><E588B8><EFBFBD>AI撟喳蝱
    <20>?蝵𤑳<E89DB5><EFBFBD>𧒄嚗㇌EDCap<61>淾I撟喳蝱銋钅𡢿<E99285><F0A1A2BF><EFBFBD>蝏靝<E89D8F>蝔喳<E89D94>嚗?
    
T2: External Module<6C><EFBFBD><EFBFBD>𧒄<EFBFBD>躰秤
    <20>?<3F>臬炏<E887AC><EFBFBD>嚗罸<E59A97>霂訫<E99C82>甈∴<E79488>
    <20>?憒<><E68692><EFBFBD><EFBFBD>嚗䔶<E59A97>銝滢<E98A9D>撖潸稲<E6BDB8><EFBFBD><E6BB9A><EFBFBD>嚗?
    
T3: AI撟喳蝱<E596B3>唳旿蝻箏仃
    <20>?<3F>𡒊賒<F0A1928A><E8B392><EFBFBD>蝏𤘪<E89D8F>銝滚<E98A9D>蝖?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

蝑𣇉裦A嚗𡁜<EFBFBD>蝑㗇<EFBFBD>扯挽霈∴<EFBFBD>Idempotency嚗?

// AI撟喳蝱Webhook<6F>交𤣰<E4BAA4><EFBFBD><EFBFBD><E6929F><EFBFBD><EFBFBD><EFBFBD><E99C82>
async function receiveRecordUpdate(req, res) {
  const { project_id, record_id, data, timestamp } = req.body;
  
  // <20><><EFBFBD><EFBFBD><E6929F><EFBFBD>免ey嚗<79>俈甇<E79487>憭滚<E686AD><E6BB9A><EFBFBD><EFBFBD>
  const idempotencyKey = `${project_id}:${record_id}:${timestamp}`;
  
  // 璉<><E79289>交糓<E4BAA4>血歇憭<E6AD87><E686AD>餈?
  const existing = await prisma.redcapSyncRecord.findUnique({
    where: { idempotencyKey }
  });
  
  if (existing) {
    // 撌脣<E6928C><E884A3><EFBFBD><EFBFBD>嚗𣬚凒<F0A3AC9A><EFBFBD><E4BAA5><EFBFBD><E5A2A7>?
    return res.send({ 
      success: true, 
      message: '<27>唳旿撌脣<E6928C><E884A3><EFBFBD><EFBFBD><E6929F><EFBFBD><EFBFBD>' 
    });
  }
  
  // <20><EFBFBD><E7AC94><EFBFBD>雿頣<E99BBF><E9A0A3>𥕦遣<F0A595A6>峕郊霈啣<E99C88>+<2B>湔鰵<E6B994>唳旿
  await prisma.$transaction(async (tx) => {
    // 1. <20>𥕦遣<F0A595A6>峕郊霈啣<E99C88><EFBFBD><EFBFBD><EFBFBD>蝥行<E89DA5>嚗?
    await tx.redcapSyncRecord.create({
      data: {
        idempotencyKey,
        projectId: project_id,
        recordId: record_id,
        redcapData: data,
        status: 'success',
        syncedAt: new Date()
      }
    });
    
    // 2. <20>湔鰵銝𡁜𦛚<F0A1819C>唳旿
    await tx.patientData.upsert({
      where: { recordId: record_id },
      update: data,
      create: data
    });
  });
  
  return res.send({ success: true });
}

蝑𣇉裦B嚗𡁶<EFBFBD><EFBFBD>砍噡<EFBFBD><EFBFBD>嚗㇉ptimistic Locking嚗?

// 瘥𤩺辺霈啣<E99C88><E595A3><EFBFBD><E8B3A3><EFBFBD>𧋦<EFBFBD>?
model PatientData {
  recordId    String   @id
  age         Int
  gender      String
  version     Int      @default(0)  // <20><>𧋦<EFBFBD>?
  updatedAt   DateTime @updatedAt
  
  @@index([version])
}

// <20>湔鰵<E6B994><EFBFBD><E59786><EFBFBD><E4BAA6>砍噡
async function updateRecord(recordId: string, newData: any, expectedVersion: number) {
  const result = await prisma.patientData.updateMany({
    where: { 
      recordId,
      version: expectedVersion  // <20><EFBFBD><E88AA3><EFBFBD>𧋦<EFBFBD>瑕龪<E79195>齿<EFBFBD><E9BDBF>湔鰵
    },
    data: {
      ...newData,
      version: expectedVersion + 1  // <20><>𧋦<EFBFBD>?1
    }
  });
  
  if (result.count === 0) {
    // <20><>𧋦<EFBFBD><EFBFBD><E7919A><EFBFBD>嚗諹秩<E8ABB9><EFBFBD><E693A7><EFBFBD>
    throw new ConflictError('<27>唳旿撌脰◤<E884B0><EFBFBD><E597A1><EFBFBD>靽格㺿嚗諹窈<E8ABB9>瑟鰵<E7919F>𡡞<EFBFBD>?);
  }
}

蝑𣇉裦C嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?+ <20><EFBFBD><E884A9><EFBFBD>

// <20><EFBFBD><EFBFBD><E996AB>蝑𣇉裦嚗朞扇敶閙<E695B6><E99699><EFBFBD><EFBFBD><E89D92>鈭箏極鋆<E6A5B5><E98B86>
model DataConflict {
  id              String   @id @default(cuid())
  recordId        String
  fieldName       String
  
  redcapValue     String   // REDCap銝剔<E98A9D><E58994>?
  aiPlatformValue String   // AI撟喳蝱銝剔<E98A9D><E58994>?
  
  redcapTimestamp DateTime // REDCap靽格㺿<E6A0BC>園𡢿
  aiPlatformTimestamp DateTime // AI撟喳蝱靽格㺿<E6A0BC>園𡢿
  
  status          String   // pending, resolved, ignored
  resolution      String?  // 鈭箏極鋆<E6A5B5><E98B86>蝏𤘪<E89D8F>
  resolvedBy      String?
  resolvedAt      DateTime?
  
  createdAt       DateTime @default(now())
}

// 璉<>瘚见<E7989A>蝒?
async function detectConflict(recordId: string) {
  const redcapData = await fetchFromRedcap(recordId);
  const aiPlatformData = await fetchFromAIPlatform(recordId);
  
  const conflicts = [];
  
  for (const field of Object.keys(redcapData)) {
    if (redcapData[field] !== aiPlatformData[field]) {
      conflicts.push({
        recordId,
        fieldName: field,
        redcapValue: redcapData[field],
        aiPlatformValue: aiPlatformData[field],
        redcapTimestamp: redcapData._timestamp,
        aiPlatformTimestamp: aiPlatformData._timestamp
      });
    }
  }
  
  if (conflicts.length > 0) {
    // 霈啣<E99C88><E595A3><EFBFBD>嚗𣬚<E59A97><EFBFBD>犖撌亙<E6928C><E4BA99>?
    await prisma.dataConflict.createMany({ data: conflicts });
    
    // <20><EFBFBD><E785BE><EFBFBD>霅阡<E99C85>𡁶䰻
    await notifyAdmin('璉<>瘚见<E7989A><E8A781>唳旿<E594B3><EFBFBD>', { recordId, conflicts });
  }
}

蝑𣇉裦D嚗𡁜<EFBFBD><EFBFBD>睲蜓隞擧芋撘𧶏<EFBFBD><EFBFBD><EFBFBD>憭齿<EFBFBD>摨佗<EFBFBD>

<EFBFBD>㗇𥋘銝<EFBFBD>銝?銝餌頂蝏?嚗𠄎ource of Truth嚗㚁<E59A97>

<0A><EFBFBD>1嚗鑹EDCap銝箔蜓
  - <20>唳旿敶訫<E695B6>嚗𡁜蘨<F0A1819C>沖EDCap銝剛<E98A9D>銵?
  - AI撟喳蝱嚗𡁜蘨霂餅芋撘𧶏<E69298>銝滚<E98A9D>霈訾耨<E8A8BE><EFBFBD>憪𧢲㺭<F0A7A2B2>?
  - AI憭<49><E686AD>蝏𤘪<E89D8F>嚗𡁜<E59A97><F0A1819C>典銁<E585B8>閧𡠺<E996A7><F0A1A0BA>”銝哨<E98A9D>銝滚<E98A9D><E6BB9A>筻EDCap
  
  隡睃飵嚗?
  <20>?銝<><E98A9D><EFBFBD>折䔮憸䀹<E686B8>憭?
  <20>?<3F><EFBFBD><EFBFBD><E89D9E>?
  <20>?<3F><EFBFBD>憟?
  
  <20><>飵嚗?
  <20>?AI撟喳蝱<E596B3><E89DB1><EFBFBD><EFBFBD>瘣㛖<E798A3><E39B96>𨀣<EFBFBD>瘜閗䌊<E99697><EFBFBD><E585B8>?
  <20>?<3F><EFBFBD>雿㯄<E99BBF><E3AF84><EFBFBD><EFBFBD>舅銝芰頂蝏<E9A082><EFBFBD>𧼮<EFBFBD><F0A7BCAE><EFBFBD>

<0A><EFBFBD>2嚗鋫I撟喳蝱銝箔蜓
  - <20>唳旿敶訫<E695B6>嚗𡁻<E59A97><EFBFBD>AI撟喳蝱<E596B3>屸𢒰嚗<F0A292B0><E59A97>撋朙EDCap iFrame<6D>䨝PI嚗?
  - REDCap嚗帋<E59A97>銝箏<E98A9D><EFBFBD><E69285><EFBFBD><EFBFBD><E58981><EFBFBD>API<50><EFBFBD>
  - 蝏煺<E89D8F><E785BA>杗I撟喳蝱憭<E89DB1><E686AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E58A90><EFBFBD><EFBFBD>
  
  隡睃飵嚗?
  <20>?<3F><EFBFBD>雿㯄<E99BBF>蝏煺<E89D8F>
  <20>?<3F>臭誑<E887AD><E8AA91><EFBFBD><EFBFBD>拍鍂AI<41><EFBFBD>
  
  <20><>飵嚗?
  <20>?<3F><><EFBFBD><E996AC>撱摧EDCap<61><70><EFBFBD><EFBFBD>务I嚗<49>極雿𣈯<E99BBF>撌典之嚗?
  <20>?憭勗縧REDCap<61><70><EFBFBD>閗挽霈膥蝑㗇瓲敹<E793B2><E695B9><EFBFBD>?

憌𡡞埯霂<EFBFBD>

<EFBFBD><EFBFBD><EFBFBD> <EFBFBD> 霂湔<EFBFBD>
*憭齿<EFBFBD>摨? <EFBFBD>𣞁 擃? <EFBFBD><EFBFBD><EFBFBD>撘譍<EFBFBD><EFBFBD><EFBFBD>扳糓霈∠<EFBFBD><EFBFBD><EFBFBD>摮阡𠗕憸?
*<EFBFBD>舀綉<EFBFBD>? <EFBFBD>椬 銝? <EFBFBD>臭誑霈曇恣蝑𣇉裦嚗䔶<EFBFBD><EFBFBD><EFBFBD>100%<25><EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>椬 銝? <EFBFBD><EFBFBD>閬?-3<>刻挽霈?瘚贝<E7989A>
<EFBFBD><EFBFBD>敶勗<EFBFBD> <EFBFBD>椬 銝? <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>犖撌乩<EFBFBD><EFBFBD>亥圾<EFBFBD><EFBFBD>蝒?

撱箄悅嚗?

  • <EFBFBD>隡睃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1嚗㇌EDCap銝箔蜓嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>甇伐<EFBFBD>
  • <EFBFBD>𩤃<EFBFBD> <20><EFBFBD><E8B8B9><EFBFBD><EFBFBD>摰墧𧒄<E5A2A7>峕郊嚗<E9838A><E59A97><EFBFBD><EFBFBD><EFBFBD><E6BCB2><EFBFBD>嚗?
  • <EFBFBD><EFBFBD><><E68692><EFBFBD><EFBFBD><E29786><EFBFBD>嚗䔶蝙<E494B6>?*<2A><><EFBFBD><E89D8F><EFBFBD><EFBFBD>?鈭箏極摰⊥瓲**璅<E79285>

<EFBFBD><20><><EFBFBD><EFBFBD><E88880>?嚗鋫PI<50><EFBFBD>銝擧鸌<E693A7>𤩺<EFBFBD>雿𨀣<E99BBF><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>讛膩

REDCap API<50><EFBFBD><E58EB0><EFBFBD>**<2A><EFBFBD><E6AFBA>𣂼<EFBFBD>**嚗峕鸌<E5B395>𤩺<EFBFBD>雿𨀣𧒄摰寞<E691B0>閫血<E996AB><E8A180>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧊋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>﹝嚗?

<EFBFBD>寞旿蝷曉躹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘚页<EFBFBD>
- 瘥讐<E798A5>霂瑟<E99C82><E7919F><EFBFBD>QPS嚗㚁<E59A97>~10-50甈∴<E79488><E288B4><EFBFBD>鈭擧<E988AD><E693A7><E288AA>滨蔭嚗?
- <20>閙活撖澆枂霈啣<E99C88><E595A3><EFBFBD>撱箄悅<1000<30>?
- <20>閙活撖澆<E69296>霈啣<E99C88><E595A3><EFBFBD>撱箄悅<500<30>?
- 撟嗅<E6929F>餈墧𦻖<E5A2A7><EFBFBD>~5-10銝?
- 頞<>𧒄<EFBFBD>園𡢿嚗?0-60蝘?

頞<><EFBFBD>𣂼<EFBFBD>嚗?
- HTTP 429 (Too Many Requests)
- <20>𣇉凒<F0A38789><EFBFBD><E4BAA5><EFBFBD><E59786><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>箸艶<EFBFBD><EFBFBD>

<EFBFBD>箸艶1嚗𡁜<EFBFBD><EFBFBD><EFBFBD>甇?0銝<30>辺霈啣<E99C88>

// <20>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗帋<E59A97>甈⊥<E79488>批紡<E689B9><EFBFBD><E7AE8F>?
$data = $redcapApi->exportRecords([
    'format' => 'json',
    'type' => 'flat'
]);
// 蝏𤘪<E89D8F>嚗朞<E59A97><E69C9E><EFBFBD><E5979A><EFBFBD>摮䀹滯<E480B9><EFBFBD><E7AE9D><EFBFBD><EFBFBD>膥撏拇<E6928F>
// <20>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁜<E59A97>憿?<3F><EFBFBD>
function exportAllRecords($projectId, $batchSize = 500) {
    $offset = 0;
    $allData = [];
    
    while (true) {
        // <20><>鸌撖澆枂
        $batch = $redcapApi->exportRecords([
            'format' => 'json',
            'records' => range($offset, $offset + $batchSize - 1)
        ]);
        
        if (empty($batch)) break;
        
        $allData = array_merge($allData, $batch);
        $offset += $batchSize;
        
        // <20><EFBFBD>嚗𡁏<E59A97><F0A1818F>寥𡢿<E5AFA5>?蝘?
        sleep(2);
        
        // 餈𥕦漲<F0A595A6><EFBFBD>
        $progress = count($allData);
        error_log("撌脣紡<E884A3>?{$progress} <20>∟扇敶?);
    }
    
    return $allData;
}

// 10銝<30>辺霈啣<E99C88> = 200<30>?<3F> 2蝘?= 6.7<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD>箸艶2嚗𡁜<EFBFBD><EFBFBD><EFBFBD>甇仿<EFBFBD>憸穃<EFBFBD><EFBFBD>?

<EFBFBD>駁堺<EFBFBD>箸艶嚗?
- 20銝芰<E98A9D>蝛嗅𨭌<E59785><EFBFBD><E8A781><EFBFBD><E59785>交㺭<E4BAA4>?
- 瘥譍犖瘥誩<E798A5><E8AAA9><EFBFBD>摮?甈?
- <20>舔PS = 20 <20> 5 / 60 <20>?1.67甈?蝘?

<0A>贝絲<E8B49D><EFBFBD>擃矋<E69383><EFBFBD><E99BBF>
- 瘥𤩺活靽嘥<E99DBD>閫血<E996AB>redcap_save_record Hook
- Hook靚<6B>鍂AI撟喳蝱API嚗<49><E59A97>埈𧒄500ms嚗?
- 憒<><E68692>Hook<6F><EFBFBD><E689AF>園𡢿>1蝘𡜐<E89D98>隡𡁻獈憛冚EDCap<61><EFBFBD>
- <20><EFBFBD><E586BD><EFBFBD>"<22>⊿▼"

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗𡁜<EFBFBD>甇亙<EFBFBD>

// <20>?<3F>躰秤嚗𡁜<E59A97>甇亥<E79487><E4BAA5><EFBFBD><E58981><EFBFBD>嚗?
function redcap_save_record($project_id, $record, ...) {
    $data = REDCap::getData($project_id, 'array', $record);
    
    // <20>峕郊HTTP霂瑟<E99C82><EFBFBD>獈憛?-5蝘𡜐<E89D98>
    $this->apiClient->post('/webhook/records', $data);
}

// <20>?甇<>嚗𡁜<E59A97>甇仿<E79487><E4BBBF>?
function redcap_save_record($project_id, $record, ...) {
    // 蝡见朖餈𥪜<E9A488>嚗䔶<E59A97><E494B6><EFBFBD>
    $this->enqueueSync($project_id, $record);
}

function enqueueSync($project_id, $record) {
    // <20><EFBFBD><E59D94>砍𧑐<E7A08D><EFBFBD>銵?
    db_query("INSERT INTO em_sync_queue (project_id, record, status) 
              VALUES (?, ?, 'pending')", [$project_id, $record]);
}

// Cron隞餃𦛚瘥誩<E798A5><E8AAA9><EFBFBD><E7AC94><EFBFBD><EFBFBD><EFBFBD>?
function processSyncQueue() {
    $queue = db_query("SELECT * FROM em_sync_queue 
                       WHERE status = 'pending' 
                       LIMIT 100");
    
    foreach ($queue as $item) {
        try {
            $data = REDCap::getData($item['project_id'], 'array', $item['record']);
            $this->apiClient->post('/webhook/records', $data);
            
            // <20><><EFBFBD>𣂼<EFBFBD>
            db_query("UPDATE em_sync_queue SET status = 'success' 
                     WHERE id = ?", [$item['id']]);
        } catch (Exception $e) {
            // <20><>扇憭梯揖
            db_query("UPDATE em_sync_queue SET status = 'failed', error = ? 
                     WHERE id = ?", [$e->getMessage(), $item['id']]);
        }
        
        // <20><EFBFBD>
        usleep(500000); // 500ms
    }
}

憌𡡞埯霂<EFBFBD>

<EFBFBD><EFBFBD><EFBFBD> <EFBFBD> 霂湔<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>椬 銝? 憭扳㺭<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
*<EFBFBD>舀綉<EFBFBD>? <EFBFBD>?<3F>舀綉 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鸌+<2B><EFBFBD><EFBFBD><E996AB>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>叚 雿? 1-2憭拙<E686AD><E68B99>?
<EFBFBD><EFBFBD>敶勗<EFBFBD> <EFBFBD>叚 雿? <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>郊憭<EFBFBD><EFBFBD>嚗?

<EFBFBD>𣞁 <20><><EFBFBD><EFBFBD><E88880>?嚗鍃xternal Module獢<65><EFBFBD><E6B2B2><EFBFBD><EFBFBD>?

<EFBFBD><EFBFBD><EFBFBD>讛膩

External Module獢<65><EFBFBD><EFBFBD>撘箏之嚗䔶<E59A97><E494B6>?銝滚虾<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<EFBFBD>?

<EFBFBD>𣂼<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD>𣂼<EFBFBD>1嚗𡁏<EFBFBD>瘜蓥耨<EFBFBD>鄗EDCap<EFBFBD><EFBFBD><EFBFBD>屸𢒰

// <20>?<3F><EFBFBD><E4ADBE>𡁜<EFBFBD>嚗𡁜<E59A97><F0A1819C>冽𤜯<E586BD>㎞EDCap<61><70><EFBFBD><EFBFBD><E6A180><EFBFBD><E4BAA6>?
// <20><EFBFBD><E88ABE><EFBFBD>JavaScript瘜典<E7989C><E585B8>?憓𧼮撩"嚗峕<E59A97>瘜?<3F>踵揢"

function redcap_every_page_top($project_id) {
    ?>
    <script>
        // <20><EFBFBD>靽格㺿DOM嚗峕<E59A97>瘜閙𤜯<E99699>㟲銝芷△<E88AB7>?
        $('#data_entry_form').append('<div>AI<41><EFBFBD></div>');
    </script>
    <?php
}

**敶勗<E695B6>**嚗?

  • <EFBFBD>?<3F><EFBFBD>摰䂿緵"摰<><E691B0>摰𡁜<E691B0><F0A1819C>?<3F><>I
  • <EFBFBD>𩤃<EFBFBD> <20><EFBFBD>鈭竃EDCap<61><EFBFBD><E6AFBA>屸𢒰<E5B1B8><F0A292B0><EFBFBD><EFBFBD><E69285>峕甅撘?
  • <EFBFBD>𩤃<EFBFBD> REDCap<61>屸𢒰<E5B1B8><F0A292B0><EFBFBD><EFBFBD><E888AA><EFBFBD><E6B8B8>睲賑<E79DB2><E8B391>OM<4F><EFBFBD>

<EFBFBD>𣂼<EFBFBD>2嚗𡁏<EFBFBD>瘜閗挪<EFBFBD><EFBFBD>鈭𥟇瓲敹<EFBFBD><EFBFBD>?

// <20>?<3F>𣂷<EFBFBD>REDCap<61><70><EFBFBD><EFBFBD>賣㺭<E8B3A3><EFBFBD><E88890><EFBFBD>嚗袏xternal Module<6C><EFBFBD><EFBFBD>// 靘见<E99D98>嚗鋽ataQuality蝐餌<E89D90><E9A48C>𣂷<EFBFBD><F0A382B7><EFBFBD>

// REDCap<61><EFBFBD><EFBFBD><E99A9E><EFBFBD><E59A97>瘜閗挪<E99697><EFBFBD>
namespace REDCap\Internal;
class DataQuality {
    private function executeRule($ruleId) {
        // External Module<6C><EFBFBD><EFBFBD>鍂甇斗䲮瘜?
    }
}

<EFBFBD>𣂼<EFBFBD>3嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

// External Module<6C><65>ook隡𡁜<E99AA1><F0A1819C>𣳇<EFBFBD>憭硋<E686AD><E7A18B><EFBFBD>
function redcap_every_page_top($project_id) {
    // 餈嗘葵<E59798>賣㺭<E8B3A3><EFBFBD>銝芷△<E88AB7><EFBFBD><EFBD81><EFBFBD>
    // 憒<><E68692><EFBFBD><EFBFBD>憭齿<E686AD>嚗䔶<E59A97><E494B6>𡝗<EFBFBD>憿菟𢒰<E88F9F>㰘蝸
}

// 瘚贝<E7989A>蝏𤘪<E89D8F>嚗?
// - 蝛慵ook嚗?5-10ms
// - <20>㗇㺭<E39787><EFBFBD><E6A180>亥砭<E4BAA5><E7A0AD>ook嚗?50-200ms
// - <20>鵎TTP霂瑟<E99C82><E7919F><EFBFBD>ook嚗?500-2000ms

蝏栞捏嚗?

  • <EFBFBD>𩤃<EFBFBD> 銝滩<E98A9D><E6BBA9>沈ook銝剜<E98A9D>銵諹<E98AB5>埈𧒄<E59F88><EFBFBD>
  • <EFBFBD>?敹<>◆撘<E29786><EFBFBD>?

<EFBFBD>𣂼<EFBFBD>4嚗𡁜<EFBFBD><EFBFBD><EFBFBD>蝞?

// <20>?External Module餈鞱<E9A488><E99EB1><EFBFBD><E585B8>鞟㴓憓<E3B493>// <20><EFBFBD>霈輸䔮嚗?
// - REDCap摰㕑<E691B0><E39591><EFBFBD>憭𣇉<E686AD><F0A38789><EFBFBD>// - <20>𣂷<EFBFBD>蝟餌<E89D9F><E9A48C>賣㺭嚗Ềxec<65><63>hell_exec蝑㚁<E89D91>
// - <20>湔𦻖<E6B994><EFBFBD>PHP隡朞<E99AA1>

摨𥪜笆蝑𣇉裦

蝑𣇉裦1嚗𡁏𥅾<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>刻器<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𥟇鰵

  • <EFBFBD><EFBFBD><EFBFBD><EFBFBD>拍鍂Hook<EFBFBD><EFBFBD>
  • <EFBFBD><EFBFBD>JavaScript憓𧼮撩UI嚗<EFBFBD><EFBFBD><EFBFBD>舀𤜯<EFBFBD><EFBFBD>
  • 雿輻鍂API雿靝蛹"<22><><EFBFBD><EFBFBD>?

*蝑𣇉裦2嚗𡁏毽<EFBFBD><EFBFBD><EFBFBD>?

REDCap (<28>唳旿敶訫<E695B6>) + AI撟喳蝱 (<28><><EFBFBD>撅閧內)
  <20>?
<0A><EFBFBD><E586BD>沖EDCap敶訫<E695B6> <20>?<3F>唳旿<E594B3>峕郊 <20>?<3F>杗I撟喳蝱<E596B3><EFBFBD><E4BAA6><EFBFBD><EFBFBD>蝏𤘪<E89D8F>

餈蹱甅<EFBFBD>臭誑嚗?

  • <EFBFBD>?<3F>拍鍂REDCap<61><70><EFBFBD>閗挽霈膥嚗<E886A5>撩憭改<E686AD>
  • <EFBFBD>?<3F>拍鍂AI撟喳蝱<E596B3><E89DB1><EFBFBD><EFBFBD><EFBFBD><E99EB1>𨥈<EFBFBD><F0A8A588>菜暑嚗?
  • <EFBFBD>?閫<><E996AB>External Module<6C><65><EFBFBD><EFBFBD>?

<EFBFBD>𣞁 <20><><EFBFBD><EFBFBD><E88880>?嚗𡁜<E59A97><F0A1819C><EFBFBD><EFBFBD><E996AB><EFBFBD>HIPAA/GDPR嚗?

<EFBFBD><EFBFBD><EFBFBD>讛膩

REDCap<EFBFBD>𡁜虜摮睃<EFBFBD>**PHI嚗㇊rotected Health Information嚗匧<E59A97>靽脲擪<E884B2>亙熒靽⊥<E99DBD>**嚗<><EFBFBD>交𧒄<E4BAA4><F0A79284><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E79899>擃塩<E69383>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

HIPAA閬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

1. 霈輸䔮<E8BCB8><EFBFBD>嚗㇁ccess Control嚗?
   - <20><EFBFBD>霈方<E99C88><EFBFBD>撩撖<E692A9><E69296>+2FA嚗?
   - <20><>撠𤩺<E692A0><F0A4A9BA>𣂼<EFBFBD><F0A382BC>?
   - 摰∟恣<E2889F><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5979A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E98A8B>

2. <20>唳旿<E594B3><EFBFBD>嚗𠄌ncryption嚗?
   - 隡㰘<E99AA1><E3B098><EFBFBD>嚗関LS 1.2+
   - <20><EFBFBD><E8B9B1><EFBFBD><EFBFBD><E69296>AES-256
   - 撖<>𤨎蝞∠<E89D9E>嚗𡁜<E59A97><F0A1819C>蠘蔭<E8A098>?

3. <20>唳旿摰峕㟲<E5B395><EFBFBD>Integrity嚗?
   - <20>脩砥<E884A9><EFBFBD><E5B08D><EFBFBD>蝑曉<E89D91>
   - <20><>𧋦<EFBFBD><EFBFBD>嚗𡁏<E59A97><F0A1818F>劐耨<E58A90>孵虾餈賣滲

4. 摰∟恣<E2889F><EFBFBD>嚗㇁udit Logs嚗?
   - 靽嘥<E99DBD><E598A5><EFBFBD>6撟?
   - 銝滚虾<E6BB9A>𣳇膄
   - 摰𡁏<E691B0>摰⊥䰻

瞏𨅯銁憌𡡞埯<EFBFBD>?

憌𡡞埯1嚗𡁏㺭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隡㰘<EFBFBD><EFBFBD><EFBFBD>嚗?

// <20>?<3F>躰秤嚗䥅TTP隡㰘<E99AA1><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>
const response = await fetch('http://ai-platform.com/api/webhook', {
  method: 'POST',
  body: JSON.stringify(patientData)  // PHI<48><EFBFBD>隡㰘<E99AA1>嚗?
});

// <20>?甇<>嚗䥅TTPS + TLS 1.3
const response = await fetch('https://ai-platform.com/api/webhook', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': encryptedApiKey,
    'X-Signature': hmacSignature
  },
  body: JSON.stringify(patientData)
});

// <20>?<3F><EFBFBD><EFBFBD>甇伐<E79487>蝡臬<E89DA1>蝡臬<E89DA1>撖?
const encryptedPayload = await encrypt(patientData, publicKey);
await fetch('https://ai-platform.com/api/webhook', {
  method: 'POST',
  body: encryptedPayload
});

憌𡡞埯2嚗𡁏𠯫敹埈<EFBFBD><EFBFBD>?

// <20>?<3F>躰秤嚗䥪HI霈啣<E99C88><E595A3>冽𠯫敹𦯀葉
$this->log("<22><><EFBFBD>?撘牐<E69298> <20><>僑樴<E58391>蛹 45 撗?);
// 餈肽<E9A488><EFBFBD>𠯫敹𦯀葉銝滩<E98A9D><E6BBA9><EFBFBD>鉄PHI

// <20>?甇<>嚗朞<E59A97><E69C9E><EFBFBD>霈啣<E99C88>
$this->log("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>扇敶閙凒<EFBFBD>?, [
    'record_id' => hash('sha256', $record),  // <20><><EFBFBD><EFBFBD>?
    'field_count' => count($data),
    'timestamp' => time()
]);

憌𡡞埯3嚗鋫PI Token瘜<6E>

// <20>?<3F>躰秤嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD><EFBFBD>杗PI Token
$apiToken = 'ABC123DEF456...';  // 摮睃<E691AE><E79D83>其誨<E585B6><E8AAA8>
// <20>?<3F>躰秤嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD><EFBFBD>典銁<E585B8>唳旿摨?
INSERT INTO settings (key, value) 
VALUES ('api_token', 'ABC123DEF456...');

// <20>?甇<>嚗𡁜<E59A97><EFBFBD><E69296><EFBFBD>?
$encrypted = openssl_encrypt(
    $apiToken, 
    'AES-256-CBC', 
    $encryptionKey, 
    0, 
    $iv
);
INSERT INTO settings (key, value, iv) 
VALUES ('api_token', $encrypted, $iv);

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞉𧋦

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 摰墧鴌<EFBFBD>曉漲 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>? 摰∟恣<EFBFBD>鞉𧋦 <EFBFBD><EFBFBD><EFBFBD>?
霈輸䔮<EFBFBD><EFBFBD> <EFBFBD>椬 銝? 1-2<>? 瘥誩僑1甈? $$$
<EFBFBD>唳旿<EFBFBD><EFBFBD> <EFBFBD>椬 銝? 2-3<>? 瘥誩僑1甈? $$$
摰∟恣<EFBFBD><EFBFBD> <EFBFBD>叚 雿? 3-5憭? 瘥誩僑2甈? $$
摰匧<EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? 4-6<>? 瘥誩僑1甈?
*蝚砌<EFBFBD><EFBFBD>孵恣霈? <EFBFBD>𣞁 擃? N/A 瘥誩僑1甈? $
<EFBFBD>餉恣 <EFBFBD>𣞁 擃? 2-3銝芣<E98A9D> <EFBFBD><EFBFBD> *$10K-50K/撟?

<EFBFBD><EFBFBD> 憭齿<E686AD>摨血笆瘥䈑<E798A5>REDCap撖寞𦻖 vs <20><EFBFBD>EDC

摰𡁻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

蝏游漲 REDCap撖寞𦻖 <EFBFBD><EFBFBD>EDC 撖寞<EFBFBD>
*<EFBFBD><EFBFBD>穃𪂹<EFBFBD>? 2-3銝芣<E98A9D> 6-12銝芣<E98A9D> <EFBFBD>叚 REDCap敹?-5<>?
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>? $50K-100K $300K-500K <EFBFBD>叚 REDCap<61>?200K+
*蝏湔擪<EFBFBD>鞉𧋦/撟? $30K-50K $50K-80K <EFBFBD>椬 REDCap<61><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>箏𦛚 <EFBFBD>𣞁 擃矋<E69383>靘肽<E99D98>REDCap<61><70>漣嚗? <EFBFBD>叚 雿𠬍<E99BBF><EFBFBD><E691B0><EFBFBD>芯蜓嚗? <EFBFBD>𣞁 REDCap憌𡡞埯擃?
*<EFBFBD>菜暑<EFBFBD>? <EFBFBD>椬 銝哨<E98A9D><E593A8>㜬M獢<4D><EFBFBD>𣂼<EFBFBD>嚗? <EFBFBD>叚 擃矋<E69383><EFBFBD><E691B0><EFBFBD>芰眏嚗? <EFBFBD>𣞁 REDCap<61><EFBFBD>
*<EFBFBD><EFBFBD>摰峕㟲<EFBFBD>? <EFBFBD>叚 擃矋<E69383>REDCap<61><EFBFBD>嚗? <EFBFBD>椬 銝哨<E98A9D><E593A8><EFBFBD>隞𡡞妟撘<E5A69F><E69298>𡢅<EFBFBD> <EFBFBD>叚 REDCap隡睃飵
*AI<EFBFBD><EFBFBD><EFBFBD>摨? <EFBFBD>椬 銝哨<E98A9D><E593A8><EFBFBD>獢交𦻖嚗? <EFBFBD>叚 擃矋<E69383><E79F8B><EFBFBD><E6AFBA><EFBFBD><EFBFBD>嚗? <EFBFBD>𣞁 REDCap暻餌<E69ABB>
<EFBFBD><EFBFBD>雿㯄<EFBFBD> <EFBFBD>椬 銝哨<E98A9D>銝文<E98A9D>蝟餌<E89D9F>嚗? <EFBFBD>叚 擃矋<E69383>蝏煺<E89D8F>雿㯄<E99BBF>嚗? <EFBFBD>𣞁 REDCap<61><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD>

REDCap撖寞𦻖<EFBFBD><EFBFBD>OI<EFBFBD><EFBFBD><EFBFBD>嚗?

<0A>鞉𧋦嚗?
- 撘<><E69298>𡢅<EFBFBD>$80K
- 撟渡輕<E6B8A1><EFBFBD>$40K
- 5撟湔<E6929F><EFBFBD><E9A485>穿<EFBFBD>$280K

<0A><EFBFBD>嚗?
- <20><><EFBFBD><EFBFBD><E69298>烐𧒄<E78390><EFBFBD>9銝芣<E98A9D><EFBFBD>𣪧<EFBFBD>笔虾銝𤘪釣AI<41><EFBFBD>嚗?
- <20>拍鍂REDCap<61><EFBFBD><E99E9F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵典<E98AB5>霈曇恣<E69B87><EFBFBD><E585B7><EFBFBD><EFBFBD>鞟恣<E99E9F><E681A3><EFBFBD><EFBFBD>恣霈⊥𠯫敹?
- 敹恍<E695B9><EFBFBD><EFBFBD><E692A3>2-3銝芣<E98A9D> vs 12銝芣<E98A9D>

憌𡡞埯嚗?
- <20><><EFBFBD><EFBFBD>箏𦛚嚗帋<E59A97>韏餸EDCap
- <20><EFBFBD>雿㯄<E99BBF>嚗𡁜<E59A97>蝟餌<E89D9F><E9A48C><EFBFBD>揢
- <20><EFBFBD><E689AF><EFBFBD>嚗鍃AV璅<E79285>

蝏栞捏嚗?
<0A>?憒<><E68692><EFBFBD><EFBFBD><E6A0BC>?敹恍<E695B9><EFBFBD><EFBFBD><E99C82><EFBFBD>?嚗朙EDCap撖寞𦻖<E5AF9E><EFBFBD><E88880><EFBFBD>㗇𥋘
<0A>?憒<><E68692><EFBFBD><EFBFBD><E6A0BC>?<3F><EFBFBD>鈭批<E988AD>蝡硺<E89DA1><E7A1BA>?嚗諹䌊<E8ABB9>漋DC<44>游末
<0A><20><EFBFBD>蝑𣇉裦嚗𡁜<E59A97><F0A1819C>沖EDCap撖寞𦻖敹恍<E695B9>𠵱VP嚗<50><E59A97><EFBFBD><EFBFBD><EFBFBD><E99C82><EFBFBD>滩䌊<E6BBA9>?

<EFBFBD><20><><EFBFBD>遣霈桐<E99C88><E6A190><EFBFBD><E5969F>?

<EFBFBD><EFBFBD><EFBFBD>?

Q1: <20>臬炏撌脫<E6928C>REDCap<61><EFBFBD><E586BD><EFBFBD>嚗?
    <20><EFBFBD> <20>?<3F>?撘箇<E69298><E7AE87><EFBFBD>撖寞𦻖嚗<F0A6BB96><EFBFBD><EFBFBD>蝘餅<E89D98><E9A485><EFBFBD>嚗?
    <20><EFBFBD> <20>?<3F>?蝏抒賒Q2

Q2: <20>臬炏<E887AC><E7828F><EFBFBD>銁6銝芣<E98A9D><E88AA3><EFBFBD><EFBFBD><EFBFBD><E692A3>
    <20><EFBFBD> <20>?<3F>?<3F><EFBFBD>撖寞𦻖嚗<F0A6BB96><E59A97><EFBFBD><EFBFBD>笔漲敹恬<E695B9>
    <20><EFBFBD> <20>?<3F>?蝏抒賒Q3

Q3: <20>臬炏<E887AC><E7828F><EFBFBD><E996AC><EFBFBD><EFBFBD><E6B8A1><EFBFBD>雿㯄<E99BBF><E3AF84>峕楛摨再I<E5868D><49><EFBFBD>嚗?
    <20><EFBFBD> <20>?<3F>?<3F><EFBFBD><E588BB><EFBFBD><EFBFBD><E59A97>撉峕凒憟踝<E6869F>
    <20><EFBFBD> <20>?<3F>?<3F><EFBFBD>撖寞𦻖

Q4: <20><><EFBFBD>臬𣪧<E887AC><F0A3AAA7><EFBFBD><EFBFBD>PHP + REDCap蝏誯<E89D8F>嚗?
    <20><EFBFBD> <20>?<3F>?撖寞𦻖憌𡡞埯<F0A1A19E><EFBFBD>
    <20><EFBFBD> <20>?<3F>?摮虫<E691AE><E899AB>鞉𧋦+2<>?

Q5: <20>臬炏<E887AC>賣𦻖<E8B3A3>妔EDCap<61><70>漣撣行䔉<E8A18C><E49489><EFBFBD>毺輕<E6AFBA><EFBFBD><E69697>穿<EFBFBD>
    <20><EFBFBD> <20>?<3F>?<3F>臭誑撖寞𦻖
    <20><EFBFBD> <20>?<3F>?銝齿綫<E9BDBF>𣂼笆<F0A382BC>?

銝厩<EFBFBD>蝑𣇉裦

蝑𣇉裦1嚗帋<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

<EFBFBD>嗆挾1嚗?-3銝芣<E98A9D>嚗㚁<E59A97>REDCap撖寞𦻖MVP
  - 摰䂿緵<E482BF><EFBFBD><E7AE87>唳旿<E594B3>峕郊
  - <20><><EFBFBD>DC璅<E79285><EFBFBD><EFBFBD><EFBFBD>瘣梹<E798A3>
  - <20><EFBFBD>嚗𡁻<E59A97><EFBFBD><E99C82><EFBFBD><EFBFBD>瘙?

<0A>嗆挾2嚗?-6銝芣<E98A9D>嚗㚁<E59A97>瘛勗漲<E58B97><E6BCB2><EFBFBD>
  - <20><><EFBFBD>SSA璅<E79285><EFBFBD><E59A97><E99C88><E288AA><EFBFBD>
  - 隡睃<E99AA1><E79D83><EFBFBD><E689AF>𣬚鍂<F0A3AC9A><EFBFBD>撉?
  - <20><EFBFBD>嚗𡁶妖蝝舐鍂<E88890><EFBFBD><E79195>唳旿

<0A>嗆挾3嚗?-18銝芣<E98A9D>嚗㚁<E59A97><EFBFBD><EFBFBD><EFBFBD>
  - <20>寞旿<E5AF9E><EFBFBD><E586BD><EFBFBD><E6BCA4><EFBFBD><E596B3>臬炏<E887AC><EFBFBD>EDC
  - 憒<><E68692><EFBFBD>㦤撉諹<E69289><E8ABB9>𣂼<EFBFBD><EFBFBD><EFBFBD>刻䌊<E588BB>?
  - <20><EFBFBD>嚗𡁻鵭<F0A181BB><EFBFBD>鈭匧<E988AD>

隡睃飵嚗?
<0A>?憌𡡞埯<F0A1A19E>舀綉嚗<E7B689><E59A97><EFBFBD>嗆挾<E59786><EFBFBD>嚗?
<0A>?韏<><E99F8F>擃䀹<E69383><EFBFBD><E59A97>瘚芾晶<E88ABE><EFBFBD>蝖桀<E89D96><E6A180><EFBFBD><EFBFBD><EFBFBD>嚗?
<0A>?敹恍<E695B9><EFBFBD><EFBFBD><E99C82>3銝芣<E98A9D><EFBFBD><E996AB><EFBFBD><EFBFBD>

蝑𣇉裦2嚗𡁏<EFBFBD>餈𤤿<EFBFBD><EFBFBD><EFBFBD>銝齿綫<EFBFBD><EFBFBD>

<EFBFBD>湔𦻖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>EDC嚗?-12銝芣<E98A9D>嚗?

憌𡡞埯嚗?
<0A>?撣<><EFBFBD><E3A6A4><EFBFBD>𧊋撉諹<E69289>
<0A>?蝡𧼮<E89DA1><F0A7BCAE><EFBFBD><E888AA><EFBFBD>
<0A>?韏<><E99F8F><EFBFBD><EFBFBD>憭?

蝑𣇉裦3嚗𡁏毽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䀝葉嚗?

<EFBFBD>峕𧒄餈𥡝<EFBFBD>嚗?
- 撠誩𣪧<E8AAA9><F0A3AAA7><EFBFBD>2鈭綽<E988AD>撖寞𦻖REDCap嚗<70><EFBFBD>𠵱VP嚗?
- 憭批𣪧<E689B9><F0A3AAA7><EFBFBD>5鈭綽<E988AD><E7B6BD><EFBFBD>EDC嚗<43><EFBFBD>煺漣<E785BA><E6BCA3><EFBFBD>

<0A><EFBFBD>嚗?
- REDCap皛∟雲<E2889F><EFBFBD><E691B0>
- <20><EFBFBD>EDC雿靝蛹<E99D9D><E89BB9>漣頝臬<E9A09D>

憌𡡞埯嚗?
<0A>𩤃<EFBFBD><><E99F8F><EFBFBD><EFBFBD><0A>𩤃<EFBFBD> 銝文<E98A9D>蝟餌<E89D9F>蝏湔擪<E6B994>鞉𧋦擃?

<EFBFBD><EFBFBD> 憌𡡞埯<F0A1A19E>拚猐<E68B9A><EFBFBD>

憌𡡞埯憿? 敶勗<EFBFBD>蝔见漲 <EFBFBD>𤑳<EFBFBD><EFBFBD><EFBFBD> 隡睃<EFBFBD>蝥? 蝻栞圾<EFBFBD>芣鴌
EAV<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? <EFBFBD>𣞁 擃? P0 霈曇恣蝻枏<EFBFBD>撅?+ <20><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? <EFBFBD>椬 銝? P0 <EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD> + <20>𧼮<EFBFBD>瘚贝<E7989A>
*<EFBFBD>唳旿銝<EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>椬 銝? <EFBFBD>椬 銝? P1 <EFBFBD><EFBFBD><EFBFBD>峕郊 + 撟<><E6929F><EFBFBD>扯挽霈?
API<EFBFBD><EFBFBD> <EFBFBD>椬 銝? <EFBFBD>椬 銝? P2 <EFBFBD><EFBFBD>鸌憭<EFBFBD><EFBFBD> + <20><EFBFBD>
EM獢<EFBFBD><EFBFBD>𣂼<EFBFBD> <EFBFBD>椬 銝? <EFBFBD>叚 雿? P3 瘛瑕<EFBFBD><EFBFBD><EFBFBD>嚗㇌EDCap + AI撟喳蝱嚗?
摰匧<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>𣞁 擃? <EFBFBD>叚 雿? P0 <EFBFBD><EFBFBD> + 摰∟恣 + <20><><EFBFBD>霈方<E99C88>
蝏湔擪<EFBFBD>鞉𧋦 <EFBFBD>椬 銝? <EFBFBD>𣞁 擃? P1 <EFBFBD>遣銝㮖<EFBFBD><EFBFBD><EFBFBD>

<EFBFBD>𤁗 <20><><EFBFBD><E89D8F>霈?

蝑娍<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

Q: 銝竃EDCap撖寞𦻖<E5AF9E><EFBFBD><EFBFBD><E98A8B><EFBFBD><EFBFBD> A: **7憭扳<E686AD><E689B3><EFBFBD><E88880>?*嚗<><E59A97>銝?銝芣糓擃㗛<E69383><E3979B><EFBFBD>EAV<41><EFBFBD><E689AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝥扼<E89DA5><E689BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E996AB>

*Q: 銝滚虾<E6BB9A><EFBFBD><E68A92>唳䲮嚗? A: REDCap<EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滚虾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撟?-4甈∴<E79488><E288B4><EFBFBD><E888AA><EFBFBD><E6B8B8><EFBFBD><EFBFBD>嚗?

Q: <20><><EFBFBD>舫𠗕<E888AB><EFBFBD> A: EAV璅<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隡睃<EFBFBD><EFBFBD>?<EFBFBD><EFBFBD><EFBFBD>撘𤩺㺭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>憭折𠗕<EFBFBD>?

Q: 憭齿<E686AD><E9BDBF><EFBFBD><E68A98><EFBFBD> A: **銝剔<E98A9D><E58994><EFBFBD>憭齿<E686AD>摨?*嚗?/5嚗?

  • 瘥磰䌊<EFBFBD>漋DC蝞<EFBFBD><EFBFBD>𤏪<EFBFBD>REDCap<EFBFBD><EFBFBD>鈭?0%撌乩<E6928C>嚗?
  • 瘥𥪜<EFBFBD>蝥涉PI<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><E588BB><EFBFBD>嚗𡁜<E59A97><F0A1819C>嗆挾蝑𣇉裦

Phase 1 (0-2銝芣<E98A9D>): <20><EFBFBD><E888AA><EFBFBD>霂?
  - <20>剖遣REDCap瘚贝<E7989A><E8B49D><EFBFBD>
  - 撘<><E69298><EFBFBD>撠㛁xternal Module嚗<65><EFBFBD>𡁜<EFBFBD><F0A1819C><EFBFBD>甇伐<E79487>
  - 瘚贝<E7989A>EAV<41><EFBFBD><E689AF><EFBFBD><EFBFBD>鍂10銝<30><EFBFBD><EFBFBD><E7AC94>唳旿嚗?
  - 霂<>摯嚗𡁏糓<F0A1818F>衣誧蝏哨<E89D8F>

Phase 2 (2-3銝芣<E98A9D>): MVP撘<50><E69298>?
  - <20>芸笆<E88AB8>主C璅<E79285><EFBFBD><E59A97><EFBFBD>劐遠<E58A90><EFBFBD>
  - <20><EFBFBD><E8A8AB>峕郊嚗㇌EDCap <20>?AI嚗?
  - 銝滩<E98A9D><E6BBA9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰墧𧒄
  - <20><EFBFBD>嚗?-10銝芾<E98A9D><E88ABE>孵恥<E5ADB5>?

Phase 3 (3-6銝芣<E98A9D>): <20>寞旿<E5AF9E><EFBFBD><E6BCA4><EFBFBD>
  - 憒<><E68692><E691B0><EFBCB8><EFBFBD>憟?<3F>?瘛勗漲<E58B97><E6BCB2><EFBFBD>
  - 憒<><E68692><EFBFBD><EFBFBD><E689AF><EFBFBD><E59C92>擧遬 <20>?<3F><><EFBFBD><EFBFBD><EFBFBD>
  - 憒<><E68692>蝏湔擪<E6B994>鞉𧋦憭芷<E686AD> <20>?頧砍<E9A0A7><E7A08D><EFBFBD>

<EFBFBD><20>喲睸撱箄悅嚗?

  1. <EFBFBD>?銝滩<E98A9D><EFBFBD><EFBFBD>憪见停餈賣<E9A488>"摰𣬚<E691B0>撖寞𦻖"
  2. <EFBFBD>?<3F><><EFBFBD><E98D82><EFBFBD><E89D9E>閙䲮獢<E4B2AE><E78DA2><EFBFBD><E99C82><EFBFBD><E79899><EFBFBD><EFBFBD><E8A8AB>峕郊頞喳<E9A09E>嚗?
  3. <EFBFBD>?<3F>𣂼<EFBFBD><EFBFBD><E996AB>"<22><><EFBFBD><EFBFBD><E7AE87>?嚗<><E59A97><EFBFBD>𨅯笆<F0A885AF>亙仃韐伐<E99F90><EFBFBD><E68692><EFBFBD><EFBFBD><EFBFBD>啗䌊<E59597><EFBFBD>
  4. <EFBFBD>𩤃<EFBFBD><><EFBFBD>侨HP + REDCap蝏誯<E89D8F><E8AAAF><EFBFBD>𣪧<EFBFBD><F0A3AAA7><EFBFBD><EFBFBD><EFBFBD>1鈭綽<E988AD>
  5. <EFBFBD>𩤃<EFBFBD><><E686B8>20-30%<25><>𧒄<EFBFBD><EFBFBD>撖?<3F><EFBFBD>"嚗<><E59A97><EFBFBD><EFBFBD>蝥扼<E89DA5><E689BC>ug嚗?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗鯝1.0
**<2A><><EFBFBD>擧凒<E693A7>?*嚗?025-12-30
銝𧢲活霂<EFBFBD>嚗䥪hase 1摰峕<E691B0><E5B395>𠬍<EFBFBD>2銝芣<E98A9D>嚗?


*<EFBFBD>辶 霈唬<E99C88>嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD>瘝⊥<E7989D>摰𣬚<E691B0><F0A3AC9A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E58EB0><EFBFBD>敶枏<E695B6><E69E8F>嗆挾<E59786><E68CBE>䲮獢<E4B2AE><E78DA2>?