Skip to content

Code generator creates duplicate type-choice validators and properties for elements that are only profiled with mustSupport #268

@luisfabib

Description

@luisfabib

When a FHIR element with a choice type (e.g., deceased[x]) is profiled solely to add mustSupport=true without changing field definitions or constraints, the code generator includes duplicate property and validator definitions that already exist in the base class. This results in unnecessary code duplication and maintenance burden.

Current Behavior

For a profile that only marks Patient.deceased[x] as mustSupport:

{
  "id": "Patient.deceased[x]",
  "path": "Patient.deceased[x]",
  "mustSupport": True
}

The generator produces:

class ExamplePatient(Patient):
    """
    Example Patient Description
    """

    _canonical_url = "http://hl7.org/fhir/StructureDefinition/example-patient"

    meta: Optional[Meta] = Field(...)
    
    # ❌ Duplicate: Already defined in Patient base class
    @property 
    def deceased(self):
        return get_type_choice_value_by_base(self, base="deceased")
        
    # ❌ Duplicate: Already defined in Patient base class
    @model_validator(mode="after")
    def deceased_type_choice_validator(self):
        return validate_type_choice_element(
            self,
            field_types=['Boolean', 'DateTime'],
            field_name_base="deceased",
            required=False,
            non_allowed_types=[],
        )

The base Patient class already provides these identical implementations:

# In Patient base class:
@property 
def deceased(self):
    return get_type_choice_value_by_base(self, base="deceased")

@model_validator(mode="after")
def deceased_type_choice_validator(self):
    return validate_type_choice_element(...)

Expected Behavior

The code generator should detect when:

  1. A type-choice element has no field-level modifications (only mustSupport is set)
  2. The base class already provides the property and validator
  3. No constraints or restrictions are applied to the allowed types

In such cases, omit the duplicate definitions and rely on inheritance from the base class:

class ExamplePatient(Patient):
    """
    Example Patient Description
    """

    _canonical_url = "http://hl7.org/fhir/StructureDefinition/example-patient"

    meta: Optional[Meta] = Field(
        title="Meta",
        description="Metadata about the resource.",
        default_factory=lambda: Meta(profile=['http://hl7.org/fhir/StructureDefinition/example-patient']),
    )
    # ✅ No duplicate property or validator - inherited from Patient

Reproducible Example

from fhircraft.fhir.resources import generator, ResourceFactory
from fhircraft.fhir.resources.datatypes.R5.core import StructureDefinition

structure_definition = {
    "resourceType": "StructureDefinition",
    "id": "example-patient",
    "text": {
        "status": "generated",
        "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">to do</div>"
    },
    "url": "http://hl7.org/fhir/StructureDefinition/example-patient",
    "version": "5.0.0",
    "name": "ExamplePatient",
    "title": "Example Patient",
    "status": "draft",
    "experimental": False,
    "date": "2018-08-11",
    "description": "Example Patient Description",
    "fhirVersion": "5.0.0",
    "kind": "resource",
    "abstract": False,
    "type": "Patient",
    "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Patient",
    "derivation": "constraint",
    "differential": {
        "element": [
            {
                "id": "Patient",
                "path": "Patient",
                "mustSupport": True
            },
            {
                "id": "Patient.deceased[x]",
                "path": "Patient.deceased[x]",
                "mustSupport": True  # ❌ Only mustSupport changes - no field modifications
            }
        ]
    }
}

factory = ResourceFactory()
model = factory.construct_resource_model(structure_definition=structure_definition, mode="differential")

source_code = generator.generate_resource_model_code(model)
print(source_code)
# ❌ Includes duplicate property and validator from base class

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfhir.resourceswontfixThis will not be worked on

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions