跳转到主要内容

关联如何工作

连接一个数据源分两个阶段:配置凭据(由运维方一次性完成)与关联账号(按用户、所有权门控)。数据随后流入内嵌的 FHIR 存储,agent 在其中读取。关于底层契约,参见 Vendor 系统

1 —— 配置凭据

每个 vendor 按约定从环境变量读取其凭据(<ID> 是 vendor id 的大写形式):
MIROBODY_VENDOR_<ID>_API_KEY=...        # bearer / API key (most REST vendors)
MIROBODY_VENDOR_<ID>_CLIENT_ID=...      # OAuth client id
MIROBODY_VENDOR_<ID>_CLIENT_SECRET=...  # OAuth client secret
MIROBODY_VENDOR_<ID>_BASE_URL=...       # host override; empty => vendor default
示例:
# Fitbit (device brand, OAuth 2.0)
MIROBODY_VENDOR_FITBIT_CLIENT_ID=your_client_id
MIROBODY_VENDOR_FITBIT_CLIENT_SECRET=your_client_secret

# Terra (aggregator)
MIROBODY_VENDOR_TERRA_API_KEY=your_api_key

# Generic EHR (SMART on FHIR) — base_url is REQUIRED (per-tenant FHIR base)
MIROBODY_VENDOR_EHR_BASE_URL=https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/
MIROBODY_VENDOR_EHR_API_KEY=smart_on_fhir_access_token
由于名称中含 _KEY / _SECRET / _TOKEN 的配置值会在加载时自动加密(Fernet,经 CONFIG_ENCRYPTION_KEY),你也可以把这些值写进 config.yml。环境变量优先。参见配置
在 vendor 的开发者门户注册你的应用以获取 client id / secret(或 API key)。通用 ehr 客户端需要租户的 FHIR 服务 base URL,可从公开的 Service Base URL 目录(ONC Lantern;Oracle Health / Cerner)发现。

2 —— 关联账号(bind → verify → data)

关联是所有权门控的:用户在读取任何数据之前先证明其拥有该外部账号,因此一个自称的 id 永远无法触及他人的记录。健康模块暴露三条路由(都需要 bearer JWT,并限定在已认证用户范围内):
1

Bind

将外部账号 id 记录为 PENDING 关联。
curl -X POST "http://localhost:8080/vendors/fitbit/bind" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"external_user_id": "FITBIT_USER_ID"}'
各 vendor 具体的请求体可能不同;请查看该 vendor 的 .cppsrc/health/vendor_service.*(verify)
2

Verify

通过该 vendor 的同意 / 认领流程证明所有权。成功后该关联被标记为 VERIFIED。
curl -X POST "http://localhost:8080/vendors/fitbit/bind/verify" \
  -H "Authorization: Bearer $JWT"
一个 UNIQUE(vendor_id, external_user_id) 约束是最后一道防线 —— 两名用户不能都认领同一个账号。
3

Fetch data

验证之后,在某个时间区间内拉取一个数据域。Vendor::fetch 运行并返回该源的 JSON。
curl "http://localhost:8080/vendors/fitbit/data?domain=heart_rate&start=2026-06-01&end=2026-06-30" \
  -H "Authorization: Bearer $JWT"
合法的 domain 取值:activitysleepheart_rateglucosenutritionbody_metricslabsclinical(vendor 会拒绝它不中转的域)。

连接一个 EHR(SMART on FHIR)

EHR 是网页能够自行连接的唯一临床数据源(Apple / Samsung 仅设备本地可用)。Mirobody 充当该 EHR 的 OAuth 客户端。浏览器驱动的流程位于 /health/ehr/* 下:
1

查找租户

在 Service Base URL 目录中搜索该医院 / 诊所:
curl "http://localhost:8080/health/ehr/providers?q=Epic" -H "Authorization: Bearer $JWT"
2

Authorize

POST /health/ehr/authorize {fhir_base_url} 运行 SMART 发现(/.well-known/smart-configuration)+ PKCE,缓存 verifier/state,并返回供浏览器跳转的 authorize_url
3

Callback

EHR 重定向回 GET /health/ehr/callback?code=&state=;该 code 会被换成一个 access token,按用户缓存。
4

Sync

POST /health/ehr/sync 使用缓存的 token,经 ehr 客户端获取 Observation 并逐条经 FHIR 存储持久化。
SMART_FHIR_* 系列键配置 SMART 客户端(client id / redirect uri / scope;参见 config.example.yml)。在 Web 客户端中,这是 Settings → Connect EHR

设备本地存储(此处无需关联)

Apple Health、Samsung Health、Google Health Connect 以及小米在服务端没有服务端 API,也没有关联流程。原生宿主 App 在设备本地读取它们,并把 FHIR Observation POST 到 /fhir。参见数据流

自带 provider

如果你需要的数据源尚未发布,在 src/health/vendor/ 下添加一个 vendor::Vendor 并注册它 —— 参见 Provider 集成。由于 vendor 是编译进程序的,你需要重新构建内核,而不是在运行时投放一个文件。

下一步

Provider 概览

已发布 vendor 的完整列表

配置

凭据的写入位置以及加密如何工作

Garmin 示例

一个设备品牌客户端的走查

Provider 集成

实现一个新的 vendor::Vendor