@crvouga/mockingbird-service-junction 2.3.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog — @crvouga/mockingbird-service-junction
2
2
 
3
+ ## 3.1.0 (2026-10-08)
4
+
5
+ ### Features
6
+
7
+ - redesign emulator experience ([d6038c2](https://github.com/crvouga/mockingbird/commit/d6038c27eebbaa1751f02bc9305002a5b1304779))
8
+
9
+ ### Dependencies
10
+
11
+ - `@crvouga/mockingbird-service-sqlite`
12
+
13
+ ## 3.0.0 (2026-10-07)
14
+
15
+ ### ⚠️ Breaking changes
16
+
17
+ - point the repo at crvouga/mockingbird ([1bf35a4](https://github.com/crvouga/mockingbird/commit/1bf35a422b84a85b50b09b72bd7cc7093082a86e))
18
+ - point the repo at crvouga/emulates ([cdb5e53](https://github.com/crvouga/mockingbird/commit/cdb5e536ed8c1f52345e3984f089001c25fdb08a))
19
+ - rename Emulators to Emulates ([2e10d9c](https://github.com/crvouga/mockingbird/commit/2e10d9cff84c54ac37768fc9a19d1aefd3943744))
20
+ - rebrand Mockingbird to Emulators ([1adca65](https://github.com/crvouga/mockingbird/commit/1adca65ce28242f11cff98eac05d2be88f680cbe))
21
+
22
+ ### Fixes and improvements
23
+
24
+ - typecheck the brand gate before builds ([fc36095](https://github.com/crvouga/mockingbird/commit/fc3609514de70ffe3170a5d216fb8a49f9ce7cbb))
25
+ - format the emulates records query ([8698872](https://github.com/crvouga/mockingbird/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
26
+ - preserve JSON prototype keys ([fba8e4d](https://github.com/crvouga/mockingbird/commit/fba8e4d2e4219d825f1ca705cabc44b5dbbb8f02))
27
+
3
28
  ## 2.3.1 (2026-10-05)
4
29
 
5
30
  ### Fixes and improvements
package/DISCOVERY.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @crvouga/mockingbird-service-junction discovery
2
2
 
3
3
  This is the installed-package index for coding agents and tooling. All relative links resolve
4
- inside `node_modules/@crvouga/mockingbird-service-junction/`; no repository checkout is needed to discover the mock's
4
+ inside `node_modules/@crvouga/mockingbird-service-junction/`; no repository checkout is needed to discover the emulator's
5
5
  supported surface or documented behavior.
6
6
 
7
7
  ## Capability and behavior sources
@@ -48,7 +48,7 @@ designed for assertions and diagnosis by consuming test suites.
48
48
  ## Report a mismatch or missing capability
49
49
 
50
50
  Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
51
- operation/command, a minimal redacted request, actual mock result, expected oracle result or vendor
51
+ operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
52
52
  documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
53
53
  customer data, prompts, PHI, card data, or unredacted recordings.
54
54
 
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @crvouga/mockingbird-service-junction
2
2
 
3
- > Familiar calls. Faithful echoes. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
3
+ > Local emulators. Real API contracts. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
4
4
 
5
- Stateful mock of the [Junction (formerly Vital) API](https://docs.junction.com/): users
5
+ Stateful emulator of the [Junction (formerly Vital) API](https://docs.junction.com/): users
6
6
  (`/v2/user`), the lab-testing catalog, lab orders (create, cancel, simulate, results,
7
7
  requisitions), at-home phlebotomy and patient-service-center (PSC) scheduling, and the
8
8
  `labtest.order.*` / `labtest.appointment.updated` webhooks. All 40 operations in the vendored
@@ -10,7 +10,7 @@ OpenAPI subset are served, and behaviour is checked by differential property tes
10
10
  Junction sandbox.
11
11
 
12
12
  Use it to take Junction off your suite's critical path: no sandbox key, no shared 50-user sandbox
13
- cap (the mock enforces no sandbox limit unless a test [asks for one](#sandbox-limits)), no
13
+ cap (the emulator enforces no sandbox limit unless a test [asks for one](#sandbox-limits)), no
14
14
  cross-suite interference. Serve it as a local origin with one command, or run it in-process.
15
15
 
16
16
  ```bash
@@ -18,10 +18,10 @@ npx mockingbird-junction serve # http://127.0.0.1:8787, recorded sandbox corpu
18
18
  ```
19
19
 
20
20
  - Operation coverage: [SUPPORT.md](https://github.com/crvouga/mockingbird/blob/main/packages/service/junction/SUPPORT.md)
21
- - Drop-in readiness and the sandbox quirks the mock mirrors:
21
+ - Drop-in readiness and the sandbox quirks the emulator mirrors:
22
22
  [docs/drop-in.md](https://github.com/crvouga/mockingbird/blob/main/packages/service/junction/docs/drop-in.md)
23
23
  - Behaviour notes: [docs/behavior.md](https://github.com/crvouga/mockingbird/blob/main/packages/service/junction/docs/behavior.md)
24
- - **What the mock does not model:** [below](#what-is-and-is-not-modelled). Read it before trusting a
24
+ - **What the emulator does not model:** [below](#what-is-and-is-not-modelled). Read it before trusting a
25
25
  green suite.
26
26
 
27
27
  ## Install
@@ -37,7 +37,7 @@ native dependencies: state lives in an in-memory SQLite engine written in TypeSc
37
37
  | --- | --- | --- |
38
38
  | `@crvouga/mockingbird-service-junction` | any (Node, Bun, Workers, browsers) | `JunctionAPI`, `createRuntime`, corpus and verify tools |
39
39
  | `@crvouga/mockingbird-service-junction/server` | Node | `createServer()` — a listening HTTP server |
40
- | `@crvouga/mockingbird-service-junction/corpus` | any | `defaultCorpus` — the recording shipped in the package (a separate entry, so importing the mock never parses it) |
40
+ | `@crvouga/mockingbird-service-junction/corpus` | any | `defaultCorpus` — the recording shipped in the package (a separate entry, so importing the emulator never parses it) |
41
41
  | `mockingbird-junction` (bin) | Node | `serve`, `corpus pull`, `corpus diff`, `verify` |
42
42
 
43
43
  ## Usage
@@ -58,12 +58,12 @@ npx mockingbird-junction serve --help
58
58
  | `--corpus <default\|none\|file>` | `default` | The shipped corpus, no corpus (synthetic data), or a file from `corpus pull` |
59
59
  | `--geo <corpus\|synthetic>` | `corpus` with a corpus | How unknown ZIPs are answered; see [Geo](#geo-corpus-or-synthetic) |
60
60
  | `--lab-accounts <file>` | built-in fixtures | [Lab accounts](#lab-accounts): a JSON array, or `{ "presets": [...], "accounts": [...] }` |
61
- | `--team-id <uuid>` | the corpus's team | The [team](#team-identity) the mock answers as |
61
+ | `--team-id <uuid>` | the corpus's team | The [team](#team-identity) the emulator answers as |
62
62
  | `--max-users <n>` | unlimited | Enforce the sandbox's [live-user cap](#sandbox-limits) |
63
63
  | `--identity <strict\|adopt-users>` | `strict` | Unknown `user_id`s: 404, or [create on first use](#fixtures-and-identity) |
64
64
  | `--default-billing-type <lab=type,…>` | `client_bill` | The `billing_type` an order for that lab gets when it omits one ([billing](#default-billing-type)) |
65
65
  | `--fixtures <file>` | — | [Users and orders](#fixtures-and-identity) every namespace starts with |
66
- | `--journal-size <n>` | `1000` | Requests each namespace's [journal](#is-this-the-mock) keeps |
66
+ | `--journal-size <n>` | `1000` | Requests each namespace's [journal](#is-this-the-emulator) keeps |
67
67
  | `--webhook-url <url>` / `--webhook-secret <whsec_…>` | off | Deliver [signed webhooks](#webhooks) (secret also from `MOCKINGBIRD_JUNCTION_WEBHOOK_SECRET`) |
68
68
  | `--webhook-retry-delays <ms,…>` | Svix's schedule | Delay before each delivery attempt, e.g. `0,1000,5000` in tests |
69
69
  | `--webhook-scope <scope>` | — | Sent as `x-mockingbird-scope` on every delivery |
@@ -124,7 +124,7 @@ or a loaded corpus). The result has `url`, `port`, `runtime` and `close()`.
124
124
 
125
125
  ### `createRuntime` (any Fetch server)
126
126
 
127
- `createRuntime` is the whole served mock — health, admin, namespaces, clock, faults, metrics — as a
127
+ `createRuntime` is the whole served emulator — health, admin, namespaces, clock, faults, metrics — as a
128
128
  single runtime-neutral `fetch(request)`. Hand it to `Bun.serve`, a Worker, or call it directly:
129
129
 
130
130
  ```ts
@@ -199,7 +199,7 @@ const order = await call("POST", "/v3/order", {
199
199
  })
200
200
  console.log(order.status, (order.json.order as { id: string }).id) // 200 "<uuid>"
201
201
 
202
- // Every event the mock published, oldest first:
202
+ // Every event the emulator published, oldest first:
203
203
  console.log(junction.webhookEvents().map((event) => event.event_type)) // ["labtest.order.created"]
204
204
  ```
205
205
 
@@ -239,8 +239,8 @@ Every Mockingbird service answers the same control surface, outside the vendor's
239
239
  through the admin API (lab accounts, limits, identity, geo) belongs to one namespace and survives
240
240
  that namespace's `POST /__admin/reset`; data does not.
241
241
  - `x-mockingbird: junction@<version>; ns=<namespace>` — on **every** response: vendor answers,
242
- errors, faults, admin and health. Junction never sends it, so it tells the mock from the vendor
243
- (see [Is this the mock?](#is-this-the-mock)).
242
+ errors, faults, admin and health. Junction never sends it, so it tells the emulator from the vendor
243
+ (see [Is this the emulator?](#is-this-the-emulator)).
244
244
 
245
245
  | Route | Does |
246
246
  | --- | --- |
@@ -270,7 +270,7 @@ Every Mockingbird service answers the same control surface, outside the vendor's
270
270
  | `DELETE /__admin/users/{id}` | Remove a user outright, leaving no deletion tombstone |
271
271
  | `POST /__admin/orders` | Insert an order, optionally already in a `status`, through `create_order`'s record builder |
272
272
  | `POST /__admin/import` | `{ "users": [...], "orders": [...] }` in one call |
273
- | `GET` / `DELETE /__admin/requests` | The namespace's [request journal](#is-this-the-mock) (`?operationId=`, `?status=`, `?since=`, `?limit=`, `?all=1`) / clear it |
273
+ | `GET` / `DELETE /__admin/requests` | The namespace's [request journal](#is-this-the-emulator) (`?operationId=`, `?status=`, `?since=`, `?limit=`, `?all=1`) / clear it |
274
274
  | `GET /__admin/corpus`, `PUT /__admin/geo` | The loaded corpus; switch [geo mode](#geo-corpus-or-synthetic) |
275
275
  | `GET /__admin/webhooks` | [Deliveries](#webhooks) with every attempt |
276
276
  | `POST /__admin/webhooks/{id}/replay`, `POST /__admin/webhooks/flush` | Redeliver one message; run pending retries now |
@@ -283,7 +283,7 @@ a new SDK call shows up — as a count — before it fails a suite as a 404.
283
283
 
284
284
  Provider-owned inventory — area serviceability, PSC site lists, the lab catalog, labs, lab
285
285
  accounts — cannot be synthesized faithfully. A corpus is an exact recording of those
286
- parameter-stable reads, and the mock answers them byte for byte.
286
+ parameter-stable reads, and the emulator answers them byte for byte.
287
287
 
288
288
  **The shipped corpus** (`defaultCorpus`, and what `serve` loads unless told otherwise) was recorded
289
289
  from the Junction sandbox. It covers area and PSC serviceability for 57 ZIPs across the US, the PSC
@@ -344,7 +344,7 @@ one active account for the lab is selected, several select the first listed, and
344
344
  falls back to Junction's platform account. The billing type must be allowed in the patient's
345
345
  state by the account's `allowed_billing`.
346
346
 
347
- Two of Junction's documented rules are **not** enforced by the sandbox, so the mock does not
347
+ Two of Junction's documented rules are **not** enforced by the sandbox, so the emulator does not
348
348
  enforce them either. An id naming another lab's account is accepted and the order is placed with
349
349
  that account (the guide says it must be "associated with the lab selected for the order"):
350
350
  recorded in `corpus/lab-account-probes.json`, where a Labcorp test ordered through Junction's
@@ -354,9 +354,9 @@ accounts are linked for the lab places the order (the guide says it "may be reje
354
354
  live by a consumer's team ([#136](https://github.com/crvouga/mockingbird/issues/136)); the
355
355
  sandbox team the parity run uses has one account per lab, so `verify --orders` checks it whenever
356
356
  a corpus has such a lab. Which of the several accounts the sandbox bills through is not visible
357
- from outside; the mock uses the first listed.
357
+ from outside; the emulator uses the first listed.
358
358
 
359
- Junction's order (`ClientFacingOrder`) has no `lab_account_id`, so neither does the mock's: not on
359
+ Junction's order (`ClientFacingOrder`) has no `lab_account_id`, so neither does the emulator's: not on
360
360
  the create response, `GET /v3/order/{id}`, `GET /v3/orders` or webhooks. The account an order was
361
361
  placed with is reported only by `GET /__admin/orders` and `instance().orderLabAccount(orderId)`.
362
362
 
@@ -455,7 +455,7 @@ works and keeps its own default id (`presetAccountId("bioreference_customer_mult
455
455
 
456
456
  ### Team identity
457
457
 
458
- The mock answers as one team: `team_id` on users, orders and webhooks, and the team that
458
+ The emulator answers as one team: `team_id` on users, orders and webhooks, and the team that
459
459
  `team_id_allowlist` is checked against. It is, in order: `teamId` / `--team-id`, the team a
460
460
  version-2 corpus recorded (`corpus pull` reads it from a listed user, else from the accounts'
461
461
  allowlists), else the fixed `MOCK_TEAM_ID`. `GET /__admin/team` reports it.
@@ -463,18 +463,18 @@ allowlists), else the fixed `MOCK_TEAM_ID`. `GET /__admin/team` reports it.
463
463
  A version-2 corpus keeps each account's allowlist **verbatim**, so an account the real team is not
464
464
  linked to answers `400 {"detail": "Lab account is not linked to your team"}` exactly as it does
465
465
  live. A version-1 corpus (no `teamId`) still loads and behaves as 0.2.0 did: every recorded account
466
- is also linked to the mock team.
466
+ is also linked to the emulator team.
467
467
 
468
468
  **Empty allowlists.** Junction's own Quest, Labcorp and BioReference accounts carry
469
- `team_id_allowlist: []`, and a real team's listing returns them, so the mock lists them and treats
469
+ `team_id_allowlist: []`, and a real team's listing returns them, so the emulator lists them and treats
470
470
  them as linked. Ordering through one by explicit id, and with the id omitted when it is the lab's
471
471
  only active account, places the order on the sandbox (`corpus/lab-account-probes.json`, recorded
472
- by the parity run), as the mock does. `verify --orders` re-checks it whenever the corpus has such
472
+ by the parity run), as the emulator does. `verify --orders` re-checks it whenever the corpus has such
473
473
  an account.
474
474
 
475
475
  ## Sandbox limits
476
476
 
477
- The mock exists to escape the sandbox's restrictions, so it enforces none of them unless a test
477
+ The emulator exists to escape the sandbox's restrictions, so it enforces none of them unless a test
478
478
  asks — this is a tested guarantee (500 users in a loop all succeed), not an accident.
479
479
 
480
480
  | Sandbox limit | Modelled | Default | Turn it on |
@@ -508,7 +508,7 @@ curl -X POST localhost:8787/__admin/import -d @test/junction-fixtures.json
508
508
  user and lab test must exist (404 otherwise).
509
509
  - Inserted records go through the same builders as `create_user` / `create_order`, so every read
510
510
  path (`GET /v2/user/{id}`, resolve by `client_user_id`, `GET /v3/order/{id}`,
511
- `GET /v3/orders?user_id=`) sees them as API-created. Default timestamps read the mock clock.
511
+ `GET /v3/orders?user_id=`) sees them as API-created. Default timestamps read the emulator clock.
512
512
  - **No webhook fires** unless the body has `"emitWebhooks": true`: fixtures should not trigger
513
513
  backend side effects.
514
514
  - `fixtures` / `--fixtures <file>` loads `{ "users": [...], "orders": [...] }` into every namespace
@@ -521,9 +521,9 @@ and the request proceeds. The journal marks the request `adopted: true`. **Order
521
521
  adopted**: an unknown order id always 404s, because inventing an order hides real bugs. The default,
522
522
  `strict`, is Junction's own behaviour.
523
523
 
524
- ## Is this the mock?
524
+ ## Is this the emulator?
525
525
 
526
- A mock 404 and a sandbox 404 are byte-identical, which is how a backend half-pointed at the sandbox
526
+ An emulator 404 and a sandbox 404 are byte-identical, which is how a backend half-pointed at the sandbox
527
527
  goes unnoticed. Three things make it visible:
528
528
 
529
529
  - **`x-mockingbird` on every response.** Assert on it in a test helper:
@@ -531,12 +531,12 @@ goes unnoticed. Three things make it visible:
531
531
  ```ts
532
532
  import { expect } from "vitest"
533
533
 
534
- /** Wrap the fetch your Junction client uses; fails any call that did not reach the mock. */
534
+ /** Wrap the fetch your Junction client uses; fails any call that did not reach the emulator. */
535
535
  export const mockOnlyFetch =
536
536
  (inner: typeof fetch = fetch): typeof fetch =>
537
537
  async (input, init) => {
538
538
  const response = await inner(input, init)
539
- expect(response.headers.get("x-mockingbird"), `${String(input)} did not reach the Junction mock`).toMatch(
539
+ expect(response.headers.get("x-mockingbird"), `${String(input)} did not reach the Junction emulator`).toMatch(
540
540
  /^junction@/,
541
541
  )
542
542
  return response
@@ -545,7 +545,7 @@ goes unnoticed. Three things make it visible:
545
545
 
546
546
  - **The request journal.** Each namespace keeps its last 1000 requests (`--journal-size`,
547
547
  `journalSize`): operation id, method, path, status, duration, fault id, the user / order /
548
- lab-account ids it touched, and when (mock clock). `GET /__admin/requests?operationId=create_order_v3_order_post`
548
+ lab-account ids it touched, and when (emulator clock). `GET /__admin/requests?operationId=create_order_v3_order_post`
549
549
  proves an order was placed here; an empty answer proves it was not. Never bodies.
550
550
  - **Miss headers on 404s.** A missing user or order keeps Junction's body byte for byte and adds
551
551
  `x-mockingbird-miss: order <id>` (or `user <id>`, `user client:<client_user_id>`) and
@@ -592,7 +592,7 @@ delayed simulations (`?delay=<seconds>`) due and moves appointment windows, with
592
592
 
593
593
  ## Faults and error shapes
594
594
 
595
- Error bodies the mock reproduces byte for byte, checked against the sandbox by `verify` and the
595
+ Error bodies the emulator reproduces byte for byte, checked against the sandbox by `verify` and the
596
596
  parity suite (`ORDER_NOT_FOUND` holds the unknown-order text per operation id):
597
597
 
598
598
  | Case | Status | Body |
@@ -639,7 +639,7 @@ With `webhooks` / `--webhook-url`, every event is delivered signed, with retries
639
639
  official `svix` verifier, and a receiver written for real Junction, accept it unchanged. (Signing
640
640
  `"<timestamp>.<body>"` without the message id, as this package's own server script did before,
641
641
  is not Svix-compatible.)
642
- - Timestamps are wall-clock even when the mock clock is moved, because receivers reject timestamps
642
+ - Timestamps are wall-clock even when the emulator clock is moved, because receivers reject timestamps
643
643
  outside a few minutes of their own clock.
644
644
  - Any 2xx is delivered; anything else is retried on Svix's schedule (immediately, 5 s, 5 min,
645
645
  30 min, 2 h, 5 h, 10 h, 10 h) or `retryDelaysMs`. `POST /__admin/webhooks/flush` runs pending
@@ -669,7 +669,7 @@ console.log(typeof accept, junction.webhooks?.deliveries().length) // "function"
669
669
 
670
670
  ## Verify
671
671
 
672
- `verify` is the fidelity guarantee: it runs the same requests against real Junction and the mock
672
+ `verify` is the fidelity guarantee: it runs the same requests against real Junction and the emulator
673
673
  and reports every divergence.
674
674
 
675
675
  ```bash
@@ -687,7 +687,7 @@ npx mockingbird-junction verify --real-key "$JUNCTION_SANDBOX_KEY" --orders --sa
687
687
  bodies must match in shape, and byte for byte for the documented error bodies.
688
688
 
689
689
  It exits 1 on any divergence. The scenario always deletes its user (and cancels its order), because
690
- it runs against the same capped sandbox the mock exists to relieve. `verifyAgainstReal` is the same
690
+ it runs against the same capped sandbox the emulator exists to relieve. `verifyAgainstReal` is the same
691
691
  check as a function. This repo runs it in CI against the Junction sandbox.
692
692
 
693
693
  ## Determinism
@@ -700,7 +700,7 @@ availability, and which requests a partial-`rate` fault hits. Wall-clock by desi
700
700
 
701
701
  ## What is and is not modelled
702
702
 
703
- A mock that is silent about its gaps is how a green suite starts lying. Specifically:
703
+ An emulator that is silent about its gaps is how a green suite starts lying. Specifically:
704
704
 
705
705
  - **Corpus-backed** (byte-exact): area and PSC serviceability for covered ZIPs; the catalog, labs,
706
706
  expected results and lab accounts of the team the corpus was recorded from.
@@ -714,11 +714,11 @@ A mock that is silent about its gaps is how a green suite starts lying. Specific
714
714
  - Rate limits and outages, except when injected as faults or switched on as
715
715
  [limits](#sandbox-limits).
716
716
  - Which of several active accounts for a lab the sandbox bills an order through when
717
- `lab_account_id` is omitted (see [Lab accounts](#lab-accounts)); the mock uses the first listed.
717
+ `lab_account_id` is omitted (see [Lab accounts](#lab-accounts)); the emulator uses the first listed.
718
718
  - Adopted users (`adopt-users`) have `client_user_id` equal to their `user_id`; nothing in
719
719
  Junction corresponds to adoption.
720
720
  - Real 429 / 5xx bodies: the presets are plausible, not recorded.
721
- - Phlebotomy availability breadth: the sandbox serves it only for `85004`; the mock generates slots
721
+ - Phlebotomy availability breadth: the sandbox serves it only for `85004`; the emulator generates slots
722
722
  for any covered ZIP.
723
723
  - Webhook retry jitter across a snapshot restore (the jitter stream is not part of a snapshot).
724
724
  - Operations outside the vendored OpenAPI subset: they return 404 and are counted as
@@ -730,12 +730,12 @@ Main entry (`@crvouga/mockingbird-service-junction`, runtime-neutral):
730
730
 
731
731
  | Export | Description |
732
732
  | --- | --- |
733
- | `createRuntime` | `(options?: JunctionRuntimeOptions) => JunctionRuntime` — the served mock (health, admin, namespaces, clock, faults, metrics, journal, webhooks) as one `fetch`. Options: `corpus`, `geo`, `labAccounts`, `teamId`, `limits`, `identity`, `defaultBillingTypes`, `fixtures`, `journalSize`, `webhooks`, `onWebhook`, `sqlite`, `clock`, `seed`, `adminKey`, `onLog`. |
734
- | `JunctionAPI` | Class. `new JunctionAPI(options?)`: one namespace's mock, implementing `fetch(request: Request): Promise<Response>`. |
733
+ | `createRuntime` | `(options?: JunctionRuntimeOptions) => JunctionRuntime` — the served emulator (health, admin, namespaces, clock, faults, metrics, journal, webhooks) as one `fetch`. Options: `corpus`, `geo`, `labAccounts`, `teamId`, `limits`, `identity`, `defaultBillingTypes`, `fixtures`, `journalSize`, `webhooks`, `onWebhook`, `sqlite`, `clock`, `seed`, `adminKey`, `onLog`. |
734
+ | `JunctionAPI` | Class. `new JunctionAPI(options?)`: one namespace's emulator, implementing `fetch(request: Request): Promise<Response>`. |
735
735
  | `JUNCTION_NAMESPACE` | `"junction"` — the default namespace's storage key when sharing a `sqlite` client. |
736
736
  | `document` | The vendored Junction OpenAPI document (Mockingbird subset) that drives routing. |
737
737
  | `operationIds` | Every `operationId` in `document`. |
738
- | `supportedOperationIds` | The `operationId`s the mock implements (all of them). |
738
+ | `supportedOperationIds` | The `operationId`s the emulator implements (all of them). |
739
739
  | `pullCorpus` | `(options: PullCorpusOptions) => Promise<SealedCorpus>` — record a corpus from a real team (GETs only). |
740
740
  | `diffCorpus` | `(before, after) => CorpusDiff` — ZIPs, lab tests, lab accounts and observations added / removed / changed. |
741
741
  | `fingerprintCorpus` | `(corpus) => Promise<string>` — SHA-256 of a corpus's content. |
@@ -744,7 +744,7 @@ Main entry (`@crvouga/mockingbird-service-junction`, runtime-neutral):
744
744
  | `SEALED_CORPUS_VERSION` | Current corpus format version (`2`: adds `teamId`). |
745
745
  | `SUPPORTED_SEALED_CORPUS_VERSIONS` | Versions `parseSealedCorpus` loads (`[1, 2]`). |
746
746
  | `MOCK_TEAM_ID` | The team id used when neither `teamId` nor the corpus gives one. |
747
- | `OTHER_TEAM_ID` | A team that is not the mock's, for fixtures modelling another team's account. |
747
+ | `OTHER_TEAM_ID` | A team that is not the emulator's, for fixtures modelling another team's account. |
748
748
  | `isLinkedToTeam` | `(account, teamId) => boolean` — the allowlist rule (`[]` counts as linked). |
749
749
  | `LAB_ACCOUNT_PRESETS` | The [lab-account presets](#lab-account-presets), without ids. |
750
750
  | `LAB_ACCOUNT_PRESET_ALIASES` | Deprecated preset names → the preset each stands for (`bioreference_customer_multi_state` → `bioreference_platform`). |
@@ -875,9 +875,9 @@ For contributors to the mockingbird repo only.
875
875
  ```bash
876
876
  bun test # offline suites, incl. scheduling state space
877
877
  bun test junction.runtime.property.test.ts # service contract, corpus, lab accounts, faults, webhooks, verify
878
- bun test junction.sdk.property.test.ts # drives the served mock through @tryvital/vital-node
878
+ bun test junction.sdk.property.test.ts # drives the served emulator through @tryvital/vital-node
879
879
 
880
- bun run mock:serve # env-configured `serve`: HOST, PORT, MOCKINGBIRD_JUNCTION_CORPUS,
880
+ bun run emulator:serve # env-configured `serve`: HOST, PORT, MOCKINGBIRD_JUNCTION_CORPUS,
881
881
  # MOCKINGBIRD_JUNCTION_WEBHOOK_URL / _SECRET / _SCOPE
882
882
  bun run corpus:record -- --force # re-record the shipped corpus/sandbox-sealed.json (JUNCTION_API_KEY)
883
883
  bun run verify -- --real-key "$KEY" # `mockingbird-junction verify` from source
@@ -898,7 +898,7 @@ Webhook parity needs a public receiver; see
898
898
 
899
899
  A completion-target simulation on an active testkit advances through delivery and queues
900
900
  completion for the next millisecond of the injected `now` clock. This is a deterministic
901
- mock scheduling boundary, not a claim about Junction's processing latency. Order, result,
901
+ emulator scheduling boundary, not a claim about Junction's processing latency. Order, result,
902
902
  transaction, and order-list reads apply due work to its owning order. A second simulation
903
903
  is not required. Results remain unavailable while the testkit is `delivered_to_lab`.
904
904
  Cancelled orders never complete from queued simulation work.
package/SUPPORT.md CHANGED
@@ -3,10 +3,10 @@
3
3
  Generated from `openapi.yaml`; do not edit by hand.
4
4
 
5
5
  - operations in spec: **40**
6
- - supported by the mock: **40**
6
+ - supported by the emulator: **40**
7
7
  - parity enabled: **22**
8
8
 
9
- | operationId | route | mock | parity | notes |
9
+ | operationId | route | emulator | parity | notes |
10
10
  | --- | --- | --- | --- | --- |
11
11
  | `get_teams_users_v2_user_get` | `GET /v2/user` | ✅ supported | ✅ | |
12
12
  | `create_user_v2_user_post` | `POST /v2/user` | ✅ supported | ✅ | |
@@ -17,31 +17,31 @@ Generated from `openapi.yaml`; do not edit by hand.
17
17
  | `patch_user_info_v2_user__user_id__info_patch` | `PATCH /v2/user/{user_id}/info` | ✅ supported | ✅ | |
18
18
  | `get_latest_user_info_user_v2_user__user_id__info_latest_get` | `GET /v2/user/{user_id}/info/latest` | ✅ supported | ✅ | |
19
19
  | `get_paginated_lab_tests_for_team_v3_lab_test_get` | `GET /v3/lab_test` | ✅ supported | ✅ | |
20
- | `get_team_lab_accounts_v3_lab_test_lab_account_get` | `GET /v3/lab_test/lab_account` | ✅ supported | ❌ disabled | lab-account inventory is fixture-owned; the mock models the documented shape, filters and routing rules, not a live account inventory |
20
+ | `get_team_lab_accounts_v3_lab_test_lab_account_get` | `GET /v3/lab_test/lab_account` | ✅ supported | ❌ disabled | lab-account inventory is fixture-owned; the emulator models the documented shape, filters and routing rules, not a live account inventory |
21
21
  | `get_lab_tests_for_team_v3_lab_tests_get` | `GET /v3/lab_tests` | ✅ supported | ✅ | |
22
22
  | `get_lab_test_for_team_v3_lab_tests__lab_test_id__get` | `GET /v3/lab_tests/{lab_test_id}` | ✅ supported | ✅ | |
23
23
  | `get_labs_v3_lab_tests_labs_get` | `GET /v3/lab_tests/labs` | ✅ supported | ✅ | |
24
24
  | `get_markers_for_lab_test_v3_lab_tests__lab_test_id__markers_get` | `GET /v3/lab_tests/{lab_test_id}/markers` | ✅ supported | ✅ | |
25
25
  | `list_order_set_markers_v3_lab_tests_list_order_set_markers_post` | `POST /v3/lab_tests/list_order_set_markers` | ✅ supported | ✅ | |
26
26
  | `create_order_v3_order_post` | `POST /v3/order` | ✅ supported | ✅ | |
27
- | `get_area_info_v3_order_area_info_get` | `GET /v3/order/area/info` | ✅ supported | ❌ disabled | central_labs presence, within_radius counts and getlabs market coverage are provider-owned geo data that a mock cannot replicate per-zip; covered by the client-parity scenario shape checks instead |
28
- | `get_psc_info_v3_order_psc_info_get` | `GET /v3/order/psc/info` | ✅ supported | ❌ disabled | patient_service_centers are real site inventories per zip (thousands of sites, result-capped at 30) that a fixture mock cannot replicate per-zip; covered by the client-parity scenario shape checks instead |
29
- | `get_phlebotomy_appointment_availability_v3_order_phlebotomy_appointment_availability_post` | `POST /v3/order/phlebotomy/appointment/availability` | ✅ supported | ❌ disabled | availability slots are provider-side data whose values shift between sandbox calls; covered by the mock-internal scheduling property suite instead |
27
+ | `get_area_info_v3_order_area_info_get` | `GET /v3/order/area/info` | ✅ supported | ❌ disabled | central_labs presence, within_radius counts and getlabs market coverage are provider-owned geo data that an emulator cannot replicate per-zip; covered by the client-parity scenario shape checks instead |
28
+ | `get_psc_info_v3_order_psc_info_get` | `GET /v3/order/psc/info` | ✅ supported | ❌ disabled | patient_service_centers are real site inventories per zip (thousands of sites, result-capped at 30) that a fixture emulator cannot replicate per-zip; covered by the client-parity scenario shape checks instead |
29
+ | `get_phlebotomy_appointment_availability_v3_order_phlebotomy_appointment_availability_post` | `POST /v3/order/phlebotomy/appointment/availability` | ✅ supported | ❌ disabled | availability slots are provider-side data whose values shift between sandbox calls; covered by the emulator-internal scheduling property suite instead |
30
30
  | `get_phlebotomy_appointment_cancellation_reason_v3_order_phlebotomy_appointment_cancellation_reasons_get` | `GET /v3/order/phlebotomy/appointment/cancellation-reasons` | ✅ supported | ✅ | |
31
- | `get_psc_appointment_availability_v3_order_psc_appointment_availability_post` | `POST /v3/order/psc/appointment/availability` | ✅ supported | ❌ disabled | availability slots are provider-side data whose values shift between sandbox calls; covered by the mock-internal scheduling property suite instead |
31
+ | `get_psc_appointment_availability_v3_order_psc_appointment_availability_post` | `POST /v3/order/psc/appointment/availability` | ✅ supported | ❌ disabled | availability slots are provider-side data whose values shift between sandbox calls; covered by the emulator-internal scheduling property suite instead |
32
32
  | `get_psc_appointment_cancellation_reason_v3_order_psc_appointment_cancellation_reasons_get` | `GET /v3/order/psc/appointment/cancellation-reasons` | ✅ supported | ✅ | |
33
- | `get_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_get` | `GET /v3/order/{order_id}/phlebotomy/appointment` | ✅ supported | ❌ disabled | appointment payloads embed provider-side slot data; covered by the mock-internal scheduling property suite instead |
34
- | `book_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_book_post` | `POST /v3/order/{order_id}/phlebotomy/appointment/book` | ✅ supported | ❌ disabled | booking depends on live provider slot state; covered by the mock-internal scheduling property suite instead |
35
- | `reschedule_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_reschedule_patch` | `PATCH /v3/order/{order_id}/phlebotomy/appointment/reschedule` | ✅ supported | ❌ disabled | rescheduling depends on live provider slot state; covered by the mock-internal scheduling property suite instead |
36
- | `cancel_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_cancel_patch` | `PATCH /v3/order/{order_id}/phlebotomy/appointment/cancel` | ✅ supported | ❌ disabled | cancellation depends on live provider appointment state; covered by the mock-internal scheduling property suite instead |
37
- | `get_psc_appointment_v3_order__order_id__psc_appointment_get` | `GET /v3/order/{order_id}/psc/appointment` | ✅ supported | ❌ disabled | appointment payloads embed provider-side slot data; covered by the mock-internal scheduling property suite instead |
38
- | `book_psc_appointment_v3_order__order_id__psc_appointment_book_post` | `POST /v3/order/{order_id}/psc/appointment/book` | ✅ supported | ❌ disabled | booking depends on live provider slot state; covered by the mock-internal scheduling property suite instead |
39
- | `reschedule_psc_appointment_v3_order__order_id__psc_appointment_reschedule_patch` | `PATCH /v3/order/{order_id}/psc/appointment/reschedule` | ✅ supported | ❌ disabled | rescheduling depends on live provider slot state; covered by the mock-internal scheduling property suite instead |
40
- | `cancel_psc_appointment_v3_order__order_id__psc_appointment_cancel_patch` | `PATCH /v3/order/{order_id}/psc/appointment/cancel` | ✅ supported | ❌ disabled | cancellation depends on live provider appointment state; covered by the mock-internal scheduling property suite instead |
33
+ | `get_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_get` | `GET /v3/order/{order_id}/phlebotomy/appointment` | ✅ supported | ❌ disabled | appointment payloads embed provider-side slot data; covered by the emulator-internal scheduling property suite instead |
34
+ | `book_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_book_post` | `POST /v3/order/{order_id}/phlebotomy/appointment/book` | ✅ supported | ❌ disabled | booking depends on live provider slot state; covered by the emulator-internal scheduling property suite instead |
35
+ | `reschedule_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_reschedule_patch` | `PATCH /v3/order/{order_id}/phlebotomy/appointment/reschedule` | ✅ supported | ❌ disabled | rescheduling depends on live provider slot state; covered by the emulator-internal scheduling property suite instead |
36
+ | `cancel_phlebotomy_appointment_v3_order__order_id__phlebotomy_appointment_cancel_patch` | `PATCH /v3/order/{order_id}/phlebotomy/appointment/cancel` | ✅ supported | ❌ disabled | cancellation depends on live provider appointment state; covered by the emulator-internal scheduling property suite instead |
37
+ | `get_psc_appointment_v3_order__order_id__psc_appointment_get` | `GET /v3/order/{order_id}/psc/appointment` | ✅ supported | ❌ disabled | appointment payloads embed provider-side slot data; covered by the emulator-internal scheduling property suite instead |
38
+ | `book_psc_appointment_v3_order__order_id__psc_appointment_book_post` | `POST /v3/order/{order_id}/psc/appointment/book` | ✅ supported | ❌ disabled | booking depends on live provider slot state; covered by the emulator-internal scheduling property suite instead |
39
+ | `reschedule_psc_appointment_v3_order__order_id__psc_appointment_reschedule_patch` | `PATCH /v3/order/{order_id}/psc/appointment/reschedule` | ✅ supported | ❌ disabled | rescheduling depends on live provider slot state; covered by the emulator-internal scheduling property suite instead |
40
+ | `cancel_psc_appointment_v3_order__order_id__psc_appointment_cancel_patch` | `PATCH /v3/order/{order_id}/psc/appointment/cancel` | ✅ supported | ❌ disabled | cancellation depends on live provider appointment state; covered by the emulator-internal scheduling property suite instead |
41
41
  | `get_order_v3_order__order_id__get` | `GET /v3/order/{order_id}` | ✅ supported | ✅ | |
42
42
  | `cancel_order_v3_order__order_id__cancel_post` | `POST /v3/order/{order_id}/cancel` | ✅ supported | ✅ | |
43
43
  | `simulate_order_v3_order__order_id__test_post` | `POST /v3/order/{order_id}/test` | ✅ supported | ✅ | |
44
- | `get_result_raw_v3_order__order_id__result_get` | `GET /v3/order/{order_id}/result` | ✅ supported | ❌ disabled | results carry provider-side specimen data; covered by the mock-internal results property suite instead |
44
+ | `get_result_raw_v3_order__order_id__result_get` | `GET /v3/order/{order_id}/result` | ✅ supported | ❌ disabled | results carry provider-side specimen data; covered by the emulator-internal results property suite instead |
45
45
  | `get_result_metadata_v3_order__order_id__result_metadata_get` | `GET /v3/order/{order_id}/result/metadata` | ✅ supported | ✅ | |
46
46
  | `get_result_pdf_v3_order__order_id__result_pdf_get` | `GET /v3/order/{order_id}/result/pdf` | ✅ supported | ❌ disabled | PDF bytes are provider-rendered; compared by shape (byteLength) only in the scenario script |
47
47
  | `get_order_requisition_pdf_v3_order__order_id__requisition_pdf_get` | `GET /v3/order/{order_id}/requisition/pdf` | ✅ supported | ❌ disabled | PDF bytes are provider-rendered; compared by shape (byteLength) only in the scenario script |