@crvouga/mockingbird-service-healthie

中文文档
3.11.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 1.6万

Healthie GraphQL API (Legacy surface) 的状态仿真器: 签名 In, 用户, 当前用户, 更新 User/ updateClient( 包括多部分的avatar), 地址, 文件和文件夹, 服务下载, 格式答案, 提供, 计费项目, IP- allowl

中文使用文档
文档目录11 节
  1. 安装
  2. 使用量
  3. 路线
  4. 网络呼号
  5. 管理员(超过标准合同)
  6. 命名空间
  7. 客户
  8. 为什么 graphql 是一个运行时间依赖
  9. 在我们的消费者中发现的差别(模仿者跟随销售商,测试结果为他们定下钉子)
  10. 故意不模拟
  11. API 密码

@crvouga/mockingbird-service-healthie (英语)

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

国家模拟器 健康图QL API覆盖着遗产 仍然暴露我们的后端 电话:

  • 签名、用户、当前用户以及配置、密码和外观更新
  • 客户端更新和地址
  • 文档和文件夹,包括多部分上传,下载由模拟器提供
  • 请求的窗体和窗体答案
  • 提供和收费项目
  • iP 允许列表状态的 Webhooks

图QL 文档运行在引用上 graphql 与Healthie用手写的一套计划相对应 选择集,别名, 碎片,变量, __typename 和验证错误的行为 健康, 模拟器只返回文档要求的字段 .

  • 行动范围: 支助
  • 健康出版SDL但无OpenAPI. openapi.yaml 描述 HTTP 侧: 一个 GraphQL 操作和文件下载路径。 GraphQL 计划为 HEALTHIE_SDL。 。 。 .

这值得测试吗? 目录(S23)将"健康"标为"遗产". 任用和 供应商搬到了Medplum。 剩下的是遗留的签名、密码重置、配置和 地址、ODX文档上传、管理导出和迁移。 检查一个套房仍然 练习这些路径,然后将模拟器接入堆栈。 已充分执行 无论是哪种方式.

安装

npm install -D @crvouga/mockingbird-service-healthie

仅限无害环境管理。 节点 22或 Bun 1.2. 单程依赖之外 hono 是大众 graphql 软件包(以16.11.0为基准,我们的后端使用版本)。 见 为什么 graphql{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}为它服务 npx mockingbird-healthie serve, (中文(简体) ), createServer 从 ./server (节点),或 createRuntime 与任何获取服务器.

使用量

点 HEALTHIE_API_URL 时间 http://127.0.0.1:8816/graphql。这需要缝合 G-H1级 第一条: 后端的Joi和zod计划目前只接受中转或推进的URL,以及 HEALTHIE_WEBHOOK_IP_ADDRESS 只有两个IP列表。 设定 HEALTHIE_API_AUTH_TOKEN 在应用程序中 并传递与 --api-key。 。 。 .

npx mockingbird-healthie serve --port 8816 \
  --api-key "$HEALTHIE_API_AUTH_TOKEN" \
  --webhook-base-url http://127.0.0.1:3000 \
  --webhook-ip 18.206.70.225
import { GraphQLClient, gql } from "graphql-request"
import { createRuntime, SEED } from "@crvouga/mockingbird-service-healthie"

// Test setup: the emulator, in this process.
const emulator = createRuntime({
  settings: { orgApiKeys: ["gh_sbox_test_org"] },
  webhooks: { baseUrl: "http://127.0.0.1:3000", ip: "18.206.70.225" },
})

// Application code: the GraphQL client the app already uses (here graphql-request). Only its
// fetch changes: requests reach the emulator instead of api.gethealthie.com.
const healthie = new GraphQLClient("https://api.gethealthie.com/graphql", {
  headers: { AuthorizationSource: "API" },
  fetch: ((url: RequestInfo | URL, init?: RequestInit) =>
    emulator.fetch(new Request(url, init))) as typeof fetch,
})

// The seeded demo patient signs in and gets an API key, as the member app does.
const signedIn = await healthie.request<{ signIn: { api_key: string; user: { id: string } } }>(
  gql`
    mutation ($e: String, $p: String) {
      signIn(input: { email: $e, password: $p, generate_api_token: true }) {
        api_key
        user { id active }
      }
    }
  `,
  { e: SEED.patientEmail, p: SEED.patientPassword },
)

// Test control: ask Healthie to request a form from the patient. POST /forms/webhooks/status
// follows.
await emulator.fetch(
  new Request("http://healthie.test/__admin/requested-forms", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ recipient_id: SEED.patientId }),
  }),
)

路线

路线行为
POST /graphql以JSON形式发出的每一份请求文件 {query, variables, operationName} 或作为 图QL 多部分请求 (单位:千美元)operations, (中文(简体) ), map,文件部分)用于 Upload 变量。 这个 Authorization 标题将 API 密钥作为 Bearer <key>, (中文(简体) ), Basic <key> 或空钥匙. AuthorizationSource: API 被接受和忽略。 错误会随着HTTP 200而出现,如Healthie. 一个不是GraphQL的身体得到一个400.
GET /files/{token}后面的字节 document.expiring_url 财务报告和审定财务报表 user.avatar_url,这里关于请求本身的来源(与 /__admin/ns/<name> 当名称空格。 链接在模拟器时钟上签名并过期( L)expiringUrlSeconds,默认为300). 被篡改或过期的链接得到一个403,被删除的文件得到一个404. 每次下载都会增加一个条目 document.opens。 。 。 .

图QL 根字段 : currentUser, (中文(简体) ), user(id), (中文(简体) ), users(keywords, should_paginate, …), (中文(简体) ), location(id), (中文(简体) ), locations, (中文(简体) ), documents(…), (中文(简体) ), document(id), (中文(简体) ), folders(…), (中文(简体) ), requestedFormCompletion(id), (中文(简体) ), formAnswerGroups(user_id, …), (中文(简体) ), formAnswerGroup(id), (中文(简体) ), initialFormAnswers(custom_module_form_id, incomplete_form_id, user_id), (中文(简体) ), offerings(client_visibility, offering_id, …) 财务报告和审定财务报表 billingItems(offerings_only, client_id, status)。 。 。 .

变异 :

  • signIn(input)数字 : generate_api_token 财务报告和审定财务报表 allow_multiple_api_keys 将受优待 namespace 当一个被设定的时候.
  • updateUser(input): 设置配置字段, 上传一个外观为 Upload,用 avatar: null,或更改密码。 密码变体发送出否 id 检查 current_password 财务报告和审定财务报表 password_confirmation。 。 。 .
  • updateClient(input)数字 : metadata, (中文(简体) ), phone_number, (中文(简体) ), password, (中文(简体) ), other_provider_ids, (中文(简体) ), user_group_id, (中文(简体) ), dietitian_id, (中文(简体) ), active,以及 location 作为 ClientLocationInput。 。 。 .
  • createLocation 财务报告和审定财务报表 updateLocation。 。 。 .
  • createFolder: 剖析 share_users 以 "user-<id>,…"。 。 。 .
  • createDocument: 取一个 Upload 或一个 file_string 数据 URL,加 share_users 财务报告和审定财务报表 rel_user_id。 。 。 .
  • deleteDocument。 。 。 .
  • updateBillingItem数字 : is_paused, (中文(简体) ), is_canceled, (中文(简体) ), note 财务报告和审定财务报表 state我们的客户发送它作为 两个别名在一个文档中的变异; 每个发出 billing_item.updated。 。 。 .

行为我们的代码分支:

  • 坏键 : 未知的 API 密钥返回 errors: [{message: "API Key is Invalid"}],哪个 我们的客户端地图401.
  • 无密钥 : currentUser 实值 null,列表为空和变异,但 signIn 失败. 我们 listFiles 转动 null 变成401.
  • 验证 : 失败归来作为 messages: [{field, message}] 带有 null 有效载荷, 我们的客户标到400. messages 实值 null 成功;我们 getFolderByPath 治疗 任何非虚值为失败.
  • 签名 : 错误的电子邮件或密码返回 user: null,我们的客户端地图 INVALID_SIGN_IN_CREDENTIALS。一个存档的用户标志 active: false,哪个地图 USER_ARCHIVED。 。 。 .
  • 谁看到什么: 患者键只看到自己的用户、护理团队、自己的文件以及 任何与它分享的东西。 组织的关键看到了一切.

网络呼号

保健活动作为 {resource_id, resource_id_type, event_type, changed_fields?}。 。 。 . resource_id 作为字符串发送,因为我们的 DTO 验证 @IsString()。每项请求 携带 x-forwarded-for: <ip>,而那个信头是 我们的接收器的唯一检查 HEALTHIE_WEBHOOK_IP_ADDRESS没有签名.

活动接收人(--webhook-base-url +路径)发件人
patient.created, (中文(简体) ), patient.updated/users/webhook/statusupdateUser, (中文(简体) ), updateClient, (中文(简体) ), POST /__admin/users,存档和无存档
requested_form_completion.created, (中文(简体) ), form_answer_group.created/forms/webhooks/statusPOST /__admin/requested-forms, (中文(简体) ), POST /__admin/form-answer-groups
billing_item.updated(默认无;添加一个为 PUT /__admin/webhook-endpoints(中文(简体) )updateBillingItem

POST /__admin/events {event_type, resource_id, resource_id_type} 发出任何事件。 交货 然后在5秒、5分、30分和2分之后再审。 标准管理员路线 还适用: GET /__admin/webhooks, (中文(简体) ), …/events, (中文(简体) ), …/:id/replay 财务报告和审定财务报表 …/flush。 。 。 .

管理员(超过标准合同)

路线效果
GET /__admin/users, (中文(简体) ), POST /__admin/users列表用户(从未密码). 从 {email, password, first_name?, last_name?, role?: patient | provider, active?, dietitian_id?, …} 回来 {user, api_key}。 。 。 .
POST /__admin/users/:id/archive | /unarchive设定 active (存档用户与 active: false) (中文(简体) ).
POST /__admin/users/:id/api-keys为用户发行另一个 API 密钥 .
POST /__admin/offerings{name, price?, billing_frequency?, visibility_status?}。 。 。 .
POST /__admin/billing-items{sender_id, offering_id?, amount_paid?, state?, is_recurring?, next_payment_date?}。 。 。 .
POST /__admin/form-answer-groups{user_id, custom_module_form_id?, filler_id?, answers?: {<label or module id>: answer}} (内容为webhook表格).
POST /__admin/requested-forms{recipient_id, sender_id?, custom_module_form_id?} (内容为webhook表格).
POST /__admin/events放弃任何健康活动.
GET /__admin/documents命名空间的文档元数据 .
GET | PUT /__admin/settings{orgApiKeys?, namespace?: string | null, expiringUrlSeconds?}。 。 。 .

种子数据SEED),在重置时重制:

  • 100001: 组织管理员,与每个组织挂钩 orgApiKeys 条目(默认) gh_sbox_org_api_key) (中文(简体) ).
  • 100002(原始内容存档于2018-03-26). : Datitian Dana Rivera, MD.
  • 100003: 演示病人 [email protected] 编号 : Password123!。 。 。 .
  • 提供 200001 和 200002 (加上,隐去也.
  • 申请表 300001。 。 。 .

错误预设( E)POST /__admin/faults {"preset": "<name>", "count"?: n}:

  • invalid_api_key
  • graphql_500: 包含 500为了我们的500个分支.
  • validation_messages
  • current_user_null
  • expired_urls
  • http_500
  • rate_limited (429个)
  • server_error
  • webhook_duplicate, (中文(简体) ), webhook_reorder, (中文(简体) ), webhook_drop

命名空间

选择三种命名空间:

  • 页:1 x-mockingbird-namespace 页眉;
  • (单位:千美元) /__admin/ns/<name>/graphql 前缀在 HEALTHIE_API_URL (文件 URL 保留前缀);
  • 按 API 键,使用 PUT /__admin/credentials {"credentials": {"<key>": "<namespace>"}}。 。 。 .

signIn 发送没有密钥, 所以并行的套件, 在需要时签名头或路径前缀 .

客户

健康没有正式的节点SDK. 我们的后端通过它说话 graphql-request 7.2.0 联合国 页:1 awesome-graphql-client 0.14.1(多个部分) Upload 页:1 这个 接受测试将模拟器通过这些精确的版本,被固定为devdependents 后端的文档逐字复制( q)test/consumer.ts) (中文(简体) ). 一个单独的 SDK 滴入测试 重复他们.

为什么 graphql 是一个运行时间依赖

我们消费者的文件需要真正的GraphQL语义: 验证一个计划, 每个选择的分辨率,别名(两个) updateBillingItems 在一个文件中, __typename, (中文(简体) ), 和多变的强迫。 包括投放未申报变量的图ql-js,其中之一 我们的文件在不知不觉中依赖.

一个手卷式的解析器会从这些规则中漂移出来,而这正是平等必须达到的目的 保护. graphql 是一个公开的,无依赖的 npm 软件包, 绑在版本我们的 后端使用,所以它是正常的 dependency 而不是被捆绑.

在我们的消费者中发现的差别(模仿者跟随销售商,测试结果为他们定下钉子)

  • createLocation 发送 city: line2 永远不要宣布 $line2因此,健康储存 第二地址线作为城市.
  • updateCheckoutPatientById 发送一个 timezone 变量,文档从未声明, 所以健康忽略了这一点.
  • FormsService.formRequestStatus 读取 recipient.id,其查询从不选择。 这个 因此它删除的缓存密钥是 …:undefined。 。 。 .
  • pauseBillingItem 类型 isPaused 作为弦. 一个字符串发送到 $is_paused: Boolean 会被GraphQL可变强制拒绝. 该方法今天没有呼叫者.

故意不模拟

  • 我们的消费者不再用预约 提供商 计量标准, 目标 图表 聊天 网络游戏管理 花脸卡突变, createClient编号 :signUp, (中文(简体) ), userGroup, (中文(简体) ), offeringCoupons, (中文(简体) ), createApiKey, (中文(简体) ), updateFolder编号 :deleteFolder, (中文(简体) ), updateDocument。查询一个失败 GraphQL 验证,就像一个打字机那样.
  • 健康网的签名(Content-Digest 编号 : Signature) (中文(简体) ). 我们的接收器只验证 源IP,所以交付没有签名.
  • 真实的页形光标 : should_paginate 10页 offset。模糊的关键字搜索是 在电子邮件和姓名上进行大小写不敏感子字符串匹配.
  • 上载流量 苹果健康与Google适切链接:永远 null。 。 。 .
  • 真实兽类的活数据. 种子数据是合成的; 通过管理员添加用户和记录 路线.

API 密码

导出仁爱说明
HealthieAPI类进程模拟器 : fetch(request), (中文(简体) ), reset(), (中文(简体) ), userForKey(key), (中文(简体) ), emit(event), (中文(简体) ), fileUrl(origin, fileId), (中文(简体) ), state选项: sqlite, (中文(简体) ), now, (中文(简体) ), namespace, (中文(简体) ), publicNamespace, (中文(简体) ), settings, (中文(简体) ), onEvent。 。 。 .
createRuntime函数全面服务合同的仿真器(健康、管理、命名空间、证书、预设、网络呼号)。 选项 : settings, (中文(简体) ), webhooks: {baseUrl, ip?, retryDelaysMs?, fetch?}, (中文(简体) ), clock, (中文(简体) ), seed, (中文(简体) ), adminKey, (中文(简体) ), onLog。 。 。 .
HEALTHIE_PRESETS对象每个命名的断层预设.
HEALTHIE_EVENT_ROUTES对象接收路径 – 事件类型 .
healthieEndpoints函数后端基址和源 IP 的 Webhook 端点 .
DEFAULT_WEBHOOK_IP字符串18.206.70.225默认值 x-forwarded-for。 。 。 .
HEALTHIE_NAMESPACE字符串服务名称, "healthie"。 。 。 .
INVALID_API_KEY字符串"API Key is Invalid"。 。 。 .
HEALTHIE_SDL, (中文(简体) ), healthieSchema数值GraphQL 子集( SDL 和已建) GraphQLSchema) (中文(简体) ).
Upload类文件绑入 Upload 变量由多段运算.
apiKeyOf函数API 密钥 a Authorization 头带( 如何将证书映射到命名空间) .
healthieTimestamp函数卫生 YYYY-MM-DD HH:MM:SS +0000 时间戳格式.
parseShareUsers函数"user-1,user-2" → ["1", "2"]。 。 。 .
SEED, (中文(简体) ), DEFAULT_SETTINGS对象种子代号与证书; 默认设置.
document, (中文(简体) ), operationIds, (中文(简体) ), supportedOperationIds数值HTTP合同及其操作代号.
createServer, (中文(简体) ), serveTarget, (中文(简体) ), DEFAULT_PORT (单位:千美元)./server(中文(简体) )节点服务过来 node:http; 数据 serve CLI目标; 第8816口.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-healthie 共发布 41 个版本,首次发布于 2026/09/23;过去 12 个月发布了 41 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/11/11今天
3.10.82026/11/038 天前
3.10.72026/11/038 天前
3.10.62026/11/038 天前
3.10.52026/11/038 天前
3.10.42026/11/038 天前

关于 @crvouga/mockingbird-service-healthie 的常见问题

@crvouga/mockingbird-service-healthie 是什么?

Healthie GraphQL API (Legacy surface) 的状态仿真器: 签名 In, 用户, 当前用户, 更新 User/ updateClient( 包括多部分的avatar), 地址, 文件和文件夹, 服务下载, 格式答案, 提供, 计费项目, IP- allowl

如何安装 @crvouga/mockingbird-service-healthie?

在项目目录运行 npm install @crvouga/mockingbird-service-healthie,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-healthie,可以用 npx mockingbird-healthie 直接运行。

@crvouga/mockingbird-service-healthie 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-healthie 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-healthie 可以商用吗?

@crvouga/mockingbird-service-healthie 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-healthie 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-healthie 在 2026/10/11 – 2026/11/09 这 30 天内被下载 16,127 次,日均约 538 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-healthie 还在维护吗?

最新版本 3.11.0 发布于 2026/11/11(今天);至今共发布 41 个版本,其中过去 12 个月发布了 41 个;首次发布于 2026/09/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。