> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirobody.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 Provider

> 配置凭据并将可穿戴设备、聚合器或 EHR 关联到 Mirobody。

## 关联如何工作

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

## 1 —— 配置凭据

每个 vendor 按约定从环境变量读取其凭据（`<ID>` 是 vendor id 的大写形式）：

```bash theme={null}
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
```

示例：

```bash theme={null}
# 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
```

<Info>
  由于名称中含 `_KEY` / `_SECRET` / `_TOKEN` 的配置值会在加载时自动加密（Fernet，经 `CONFIG_ENCRYPTION_KEY`），你也可以把这些值写进 `config.yml`。环境变量优先。参见[配置](/zh/configuration)。
</Info>

在 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，并限定在已认证用户范围内）：

<Steps>
  <Step title="Bind">
    将外部账号 id 记录为 PENDING 关联。

    ```bash theme={null}
    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"}'
    ```

    <Note>各 vendor 具体的请求体可能不同；请查看该 vendor 的 `.cpp` 与 `src/health/vendor_service.*`。*(verify)*</Note>
  </Step>

  <Step title="Verify">
    通过该 vendor 的同意 / 认领流程证明所有权。成功后该关联被标记为 VERIFIED。

    ```bash theme={null}
    curl -X POST "http://localhost:8080/vendors/fitbit/bind/verify" \
      -H "Authorization: Bearer $JWT"
    ```

    一个 `UNIQUE(vendor_id, external_user_id)` 约束是最后一道防线 —— 两名用户不能都认领同一个账号。
  </Step>

  <Step title="Fetch data">
    验证之后，在某个时间区间内拉取一个数据域。`Vendor::fetch` 运行并返回该源的 JSON。

    ```bash theme={null}
    curl "http://localhost:8080/vendors/fitbit/data?domain=heart_rate&start=2026-06-01&end=2026-06-30" \
      -H "Authorization: Bearer $JWT"
    ```

    合法的 `domain` 取值：`activity`、`sleep`、`heart_rate`、`glucose`、`nutrition`、`body_metrics`、`labs`、`clinical`（vendor 会拒绝它不中转的域）。
  </Step>
</Steps>

## 连接一个 EHR（SMART on FHIR）

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

<Steps>
  <Step title="查找租户">
    在 Service Base URL 目录中搜索该医院 / 诊所：

    ```bash theme={null}
    curl "http://localhost:8080/health/ehr/providers?q=Epic" -H "Authorization: Bearer $JWT"
    ```
  </Step>

  <Step title="Authorize">
    `POST /health/ehr/authorize {fhir_base_url}` 运行 SMART 发现（`/.well-known/smart-configuration`）+ PKCE，缓存 verifier/state，并返回供浏览器跳转的 `authorize_url`。
  </Step>

  <Step title="Callback">
    EHR 重定向回 `GET /health/ehr/callback?code=&state=`；该 code 会被换成一个 access token，按用户缓存。
  </Step>

  <Step title="Sync">
    `POST /health/ehr/sync` 使用缓存的 token，经 `ehr` 客户端获取 `Observation` 并逐条经 FHIR 存储持久化。
  </Step>
</Steps>

用 `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`。参见[数据流](/zh/concepts/data-flow)。

## 自带 provider

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

## 下一步

<CardGroup cols={2}>
  <Card title="Provider 概览" icon="plug" href="/zh/providers/overview">
    已发布 vendor 的完整列表
  </Card>

  <Card title="配置" icon="gear" href="/zh/configuration">
    凭据的写入位置以及加密如何工作
  </Card>

  <Card title="Garmin 示例" icon="watch" href="/zh/examples/garmin-provider">
    一个设备品牌客户端的走查
  </Card>

  <Card title="Provider 集成" icon="code" href="/zh/development/provider-integration">
    实现一个新的 `vendor::Vendor`
  </Card>
</CardGroup>
