@crvouga/mockingbird-service-caretalk

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

Stateful emulator of CareTalk's external API: client-login tokens, GetForm definitions, SavePatientForm rounds, patient search/insert, states, free slots and appointments.

原始使用文档
文档目录7 节
  1. Install
  2. Usage
  3. Routes
  4. Admin (beyond the standard contract)
  5. Namespaces
  6. Deliberately not modelled
  7. API

@crvouga/mockingbird-service-caretalk

Local emulators. Real API contracts. Part of Mockingbird.

Stateful emulator of CareTalk's external API (/externalapi) for test suites: client login, form definitions (GetForm) and saved form rounds (SavePatientForm, the form-submission queue's call), patient search and insert (the account backfill), states, free slots and appointments. The backend requires CareTalk keys at boot, so the emulator lets a stack boot and run the CareTalk paths without the beta environment.

  • Operation coverage: SUPPORT.md
  • The vendor publishes no spec: the contract (openapi.yaml) is hand-authored from the consumer's zod schemas and interfaces (caretalk.types.ts, caretalk-forms.type.ts).

Install

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

ESM only. Node >= 22 or Bun >= 1.2. No native dependencies. Serve it with npx mockingbird-caretalk serve, createServer from ./server (Node), or createRuntime with any Fetch server.

Usage

Point CARETALK_API_URL at the emulator (the backend validates it as https-only, so relax that for loopback or front the emulator with TLS). getFormData hardcodes https://api.caretalkbeta.com (seam G-Y1). CARETALK_USERNAME, CARETALK_PASSWORD and CARETALK_API_KEY can be any values unless --api-user / --api-key pin them.

npx mockingbird-caretalk serve --port 8823 --api-user "$CARETALK_USERNAME:$CARETALK_PASSWORD" --api-key "$CARETALK_API_KEY"
import { createServer } from "@crvouga/mockingbird-service-caretalk/server"

// Test setup: the emulator. The application gets CARETALK_API_URL = server.url.
const server = await createServer()
const baseUrl = server.url

// Application code: log in, then read a form with the token.
const login = await fetch(`${baseUrl}/externalapi/Auth/client-login`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  // Any credentials log in unless --api-user pins them.
  body: JSON.stringify({ userName: "acme-api", password: crypto.randomUUID() }),
})
const { token } = (await login.json()) as { token: string }
const forms = await fetch(`${baseUrl}/externalapi/Forms/GetForm/health-history`, {
  headers: { authorization: `Bearer ${token}` },
})
const [form] = (await forms.json()) as { fullFormDto: { id: number } }[]

// Test control: after the app's form-submission queue runs, assert what reached CareTalk.
const saved = await fetch(`${baseUrl}/__admin/form-submissions`)
const { submissions } = (await saved.json()) as { submissions: unknown[] }
await server.close()

Routes

RouteBehaviour
POST /externalapi/Auth/client-login{userName, password} → {token, expiration}. Tokens last tokenTtlSeconds (default 3600, what our client caches for) on the emulator clock.
GET /externalapi/Forms/GetForm/{formName}By name or slug, case-insensitive: [{formRoundId, patientAppointmentId, submitDate, fullFormDto}]; an unknown form is []. With PatientId (and AppointmentId), the patient's latest saved round: chosen answers isChecked, free text echoed. Accepts a login token or a static API key.
POST /externalapi/Forms/SavePatientForm?patientId=&patientAppointmentId=The submission (fullFormDto.groups[].groupQuestions[]). Question ids must belong to the form, answer ids to the question (text questions take id: 0 with the typed value), single-choice questions one answer; violations are 400 ProblemDetails, an unknown patient or form 404. → {success: true, message}.
GET /externalapi/Patients/SearchForPatient?FirstName&LastName&zipCode&DateOfBirthCase-insensitive names, ZIP, and the date in any of YYYY-MM-DD, MM/DD/YYYY, ISO → {isExists: true, eligibleId, programId}; no match is 400 {isExists: false, message} (our client reads 400 as "no such patient").
GET /externalapi/States51 states {id, stateUid, name, abbreviation, …} (UT is 45).
POST /externalapi/PatientsCreates a patient and echoes CareTalk's full record (id, eligibilityId = id, userState, formattedUserMobile, clientId, …).
GET /externalapi/PatientAppointments/GetFreeSlots?date&programId&eligibleIdHalf-hour slots 09:00–16:30 for two physicians, minus booked ones.
POST /externalapi/PatientAppointments{doctorId, patientId (the eligible id), from, to} → {id, patientId: null, eligibilityId, appointmentStatus: 1, physicianId}; a taken or unknown slot is 400.
GET /externalapi/PatientAppointments/GetPatientAppointmentsByEligibleId/{id}That patient's appointments.

Unauthenticated or expired calls are an empty 401 with WWW-Authenticate: Bearer (our client logs in again once and retries). Validation errors are ASP.NET ProblemDetails {type, title, status, errors, traceId}.

Admin (beyond the standard contract)

RouteEffect
GET /__admin/form-submissions[?patientId=]Saved rounds: {formRoundId, formId, patientId, patientAppointmentId, submitDate, answers: [{questionId, answerIds, freeAnswerText}]}.
GET / POST /__admin/patientsList patients, or create one directly (the Patients POST body) so a search finds it.
GET /__admin/forms, PUT /__admin/forms/:idList or add/replace a form definition (fullFormDto shape).
POST /__admin/appointments/:id/status{appointmentStatus}: change an appointment's status code.
GET/PUT /__admin/settings{tokenTtlSeconds?, users?: [{userName, password}], apiKeys?, programId?}.

Fault presets (POST /__admin/faults {"preset": "<name>", "count"?: n}): login_failure, invalid_credentials, token_expired (count applies per operation), server_error, gateway_html, form_not_found, patient_not_found, save_rejected, connection_drop, slow.

Namespaces

x-mockingbird-namespace, a /__admin/ns/<name> prefix on CARETALK_API_URL, or by credential: tokens carry the API user they were issued to, so PUT /__admin/credentials {"credentials": {"<CARETALK_USERNAME>": "<ns>", "<CARETALK_API_KEY>": "<ns>"}} routes both auth styles.

Deliberately not modelled

  • CareTalk's clinical workflows behind the forms (reviews, form rounds created by staff), eligibility files, Health Gorilla retrieval, medications and diagnostics.
  • Real physician calendars: slots are synthesised; time zones are fixed to Mountain.
  • The live form catalogue: DEFAULT_FORMS is synthesised in CareTalk's shape (the live-parity script seeds the emulator from the beta environment's forms instead).

API

ExportKindDescription
CareTalkAPIclassThe in-process emulator: fetch(request), reset(), addPatient(body), slots(date), setAppointmentStatus(id, status), upsertForm(form), rounds(), patients(). Options: sqlite, now, namespace, forms, settings.
createRuntimefunctionThe emulator with the full service contract (health, admin, namespaces, credentials, presets). Options: forms, settings, clock, seed, adminKey, onLog, sqlite.
CARETALK_PRESETSobjectEvery named fault preset.
CARETALK_NAMESPACEstringThe service name, "caretalk".
DEFAULT_FORMSarrayThe seeded form definitions (Health History 101, AOE Questions 102).
DEFAULT_DOCTORSarrayThe physicians free slots are generated for.
US_STATESarrayThe /externalapi/States rows.
tokenCredentialfunctionThe API user a token was issued to, or the static key (how credentials map to namespaces).
normalizeDatefunctionYYYY-MM-DD from ISO, YYYY-MM-DD or MM/DD/YYYY.
problemfunctionBuild an ASP.NET ProblemDetails response.
document, operationIds, supportedOperationIdsvaluesThe OpenAPI contract and its operation ids.
createServer, serveTarget, DEFAULT_PORT (./server)NodeServe over node:http; the serve CLI target (--api-user, --api-key); port 8823.

Part of mockingbird.

版本与发布记录

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

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

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

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

Stateful emulator of CareTalk's external API: client-login tokens, GetForm definitions, SavePatientForm rounds, patient search/insert, states, free slots and appointments.

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

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

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

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

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

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

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

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

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

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

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

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