• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

medplum / medplum / 31221389708
92%
main: 92%

Build:
Build:
LAST BUILD BRANCH: medplum-auditevent-expungement
DEFAULT BRANCH: main
Ran 07 Aug 2026 09:53PM UTC
Jobs 1
Files 869
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

07 Aug 2026 09:47PM UTC coverage: 92.162% (+0.009%) from 92.153%
31221389708

push

github

web-flow
feat(fhircast): track each subscriber's events and confirm them (#10096)

* feat(fhircast): alias FHIRcast STU3 routes at /api/hub

Some subscribers, notably the OHIF DICOM viewer, hardcode `hub.url` to
`/api/hub`. Mount the STU3 router there as well, and allow CORS on it.

Form-encoded subscription requests already worked -- the global
`urlencoded({ extended: false })` parser keeps dotted keys literal, so
the body arrives in the same shape the validators expect. Covered by a
test rather than a code change.

Fixes #10035

Signed-off-by: Derrick Farris <derrick@medplum.com>

* feat(fhircast): track each subscriber's events and confirm them

The Hub kept no record of what a subscriber asked for: `hub.events` came
back empty in the connection confirmation, and every socket on a topic
received every event published to it.

Give each subscribe request its own endpoint and store
`{projectId, topic, events, version}` under it in Redis, leased for the
same hour as the access token. On connect the socket reads that record
and keeps the events in memory, so it can now:

- confirm with the real `hub.events` -- the four fields STU3 defines,
  plus the ones STU3 dropped for STU2 subscribers
- receive only the events it asked for, matched case-insensitively the
  way the Hub already lowercases a published event to route it;
  `heartbeat` and `syncerror` reach everyone
- be denied on its own when it unsubscribes, rather than taking down
  every other subscriber on the topic

Closes #10028
Closes #6788
Closes #10030

Signed-off-by: Derrick Farris <derrick@medplum.com>

* refactor(fhircast): address static analysis findings

Use `findLast` rather than `filter(...).pop()` to take the endpoint from
a subscription URL, and make the always-delivered event list a `Set`.

Signed-off-by: Derrick Farris <derrick@medplum.com>

* refactor(fhircast): expire the user topic with the lease constant

`getTopicForUser` hardcoded the same hour `FHIRCAST_LEASE_SECONDS` now
carries, alo... (continued)

23605 of 26734 branches covered (88.3%)

Branch coverage included in aggregate %.

100 of 102 new or added lines in 4 files covered. (98.04%)

41733 of 44161 relevant lines covered (94.5%)

11945.77 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
91.64
0.53% packages/server/src/fhircast/routes.ts
1
93.6
1.1% packages/server/src/ws/fhircast.ts
Jobs
ID Job ID Ran Files Coverage
1 31221389708.1 07 Aug 2026 09:53PM UTC 869
92.16
GitHub Action Run
Source Files on build 31221389708
  • Tree
  • List 869
  • Changed 4
  • Source Changed 4
  • Coverage Changed 4
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #31221389708
  • 0c8c3ca6 on github
  • Prev Build on gh-readonly-queue/main/pr-10128-7b72689fb36358a4633d0b4c552d84af887c3833 (#31208530932)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc