Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ The `APIBuilder` class (`src/api/builder.ts`) provides the fluent API for the th
.typeSchema({ // IR transformations
treeShake: {...}, // Filter types
promoteLogical: {...}, // Promote logical models
resolveCollisions: {...}, // Resolve schema collisions
})
.introspection({ // Debug output (optional)
typeSchemas: "./schemas", // Type Schemas path/.ndjson
Expand Down
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [Tree Shaking](#tree-shaking)
- [Field-Level Tree Shaking](#field-level-tree-shaking)
- [Logical Model Promotion](#logical-model-promotion)
- [Resolving Schema Collisions](#resolving-schema-collisions)
- [Generation](#generation)
- [1. Writer-Based Generation (Programmatic)](#1-writer-based-generation-programmatic)
- [2. Mustache Template-Based Generation (Declarative)](#2-mustache-template-based-generation-declarative)
Expand Down Expand Up @@ -147,6 +148,7 @@ const builder = new APIBuilder()
.typeSchema({
treeShake: { ... }, // Include only specified types
promoteLogical: { ... }, // Process logical models as resources
resolveCollisions: { ... },// Resolve duplicate schema collisions
})

// Code generator (choose one)
Expand Down Expand Up @@ -283,6 +285,57 @@ const builder = new APIBuilder({})
})
```

#### Resolving Schema Collisions

When multiple StructureDefinitions produce the same binding (e.g. `ObservationCategory` from both `Observation` and `ObservationDefinition`), the schemas may differ in strength or value set. By default the generator picks the most common variant and emits a warning:

```
! ts: 'urn:fhir:binding:ObservationCategory' from 'shared' has 2 versions (#duplicateSchema)
```

To fix this, add `resolveCollisions` to `.typeSchema()` specifying which source should win for each binding URL:

```typescript
.typeSchema({
resolveCollisions: {
"urn:fhir:binding:ObservationCategory": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Observation",
},
},
})
```

- **`package`** — the FHIR package ID (`name#version`) that contains the preferred source
- **`canonical`** — the StructureDefinition URL that should provide the authoritative binding

The generated `README.md` report (from `.introspection()`) lists all collisions with version details and includes a ready-to-paste `resolveCollisions` config for any unresolved ones. Example output:

```markdown
## Schema Collisions

- `urn:fhir:binding:CommunicationReason` (2 versions)
- Version 1 (selected): Communication (hl7.fhir.r4.core#4.0.1)
- Version 2: CommunicationRequest (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ProcessPriority` (2 versions)
- Version 1 (auto): Claim (hl7.fhir.r4.core#4.0.1), CoverageEligibilityRequest (hl7.fhir.r4.core#4.0.1)
- Version 2: ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)

### Suggested `resolveCollisions` config

.typeSchema({
resolveCollisions: {
"urn:fhir:binding:ProcessPriority": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Claim",
},
},
})
```

- **(selected)** — resolved by your `resolveCollisions` config
- **(auto)** — picked automatically (most common variant); add to config to make explicit

### Generation

The generation stage transforms Type Schema into target language code using two complementary approaches:
Expand Down
47 changes: 41 additions & 6 deletions examples/python/fhir_types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2548,20 +2548,55 @@ and check `<pkg>/collisions/<name>/1.json, 2.json, ...` files.
### `shared`

- `urn:fhir:binding:CommunicationReason` (2 versions)
- Version 1: Communication (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Communication (hl7.fhir.r4.core#4.0.1)
- Version 2: CommunicationRequest (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ObservationCategory` (2 versions)
- Version 1: Observation (hl7.fhir.r4.core#4.0.1), vitalsigns (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Observation (hl7.fhir.r4.core#4.0.1), vitalsigns (hl7.fhir.r4.core#4.0.1)
- Version 2: ObservationDefinition (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ObservationRangeMeaning` (2 versions)
- Version 1: cholesterol (hl7.fhir.r4.core#4.0.1), hdlcholesterol (hl7.fhir.r4.core#4.0.1), ldlcholesterol (hl7.fhir.r4.core#4.0.1), Observation (hl7.fhir.r4.core#4.0.1), triglyceride (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): cholesterol (hl7.fhir.r4.core#4.0.1), hdlcholesterol (hl7.fhir.r4.core#4.0.1), ldlcholesterol (hl7.fhir.r4.core#4.0.1), Observation (hl7.fhir.r4.core#4.0.1), triglyceride (hl7.fhir.r4.core#4.0.1)
- Version 2: ObservationDefinition (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:PaymentType` (2 versions)
- Version 1: ClaimResponse (hl7.fhir.r4.core#4.0.1), ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): ClaimResponse (hl7.fhir.r4.core#4.0.1), ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- Version 2: PaymentReconciliation (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ProcessPriority` (2 versions)
- Version 1: Claim (hl7.fhir.r4.core#4.0.1), CoverageEligibilityRequest (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Claim (hl7.fhir.r4.core#4.0.1), CoverageEligibilityRequest (hl7.fhir.r4.core#4.0.1)
- Version 2: ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:TargetDisease` (2 versions)
- Version 1: Immunization (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Immunization (hl7.fhir.r4.core#4.0.1)
- Version 2: ImmunizationRecommendation (hl7.fhir.r4.core#4.0.1)

### Suggested `resolveCollisions` config

Add to `.typeSchema({ resolveCollisions: { ... } })` to resolve remaining collisions:

```typescript
.typeSchema({
resolveCollisions: {
"urn:fhir:binding:CommunicationReason": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Communication",
},
"urn:fhir:binding:ObservationCategory": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Observation",
},
"urn:fhir:binding:ObservationRangeMeaning": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/cholesterol",
},
"urn:fhir:binding:PaymentType": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/ClaimResponse",
},
"urn:fhir:binding:ProcessPriority": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Claim",
},
"urn:fhir:binding:TargetDisease": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Immunization",
},
},
})
```
31 changes: 25 additions & 6 deletions examples/typescript-r4/fhir-types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2533,20 +2533,39 @@ and check `<pkg>/collisions/<name>/1.json, 2.json, ...` files.
### `shared`

- `urn:fhir:binding:CommunicationReason` (2 versions)
- Version 1: Communication (hl7.fhir.r4.core#4.0.1)
- Version 1 (selected): Communication (hl7.fhir.r4.core#4.0.1)
- Version 2: CommunicationRequest (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ObservationCategory` (2 versions)
- Version 1: Observation (hl7.fhir.r4.core#4.0.1), vitalsigns (hl7.fhir.r4.core#4.0.1)
- Version 1 (selected): Observation (hl7.fhir.r4.core#4.0.1), vitalsigns (hl7.fhir.r4.core#4.0.1)
- Version 2: ObservationDefinition (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ObservationRangeMeaning` (2 versions)
- Version 1: cholesterol (hl7.fhir.r4.core#4.0.1), hdlcholesterol (hl7.fhir.r4.core#4.0.1), ldlcholesterol (hl7.fhir.r4.core#4.0.1), Observation (hl7.fhir.r4.core#4.0.1), triglyceride (hl7.fhir.r4.core#4.0.1)
- Version 1 (selected): cholesterol (hl7.fhir.r4.core#4.0.1), hdlcholesterol (hl7.fhir.r4.core#4.0.1), ldlcholesterol (hl7.fhir.r4.core#4.0.1), Observation (hl7.fhir.r4.core#4.0.1), triglyceride (hl7.fhir.r4.core#4.0.1)
- Version 2: ObservationDefinition (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:PaymentType` (2 versions)
- Version 1: ClaimResponse (hl7.fhir.r4.core#4.0.1), ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- Version 1 (selected): ClaimResponse (hl7.fhir.r4.core#4.0.1), ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- Version 2: PaymentReconciliation (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:ProcessPriority` (2 versions)
- Version 1: Claim (hl7.fhir.r4.core#4.0.1), CoverageEligibilityRequest (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Claim (hl7.fhir.r4.core#4.0.1), CoverageEligibilityRequest (hl7.fhir.r4.core#4.0.1)
- Version 2: ExplanationOfBenefit (hl7.fhir.r4.core#4.0.1)
- `urn:fhir:binding:TargetDisease` (2 versions)
- Version 1: Immunization (hl7.fhir.r4.core#4.0.1)
- Version 1 (auto): Immunization (hl7.fhir.r4.core#4.0.1)
- Version 2: ImmunizationRecommendation (hl7.fhir.r4.core#4.0.1)

### Suggested `resolveCollisions` config

Add to `.typeSchema({ resolveCollisions: { ... } })` to resolve remaining collisions:

```typescript
.typeSchema({
resolveCollisions: {
"urn:fhir:binding:ProcessPriority": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Claim",
},
"urn:fhir:binding:TargetDisease": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Immunization",
},
},
})
```
18 changes: 18 additions & 0 deletions examples/typescript-r4/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ if (require.main === module) {
"http://hl7.org/fhir/StructureDefinition/patient-birthTime": {},
},
},
resolveCollisions: {
"urn:fhir:binding:CommunicationReason": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Communication",
},
"urn:fhir:binding:ObservationCategory": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Observation",
},
"urn:fhir:binding:ObservationRangeMeaning": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/Observation",
},
"urn:fhir:binding:PaymentType": {
package: "hl7.fhir.r4.core#4.0.1",
canonical: "http://hl7.org/fhir/StructureDefinition/ClaimResponse",
},
},
})
.introspection({
typeSchemas: "type-schemas",
Expand Down
Loading
Loading