Skip to content
This repository was archived by the owner on Mar 18, 2026. It is now read-only.

feat: opt-in profile constraints and field documentation extraction#5

Open
Palid wants to merge 3 commits intofhir-clj:mainfrom
MEWB-AS:main
Open

feat: opt-in profile constraints and field documentation extraction#5
Palid wants to merge 3 commits intofhir-clj:mainfrom
MEWB-AS:main

Conversation

@Palid
Copy link
Copy Markdown

@Palid Palid commented Nov 6, 2025

🎯 Problem

FHIR profiles define important metadata that wasn't being extracted by type-schema:

  1. Profile Constraints: Profiles like Norwegian Basis define constrained complex types (e.g., NoBasisHumanName extending HumanName) with specific profile URLs that downstream generators need to generate correct TypeScript types.

  2. Field Documentation: FHIR elements contain rich documentation (short, definition, comment, requirements, etc.) that should be available as JSDoc comments in generated code for developer experience.

Without this metadata, TypeScript generators cannot:

  • Use profile-specific constrained types (forced to use base FHIR types)
  • Generate helpful JSDoc documentation for fields
  • Properly handle complex-type-constraint profiles

💡 Solution

This PR introduces two opt-in CLI flags that extract additional metadata from FHIR schemas:

1. --include-profile-constraints flag

Extracts profile URLs from constrained elements into a new profileConstraints field:

{:name "name"
 :type "HumanName"
 :profileConstraints [{:url "http://hl7.no/fhir/StructureDefinition/no-basis-HumanName"
                       :kind "complex-type-constraint"}]
 ...}

2. --include-field-docs flag

Extracts comprehensive documentation into field-level docs:

{:name "identifier"
 :short "A unique identifier for the patient"
 :definition "An identifier for this patient..."
 :comment "Patients are almost always assigned..."
 :requirements "Patients are often assigned specific..."
 :alias ["Medical Record Number" "MRN"]
 ...}

📊 Evidence & Testing

Test Coverage

  • 25 tests with 138 assertions - all passing ✅
  • Tests validate both flags work correctly with Norwegian Basis profiles
  • Backward compatibility maintained (flags default to false)

Real-World Example

Norwegian Basis Patient profile:

Without flags:

interface NoBasisPatient extends Patient {
  name?: HumanName[];  // ❌ Uses base type
  // No JSDoc
}

With --include-profile-constraints:

interface NoBasisPatient extends Patient {
  name?: NoBasisHumanName[];  // ✅ Uses constrained type
}

With --include-field-docs:

interface Patient {
  /**
   * @summary A name associated with the patient
   * @description A name associated with the individual. A patient may have
   * multiple names with different uses or applicable periods.
   * @remarks Names may be changed, or repudiated, or people may have
   * different names in different contexts.
   */
  name?: HumanName[];
}

🔧 Implementation Details

Files Changed

  • src/type_schema/core.clj (+220 lines): Core extraction logic
  • src/main.clj (+34 lines): CLI option definitions
  • test/type_schema/profile_test.clj (+137 lines): Profile constraint tests
  • test/main_test.clj (+80 lines): CLI flag tests
  • .gitignore (+1 line): Ignore generated files

Backward Compatibility

  • Both flags default to false - no changes to existing behavior
  • Output schema structure unchanged when flags are disabled
  • Minimal performance impact when enabled

🔗 Related Work

Companion PR: fhir-schema/fhir-schema-codegen#40 implements the TypeScript generator support for these new fields.

Release: Available at https://github.com/MEWB-AS/type-schema/releases/tag/v0.0.16 for immediate testing.

🧪 Testing Instructions

# Clone and build
git clone https://github.com/fhir-clj/type-schema.git
cd type-schema
clojure -T:build uber

# Test without flags (baseline)
java -jar target/type-schema.jar \
  hl7.fhir.r4.core@4.0.1 \
  hl7.fhir.no.basis@2.2.2 \
  -o /tmp/no-flags.ndjson

# Test with profile constraints
java -jar target/type-schema.jar \
  hl7.fhir.r4.core@4.0.1 \
  hl7.fhir.no.basis@2.2.2 \
  -o /tmp/with-constraints.ndjson \
  --include-profile-constraints

# Test with field docs
java -jar target/type-schema.jar \
  hl7.fhir.r4.core@4.0.1 \
  hl7.fhir.no.basis@2.2.2 \
  -o /tmp/with-docs.ndjson \
  --include-field-docs

# Compare outputs
grep 'profileConstraints' /tmp/no-flags.ndjson
# Should return nothing

grep 'profileConstraints' /tmp/with-constraints.ndjson
# Should find multiple matches

grep '"short"' /tmp/no-flags.ndjson
# Should return nothing

grep '"short"' /tmp/with-docs.ndjson
# Should find multiple matches

✅ Checklist

  • Tests pass (25 tests, 138 assertions)
  • Backward compatible (opt-in flags)
  • Documentation updated
  • Released for testing (v0.0.16)

…on (v0.0.16)

Add two new optional features for type-schema generation, both disabled
by default to maintain backward compatibility:

**1. Profile Constraints Extraction** (`--include-profile-constraints`)
- Extracts FHIR profile URLs from StructureDefinition elements
- Adds `profileConstraints` field to output schema
- Example: Norwegian Basis profiles (no-basis-HumanName, no-basis-Address)
- Useful for: validation, code generation, profile-aware tooling

**2. Field Documentation Extraction** (`--include-field-docs`)
- Extracts element documentation from StructureDefinition
- Includes: short, definition, comment, requirements, mustSupport,
  binding info, examples, and other metadata
- Useful for: documentation generation, tooltips, developer guidance

## API Changes

### Library API (translate-fhir-schema)
```clojure
;; Default behavior (backward compatible)
(translate-fhir-schema fhir-schema)

;; With profile constraints
(translate-fhir-schema fhir-schema {:include-profile-constraints? true})

;; With field documentation
(translate-fhir-schema fhir-schema {:include-field-docs? true})

;; Both features enabled
(translate-fhir-schema fhir-schema
  {:include-profile-constraints? true
   :include-field-docs? true})
```

### CLI Interface
```bash
# Include profile constraints
type-schema --include-profile-constraints hl7.fhir.no.basis@2.2.2

# Include field documentation
type-schema --include-field-docs hl7.fhir.r4.core

# Both flags together
type-schema --include-profile-constraints --include-field-docs \\
  hl7.fhir.r4.core hl7.fhir.no.basis@2.2.2
```

## Implementation Details

**Core Functions Added:**
- `path->element-id`: Convert path to StructureDefinition element ID
- `extract-profile-constraints`: Extract profile URLs and names
- `extract-field-documentation`: Extract element documentation

**Updated Functions:**
- `build-field`: Accept and use feature flags
- `iterate-over-elements`: Pass options to build-field
- `iterate-over-backbone-element`: Pass options through
- `translate-fhir-schema`: Accept and propagate options map
- `process-packages` (CLI): Pass CLI flags to translate-fhir-schema

**CLI Options Added:**
- `--include-profile-constraints`: Enable profile constraint extraction
- `--include-field-docs`: Enable field documentation extraction

## Testing

**Library Tests** (test/type_schema/profile_test.clj):
- Backward compatibility tests (flags disabled by default)
- Profile constraints extraction with Norwegian Basis profiles
- Field documentation extraction from standard FHIR Patient
- Combined flags test
- 6 test suites, all passing

**CLI Integration Tests** (test/main_test.clj):
- CLI option parsing validation
- Profile constraints flag with multi-package support
- Field documentation flag integration
- Backward compatibility (no flags)
- 4 additional test suites, all passing

**Test Results**: 25 total tests, 138 assertions, all passing ✅

## Backward Compatibility

- Both features default to `false` - no breaking changes
- All existing tests pass without modification
- Output schema is additive-only (no removed fields)
- Clean JSON output (empty collections removed via remove-empty-vals)
- CLI maintains all existing functionality

## Version

Bumped to **v0.0.16** for this release
Version bump to support FHIR-compliant extension generation with discriminated
unions in downstream fhir-schema-codegen.

This version is compatible with the extension generation improvements that fix
critical FHIR R4 spec violations where Extension profiles incorrectly inherited
ALL 55+ value[x] types from base Extension type.

No functional changes in type-schema itself - version bump enables coordinated
release with fhir-schema-codegen@0.0.25 extension generation fix.

Related changes:
- fhir-schema-codegen: Extension generation with discriminated unions
- medimind: Updated patch for @fhirschema/codegen@0.0.24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant