@softspark/ai-toolkit 2.7.2 → 2.7.3

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.
@@ -0,0 +1,535 @@
1
+ ---
2
+ title: "Medplum Documentation Map"
3
+ category: reference
4
+ service: ai-toolkit
5
+ tags: [medplum, fhir, healthcare, ehr, sdk, api, clinical, interoperability]
6
+ version: "1.0.0"
7
+ created: "2026-04-17"
8
+ last_updated: "2026-04-17"
9
+ description: "Comprehensive navigable index of Medplum documentation covering SDK, FHIR resources, clinical workflows, security, integrations, and terminology."
10
+ ---
11
+
12
+ # Medplum Documentation Map
13
+
14
+ ## Overview
15
+
16
+ Medplum is an open-source healthcare platform built on FHIR R4. It provides a FHIR-compliant datastore, TypeScript SDK, React component library, bot automation engine, and compliance infrastructure (HIPAA, SOC2, HITRUST).
17
+
18
+ | Item | Value |
19
+ |------|-------|
20
+ | Docs | `https://www.medplum.com/docs/` |
21
+ | API Base | `https://api.medplum.com/fhir/R4/` |
22
+ | App | `https://app.medplum.com/` |
23
+ | Storybook | `https://storybook.medplum.com/` |
24
+ | GraphiQL | `https://graphiql.medplum.com/` |
25
+
26
+ ### Key Packages
27
+
28
+ | Package | Purpose |
29
+ |---------|---------|
30
+ | `@medplum/core` | SDK client, FHIR helpers, FHIRPath, HL7 parsing |
31
+ | `@medplum/fhirtypes` | TypeScript type definitions for all FHIR R4 resources |
32
+ | `@medplum/react` | React UI components (Mantine 7+, React 18+) |
33
+ | `@medplum/mock` | MockClient for unit testing |
34
+ | `@medplum/cli` | Command-line interface for FHIR operations |
35
+
36
+ ---
37
+
38
+ ## Documentation Sections
39
+
40
+ | Section | Path | Description |
41
+ |---------|------|-------------|
42
+ | FHIR Basics | `/docs/fhir-basics` | Resources, references, search, CodeableConcepts, identifiers, ValueSets, Subscriptions |
43
+ | FHIR Datastore | `/docs/fhir-datastore` | CRUD, binary data, batch requests, profiles, history, deduplication, USCDI |
44
+ | Search | `/docs/search` | Basic search, advanced parameters, `_filter`, pagination, `_include`/`_revinclude`, chaining |
45
+ | Terminology | `/docs/terminology` | CodeSystem, ValueSet, ConceptMap operations; LOINC, SNOMED, ICD-10 |
46
+ | GraphQL | `/docs/graphql` | Queries, mutations, connections, nested resolution, reverse references, array filtering |
47
+ | React Components | `/docs/react` | MedplumProvider, hooks, Mantine integration, tree-shaking, useSubscription |
48
+ | Analytics | `/docs/analytics` | Analytics and reporting capabilities |
49
+ | Auth | `/docs/auth` | OAuth2 flows, client credentials, external IDPs, Google, mTLS, MFA, token exchange, sessions |
50
+ | User Management | `/docs/user-management` | Project vs server users, registration, invitations |
51
+ | Access Control | `/docs/access` | Access policies, compartments, SMART scopes, IP rules, multi-tenant, field-level control |
52
+ | AI | `/docs/ai` | AI operations, AWS integration, MCP server |
53
+ | Bots | `/docs/bots` | Bot basics, cron jobs, questionnaire handlers, Lambda layers, secrets, webhooks, HL7, PDFs, unit testing |
54
+ | Subscriptions | `/docs/subscriptions` | Event-driven notifications, WebSocket, webhook resending |
55
+ | CLI | `/docs/cli` | Command-line FHIR operations, external servers |
56
+ | Integrations | `/docs/integration` | DoseSpot, Health Gorilla, Stedi, Candid Health, eFax, HL7, FHIRcast, SMART, CDS Hooks, C-CDA |
57
+ | Agent | `/docs/agent` | On-prem agent for HL7/DICOM bridging |
58
+ | Self-Hosting | `/docs/self-hosting` | Self-hosted deployment |
59
+ | Compliance | `/docs/compliance` | HIPAA, SOC2, HITRUST, ONC, CLIA/CAP, CFR11, GMP, ISO9001 |
60
+ | API Reference | `/docs/api` | REST endpoints, FHIR resources (150+), operations (40+), datatypes (40+), Medplum custom resources |
61
+ | SDK Reference | `/docs/sdk/core` | MedplumClient, utility functions, interfaces, types |
62
+
63
+ ---
64
+
65
+ ## Clinical Workflows
66
+
67
+ | Workflow | Path | Key Resources |
68
+ |----------|------|---------------|
69
+ | Intake & Registration | `/docs/intake` | Patient, QuestionnaireResponse, Encounter |
70
+ | Charting | `/docs/charting` | Condition, AllergyIntolerance, Observation (vitals), DocumentReference |
71
+ | Scheduling | `/docs/scheduling` | Schedule, Slot, Appointment, AppointmentResponse |
72
+ | Labs & Imaging | `/docs/labs-imaging` | ServiceRequest, DiagnosticReport, Observation, ImagingStudy |
73
+ | Medications | `/docs/medications` | MedicationRequest, Medication, MedicationAdministration |
74
+ | Care Plans | `/docs/careplans` | CarePlan, CareTeam, Task, PlanDefinition, Goal |
75
+ | Communications | `/docs/communications` | Communication, CommunicationRequest (threads, messaging, SMS) |
76
+ | Billing | `/docs/billing` | Claim, Coverage, ExplanationOfBenefit, ChargeItem |
77
+
78
+ ### Clinical Configuration
79
+
80
+ | Feature | Path | Resources |
81
+ |---------|------|-----------|
82
+ | Provider Directory | `/docs/administration/provider-directory` | Practitioner, PractitionerRole, Organization, Location |
83
+ | Questionnaires | `/docs/questionnaires` | Questionnaire, QuestionnaireResponse, SDC extensions |
84
+ | Diagnostic Catalog | `/docs/careplans/diagnostic-catalog` | CodeSystem, ValueSet (LOINC panels) |
85
+ | Clinical Protocols | `/docs/careplans/protocols` | PlanDefinition, ActivityDefinition |
86
+
87
+ ---
88
+
89
+ ## SDK Reference — MedplumClient
90
+
91
+ ### CRUD Operations
92
+
93
+ | Method | Description |
94
+ |--------|-------------|
95
+ | `createResource(resource)` | Create new FHIR resource (server assigns ID) |
96
+ | `readResource(resourceType, id)` | Read resource by type and ID |
97
+ | `updateResource(resource)` | Update existing resource (must include ID) |
98
+ | `patchResource(resourceType, id, operations)` | Apply JSON Patch operations |
99
+ | `deleteResource(resourceType, id)` | Delete resource by type and ID |
100
+ | `upsertResource(resource, query)` | Atomic create-or-update via search query |
101
+ | `createResourceIfNoneExist(resource, query)` | Conditional create if no match found |
102
+
103
+ ### Search
104
+
105
+ | Method | Description |
106
+ |--------|-------------|
107
+ | `search(resourceType, query)` | Execute FHIR search, returns Bundle |
108
+ | `searchResources(resourceType, query)` | Returns resource array (unwrapped Bundle) |
109
+ | `searchOne(resourceType, query)` | Returns first matching resource |
110
+ | `searchResourcePages(resourceType, query)` | Async generator for paginated results |
111
+ | `fhirSearchUrl(resourceType, query)` | Build search URL from parameters |
112
+
113
+ ### Authentication
114
+
115
+ | Method | Description |
116
+ |--------|-------------|
117
+ | `startLogin(loginRequest)` | Initiate user login flow |
118
+ | `startClientLogin(clientId, clientSecret)` | OAuth2 client credentials flow |
119
+ | `startGoogleLogin(loginRequest)` | Google Sign-In authentication |
120
+ | `setAccessToken(accessToken, refreshToken)` | Manually set auth tokens |
121
+ | `setBasicAuth(clientId, clientSecret)` | Configure basic auth |
122
+ | `signOut()` | Revoke token and clear cache |
123
+ | `isAuthenticated(gracePeriod)` | Check current auth status |
124
+ | `getProfile()` | Get current user profile (sync) |
125
+ | `getProfileAsync()` | Get current user profile (async fetch) |
126
+
127
+ ### Advanced Operations
128
+
129
+ | Method | Description |
130
+ |--------|-------------|
131
+ | `executeBatch(bundle)` | Process batch or transaction Bundle |
132
+ | `executeBot(id, body, contentType)` | Run bot by ID or Identifier |
133
+ | `graphql(query, operationName, variables)` | Execute GraphQL queries |
134
+ | `readHistory(resourceType, id)` | Get all resource versions |
135
+ | `readPatientEverything(id)` | Patient $everything operation |
136
+ | `validateResource(resource)` | Validate resource against profiles |
137
+ | `valueSetExpand(params)` | Expand ValueSet for code lookups |
138
+ | `readResourceGraph(resourceType, id, graphName)` | Fetch linked resources via $graph |
139
+
140
+ ### Media & Files
141
+
142
+ | Method | Description |
143
+ |--------|-------------|
144
+ | `createBinary(data, filename, contentType)` | Create Binary resource from data |
145
+ | `createAttachment(data, filename, contentType)` | Create Attachment element with Binary |
146
+ | `createPdf(docDefinition, filename)` | Generate PDF as Binary (pdfmake) |
147
+ | `uploadMedia(contents, contentType, filename)` | Upload and create Media resource |
148
+ | `download(url)` | Download URL as blob |
149
+
150
+ ### Subscriptions & Real-time
151
+
152
+ | Method | Description |
153
+ |--------|-------------|
154
+ | `subscribeToCriteria(criteria, props)` | Subscribe to WebSocket notifications |
155
+ | `unsubscribeFromCriteria(criteria, props)` | Unsubscribe from criteria |
156
+ | `getSubscriptionManager()` | Access WebSocket subscription manager |
157
+
158
+ ---
159
+
160
+ ## SDK Utility Functions
161
+
162
+ | Function | Description |
163
+ |----------|-------------|
164
+ | `createReference(resource)` | Create a FHIR Reference from a resource |
165
+ | `getReferenceString(resource)` | Get `ResourceType/id` string |
166
+ | `getDisplayString(resource)` | Human-readable display for any resource |
167
+ | `formatHumanName(name)` | Format FHIR HumanName as string |
168
+ | `formatAddress(address)` | Format FHIR Address as string |
169
+ | `formatCodeableConcept(cc)` | Format CodeableConcept as string |
170
+ | `formatDate(date)` | Format FHIR date as human-readable |
171
+ | `formatDateTime(dateTime)` | Format FHIR dateTime as human-readable |
172
+ | `formatQuantity(quantity)` | Human-readable Quantity string |
173
+ | `getCodeBySystem(cc, system)` | Find code for a given system in CodeableConcept |
174
+ | `setCodeBySystem(cc, system, code)` | Set code for a given system |
175
+ | `getIdentifier(resource, system)` | Get identifier value for a system |
176
+ | `setIdentifier(resource, system, value)` | Set identifier for a system |
177
+ | `getExtension(resource, urls)` | Get extension by URL |
178
+ | `getExtensionValue(resource, urls)` | Get extension value by URL |
179
+ | `parseReference(ref)` | Parse reference string to ResourceType/ID |
180
+ | `resolveId(reference)` | Extract ID from reference |
181
+ | `isResource(value)` | Type guard for FHIR resource |
182
+ | `isReference(value)` | Type guard for FHIR Reference |
183
+ | `deepClone(value)` | Deep clone a FHIR resource |
184
+ | `deepEquals(a, b)` | Compare resources (ignoring versionId) |
185
+ | `normalizeOperationOutcome(error)` | Normalize error to OperationOutcome |
186
+ | `normalizeErrorString(error)` | Normalize error to displayable string |
187
+ | `getQuestionnaireAnswers(response)` | Extract answers as map by linkId |
188
+ | `evalFhirPath(expression, resource)` | Evaluate FHIRPath expression |
189
+ | `validateResource(resource)` | Validate against StructureDefinition |
190
+ | `generateId()` | Cross-platform UUID generator |
191
+
192
+ ---
193
+
194
+ ## FHIR Search Syntax
195
+
196
+ ### Parameter Types
197
+
198
+ | Type | Behavior | Example |
199
+ |------|----------|---------|
200
+ | `string` | Case-insensitive prefix match | `name=eve` matches Eve, Evelyn |
201
+ | `token` | Exact match, supports system namespace | `identifier=http://sys\|val` |
202
+ | `date` | Supports comparison prefixes | `birthdate=1940-03-29` |
203
+ | `reference` | Links to other resources | `subject=Patient/123` |
204
+ | `quantity` | Numeric with units | `value-quantity=gt40` |
205
+ | `number` | Plain numeric | `probability=gt0.8` |
206
+
207
+ ### Operators
208
+
209
+ | Operator | Syntax | Example |
210
+ |----------|--------|---------|
211
+ | AND | Multiple parameters | `name=Simpson&birthdate=1940-03-29` |
212
+ | OR | Comma-separated | `status=completed,cancelled` |
213
+
214
+ ### Modifiers
215
+
216
+ | Modifier | Purpose | Example |
217
+ |----------|---------|---------|
218
+ | `:not` | Exclude values | `status:not=completed` |
219
+ | `:missing` | Include/exclude absent params | `birthdate:missing=true` |
220
+ | `:contains` | Substring match (string only) | `name:contains=eve` |
221
+ | `:exact` | Case-sensitive exact match | `name:exact=Eve` |
222
+
223
+ ### Comparison Prefixes (date, quantity, number)
224
+
225
+ | Prefix | Meaning |
226
+ |--------|---------|
227
+ | `eq` | Equal (default) |
228
+ | `ne` | Not equal |
229
+ | `gt` | Greater than |
230
+ | `lt` | Less than |
231
+ | `ge` | Greater than or equal |
232
+ | `le` | Less than or equal |
233
+ | `sa` | Starts after |
234
+ | `eb` | Ends before |
235
+
236
+ ### Special Parameters
237
+
238
+ | Parameter | Purpose | Example |
239
+ |-----------|---------|---------|
240
+ | `_sort` | Sort results (prefix `-` for descending) | `_sort=-_lastUpdated` |
241
+ | `_count` | Results per page | `_count=20` |
242
+ | `_offset` | Pagination offset | `_offset=40` |
243
+ | `_total` | Include total count | `_total=accurate` |
244
+ | `_include` | Include forward-referenced resources | `_include=Observation:patient` |
245
+ | `_revinclude` | Include backward-referencing resources | `_revinclude=Provenance:target` |
246
+ | `_include:iterate` | Recursive inclusion (multi-hop) | `_include:iterate=Patient:general-practitioner` |
247
+
248
+ ---
249
+
250
+ ## Core FHIR Resources
251
+
252
+ ### Clinical
253
+
254
+ | Resource | Purpose |
255
+ |----------|---------|
256
+ | `Patient` | Demographics, identifiers, contacts |
257
+ | `Practitioner` | Provider demographics, qualifications |
258
+ | `PractitionerRole` | Provider role at organization/location |
259
+ | `Organization` | Healthcare organization |
260
+ | `Encounter` | Patient visit or interaction |
261
+ | `Condition` | Diagnosis or health concern |
262
+ | `Observation` | Measurements, vitals, lab results |
263
+ | `DiagnosticReport` | Lab/imaging report aggregating observations |
264
+ | `ServiceRequest` | Order for a procedure, lab, or referral |
265
+ | `MedicationRequest` | Prescription or medication order |
266
+ | `AllergyIntolerance` | Allergy or adverse reaction record |
267
+ | `Procedure` | Performed clinical procedure |
268
+ | `CarePlan` | Treatment plan with activities and goals |
269
+ | `CareTeam` | Group of practitioners caring for a patient |
270
+ | `Goal` | Patient health objective |
271
+ | `Task` | Actionable work item |
272
+
273
+ ### Administrative
274
+
275
+ | Resource | Purpose |
276
+ |----------|---------|
277
+ | `Schedule` | Provider availability container |
278
+ | `Slot` | Bookable time block within a Schedule |
279
+ | `Appointment` | Scheduled visit with participants |
280
+ | `Coverage` | Insurance/payer information |
281
+ | `Claim` | Billing claim submission |
282
+ | `Communication` | Message between participants |
283
+ | `Questionnaire` | Form/survey definition |
284
+ | `QuestionnaireResponse` | Completed form responses |
285
+
286
+ ### Infrastructure
287
+
288
+ | Resource | Purpose |
289
+ |----------|---------|
290
+ | `Bundle` | Collection of resources (transaction, batch, searchset) |
291
+ | `Subscription` | Event-driven notification trigger |
292
+ | `AuditEvent` | Security/privacy audit log entry |
293
+ | `Binary` | Raw binary data (files, images) |
294
+ | `DocumentReference` | Metadata about a document/attachment |
295
+ | `OperationOutcome` | Processing result with issues/errors |
296
+ | `ValueSet` | Set of codes for a specific use |
297
+ | `CodeSystem` | Collection of codes in a domain |
298
+ | `StructureDefinition` | Resource profile/schema definition |
299
+ | `PlanDefinition` | Clinical protocol/workflow template |
300
+
301
+ ### Medplum Custom Resources
302
+
303
+ | Resource | Purpose |
304
+ |----------|---------|
305
+ | `Bot` | Serverless function definition |
306
+ | `ClientApplication` | OAuth2 client registration |
307
+ | `Project` | Top-level tenant/organization container |
308
+ | `ProjectMembership` | User membership with role/access policy |
309
+ | `AccessPolicy` | Resource-level access control rules |
310
+ | `Agent` | On-prem integration agent |
311
+ | `UserConfiguration` | User UI preferences |
312
+
313
+ ---
314
+
315
+ ## Security & Identity
316
+
317
+ ### Authentication Flows
318
+
319
+ | Flow | Use Case | SDK Method |
320
+ |------|----------|------------|
321
+ | Client Credentials | Service-to-service, backend | `startClientLogin(clientId, secret)` |
322
+ | Authorization Code | User-facing web apps | `startLogin()` + `processCode()` |
323
+ | Google Sign-In | Google SSO | `startGoogleLogin()` |
324
+ | External IDP | Auth0, Cognito, Okta | `signInWithExternalAuth()` |
325
+ | JWT Bearer | Server-issued JWT assertion | `startJwtBearerLogin()` |
326
+ | Token Exchange | Convert external tokens | `exchangeExternalAccessToken()` |
327
+ | mTLS | Certificate-based auth | Server config |
328
+
329
+ ### Access Policy Features
330
+
331
+ | Feature | Description |
332
+ |---------|-------------|
333
+ | Resource type rules | Allow/deny per resource type (read, write, create, delete) |
334
+ | Read-only fields | `readonlyFields` array on resource type |
335
+ | Hidden fields | `hiddenFields` array on resource type |
336
+ | Criteria filtering | FHIR search query (e.g., `Patient?address-state=CA`) |
337
+ | Compartments | Patient-based data isolation via `_compartment` |
338
+ | Parameterized | Variables: `%profile`, `%profile.id`, `%patient`, custom |
339
+ | Write constraints | FHIRPath expressions for state machine enforcement |
340
+ | SMART scopes | `patient/*.read`, `user/*.write` style scopes |
341
+ | IP rules | Restrict by IP address/CIDR |
342
+
343
+ ---
344
+
345
+ ## Automation
346
+
347
+ ### Bot Handler Pattern
348
+
349
+ ```typescript
350
+ import { BotEvent, MedplumClient } from '@medplum/core';
351
+ import { Patient } from '@medplum/fhirtypes';
352
+
353
+ export async function handler(medplum: MedplumClient, event: BotEvent): Promise<any> {
354
+ const patient = event.input as Patient;
355
+ // event.secrets — project secrets map
356
+ // event.bot — reference to this Bot resource
357
+ // event.traceId — request correlation ID
358
+ return true;
359
+ }
360
+ ```
361
+
362
+ ### Bot Execution Triggers
363
+
364
+ | Trigger | Method |
365
+ |---------|--------|
366
+ | HTTP POST | `POST /fhir/R4/Bot/<ID>/$execute` |
367
+ | FHIR Subscription | Subscription criteria → rest-hook to `Bot/<ID>` |
368
+ | Cron schedule | Bot with cron expression in properties |
369
+ | Manual | Execute button in Medplum App |
370
+
371
+ ### Subscription Pattern
372
+
373
+ ```typescript
374
+ // Server-side: create Subscription resource
375
+ const sub = await medplum.createResource({
376
+ resourceType: 'Subscription',
377
+ status: 'active',
378
+ criteria: 'Patient?name=Simpson',
379
+ channel: { type: 'rest-hook', endpoint: 'Bot/<BOT_ID>' }
380
+ });
381
+
382
+ // Client-side: WebSocket subscription
383
+ medplum.subscribeToCriteria('Patient?name=Simpson');
384
+ ```
385
+
386
+ ---
387
+
388
+ ## Integrations
389
+
390
+ | Integration | Path | Purpose |
391
+ |-------------|------|---------|
392
+ | DoseSpot | `/docs/integration/dosespot` | E-prescribing (enrollment, favorites, Rx) |
393
+ | Health Gorilla | `/docs/integration/health-gorilla` | Lab orders, receiving results |
394
+ | Stedi | `/docs/integration/stedi` | EDI/X12 eligibility checks |
395
+ | Candid Health | `/docs/integration/candid-health` | Revenue cycle management |
396
+ | eFax | `/docs/integration/efax` | Fax send/receive |
397
+ | HL7 v2 | `/docs/integration/hl7-interfacing` | ADT, ORM/OBR/OBX message interfacing |
398
+ | FHIRcast | `/docs/fhircast` | Real-time clinical context synchronization |
399
+ | SMART App Launch | `/docs/integration/smart-app-launch` | Embedded app launch framework |
400
+ | CDS Hooks | `/docs/integration/cds-hooks` | Clinical decision support at workflow triggers |
401
+ | C-CDA | `/docs/integration/c-cda` | Continuity of Care Document export |
402
+ | On-Prem Agent | `/docs/agent` | Bridge to on-prem HL7/DICOM systems |
403
+ | Log Streaming | `/docs/integration/log-streaming` | External log aggregation |
404
+
405
+ ---
406
+
407
+ ## Terminology Systems
408
+
409
+ | System | URI | Usage |
410
+ |--------|-----|-------|
411
+ | LOINC | `http://loinc.org` | Lab tests, vitals, clinical observations |
412
+ | SNOMED CT | `http://snomed.info/sct` | Clinical findings, procedures, body structures |
413
+ | ICD-10 | `http://hl7.org/fhir/sid/icd-10-cm` | Diagnoses, billing codes |
414
+ | RxNorm | `http://www.nlm.nih.gov/research/umls/rxnorm` | Medications (ingredients, brands, dose forms) |
415
+ | NDC | `http://hl7.org/fhir/sid/ndc` | Drug product codes (packaging level) |
416
+ | CPT | `http://www.ama-assn.org/go/cpt` | Procedure billing codes |
417
+ | UCUM | `http://unitsofmeasure.org` | Units of measure |
418
+ | US NPI | `http://hl7.org/fhir/sid/us-npi` | National Provider Identifier |
419
+ | US SSN | `http://hl7.org/fhir/sid/us-ssn` | Social Security Number |
420
+
421
+ ---
422
+
423
+ ## Compliance
424
+
425
+ | Standard | Path | Scope |
426
+ |----------|------|-------|
427
+ | HIPAA | `/docs/compliance/hipaa` | PHI protection, BAA, audit logging |
428
+ | SOC 2 Type II | `/docs/compliance/soc2` | Security, availability, confidentiality |
429
+ | HITRUST | `/docs/compliance/hitrust` | Healthcare security framework |
430
+ | ONC | `/docs/compliance/onc` | Health IT certification |
431
+ | CLIA/CAP | `/docs/compliance/clia-cap` | Laboratory certification |
432
+ | 21 CFR Part 11 | `/docs/compliance/cfr11` | Electronic records/signatures |
433
+ | ISO 9001 | `/docs/compliance/iso9001` | Quality management |
434
+ | HTI-1/HTI-4 | `/docs/compliance/hti-4` | Health tech interoperability rules |
435
+
436
+ ---
437
+
438
+ ## React Components (@medplum/react)
439
+
440
+ ### Setup
441
+
442
+ Requires: React 18+, Mantine 7+, PostCSS with Mantine preset, `@medplum/core`, `@medplum/react`.
443
+
444
+ Provider nesting: `BrowserRouter` → `MedplumProvider` → `MantineProvider`.
445
+
446
+ ### Key Components
447
+
448
+ | Component | Purpose |
449
+ |-----------|---------|
450
+ | `<MedplumProvider>` | Provides MedplumClient context to app |
451
+ | `<SignInForm>` | Authentication form |
452
+ | `<ResourceTable>` | Display resource fields in table |
453
+ | `<ResourceForm>` | Edit resource with auto-generated form |
454
+ | `<SearchControl>` | Search interface with filters and results |
455
+ | `<QuestionnaireForm>` | Render and submit FHIR Questionnaire |
456
+ | `<QuestionnaireBuilder>` | Build/edit Questionnaire resources |
457
+ | `<ChatControl>` | Communication thread interface |
458
+
459
+ ### Key Hooks
460
+
461
+ | Hook | Purpose |
462
+ |------|---------|
463
+ | `useMedplum()` | Access MedplumClient instance |
464
+ | `useMedplumContext()` | Access client + profile + loading state |
465
+ | `useResource(ref)` | Read resource by reference |
466
+ | `useSearch(type, query)` | Execute search with React Suspense |
467
+ | `useSubscription(criteria)` | WebSocket subscription with auto-cleanup |
468
+
469
+ ---
470
+
471
+ ## Bundle Transaction Pattern
472
+
473
+ ```typescript
474
+ const bundle = await medplum.executeBatch({
475
+ resourceType: 'Bundle',
476
+ type: 'transaction',
477
+ entry: [
478
+ {
479
+ fullUrl: 'urn:uuid:patient-1',
480
+ resource: { resourceType: 'Patient', name: [{ family: 'Smith' }] },
481
+ request: { method: 'POST', url: 'Patient' }
482
+ },
483
+ {
484
+ resource: {
485
+ resourceType: 'Observation',
486
+ subject: { reference: 'urn:uuid:patient-1' }, // internal ref
487
+ code: { coding: [{ system: 'http://loinc.org', code: '8867-4' }] }
488
+ },
489
+ request: { method: 'POST', url: 'Observation' }
490
+ }
491
+ ]
492
+ });
493
+ ```
494
+
495
+ Key patterns:
496
+ - `urn:uuid:` for internal references resolved server-side
497
+ - `ifNoneExist` on request for conditional creates
498
+ - `ifMatch` with `W/"versionId"` for optimistic concurrency
499
+ - Conditional references: `Practitioner?identifier=http://hl7.org/fhir/sid/us-npi|123`
500
+ - Async processing via `Prefer: respond-async` header for large bundles
501
+
502
+ ---
503
+
504
+ ## GraphQL Patterns
505
+
506
+ ```graphql
507
+ # Search with nested resolution
508
+ {
509
+ PatientList(name: "Eve", address_city: "Philadelphia") {
510
+ id
511
+ name { family given }
512
+ }
513
+ }
514
+
515
+ # Reverse references
516
+ {
517
+ Patient(id: "123") {
518
+ encounters: EncounterList(_reference: patient) {
519
+ id
520
+ status
521
+ }
522
+ }
523
+ }
524
+
525
+ # Inline fragments for reference resolution
526
+ {
527
+ DiagnosticReport(id: "456") {
528
+ result {
529
+ resource { ... on Observation { valueQuantity { value unit } } }
530
+ }
531
+ }
532
+ }
533
+ ```
534
+
535
+ Notes: Search uses snake_case params (not kebab-case). `:not`, `:missing`, `:contains` modifiers not supported in GraphQL. Schema introspection disabled by default.