Class: Generator::MetadataManager

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/au_ps_inferno/generator/metadata_manager.rb

Overview

Builds and persists metadata for Composition sections from IG resources.

Extracts Composition StructureDefinition sections and their entry constraints (profiles, cardinality, mustSupport, section codes) and serializes them to YAML. Output hash keys: composition_sections, composition_mandatory_ms_elements, composition_optional_ms_elements, profiles.

rubocop:disable Metrics/ClassLength

Constant Summary collapse

%w[11369-6 30954-2 47519-4 46264-8].freeze
OPTIONAL_SECTIONS_CODES =
%w[42348-3 104605-1 47420-5 11348-0 10162-6 81338-6 18776-5 29762-2 8716-3].freeze
SUB_ELEMENTS_TO_SKIP =
%w[event.period event.code section.emptyReason section.entry section.code section.text
section.title meta.profile].freeze
ATTESTER_PROFILE_REFS =
[
  'Patient|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-patient',
  'RelatedPerson|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-relatedperson',
  'Practitioner|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-practitioner',
  'PractitionerRole|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-practitionerrole',
  'Organization|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-organization'
].freeze
AUTHOR_PROFILE_REFS =
[
  'Practitioner|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-practitioner',
  'PractitionerRole|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-practitionerrole',
  'Patient|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-patient',
  'RelatedPerson|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-relatedperson',
  'Organization|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-organization',
  'Device|http://hl7.org/fhir/uv/ips/StructureDefinition/Device-uv-ips'
].freeze
CUSTODIAN_PROFILE_REFS =
[
  'Organization|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-organization'
].freeze
SUBJECT_PROFILE_REFS =
[
  'Patient|http://hl7.org.au/fhir/ps/StructureDefinition/au-ps-patient'
].freeze

Constants included from Constants

Constants::REQUIRED_PROFILES, Constants::RESOURCES_FILTERS_MAPPING

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ig_resources) ⇒ MetadataManager

Initializes a MetadataManager for the given IG resources.

Parameters:

  • ig_resources (Array<FHIR::Model>)

    Parsed IG resources (e.g. from IGResourcesExtractor#ig_resources)



57
58
59
60
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 57

def initialize(ig_resources)
  @ig_resources = ig_resources
  
end

Instance Attribute Details

#composition_sectionsArray<Hash> (readonly)

Returns Array of section metadata hashes.

Returns:

  • (Array<Hash>)

    Array of section metadata hashes



20
21
22
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 20

def composition_sections
  @composition_sections
end

Instance Method Details



277
278
279
280
281
282
283
284
285
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 277

def all_ms_elements_related_to_slice(slice)
  composition_structure_definition = get_structure_definition_by_type('Composition')
  return [] if composition_structure_definition.nil?

  elements = composition_structure_definition.snapshot.element
  elements.filter do |element|
    ms_composition_path?(element) && element.path.include?(slice)
  end
end

#build_basic_section_data(section) ⇒ Hash

Builds the basic section fields from a snapshot element (no code or entries).

Parameters:

  • section (FHIR::Element)

    Snapshot element for Composition.section (with sliceName)

Returns:

  • (Hash)

    Basic section fields: :id, :short, :definition, :min, :max, :required, :mustSupport



449
450
451
452
453
454
455
456
457
458
459
460
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 449

def build_basic_section_data(section)
  {
    id: section.id,
    short: section.short,
    definition: section.definition,
    min: section.min,
    max: section.max,
    required: section.min.positive?,
    mustSupport: section.mustSupport || false,
    ms_elements: composition_ms_sections_elements
  }
end

#build_metadata_for_attesterObject



541
542
543
544
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 541

def 
  # attester.party: AU PS Patient | RelatedPerson | Practitioner | PractitionerRole | Organization (no Device)
  (ATTESTER_PROFILE_REFS)
end

#build_metadata_for_authorObject



546
547
548
549
550
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 546

def 
  # AU PS Practitioner, AU PS PractitionerRole, AU PS Patient, AU PS RelatedPerson,
  # AU PS Organization profiles or Device resource
  (AUTHOR_PROFILE_REFS)
end

#build_metadata_for_custodianObject



536
537
538
539
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 536

def 
  # Custodian is only AU PS Organization
  (CUSTODIAN_PROFILE_REFS)
end

#build_metadata_for_mapping(profile_refs) ⇒ Object



552
553
554
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 552

def (profile_refs)
  profile_refs.map { |profile| (profile) }
end

#build_metadata_for_slice(element) ⇒ Object



312
313
314
315
316
317
318
319
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 312

def (element)
  related = all_ms_elements_related_to_slice(element.path)
  base = element.path
  (element).merge(
    mandatory_ms_sub_elements: slice_relative_sub_paths(related, base, &:zero?),
    optional_ms_sub_elements: slice_relative_sub_paths(related, base, &:positive?)
  )
end

#build_metadata_for_subjectObject



532
533
534
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 532

def 
  SUBJECT_PROFILE_REFS.map { |profile| (profile) }
end

#build_normalized_element_data(element, sd_decorator) ⇒ Object



577
578
579
580
581
582
583
584
585
586
587
588
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 577

def build_normalized_element_data(element, sd_decorator)
  first_element_type = element&.type&.first
  profile = first_element_type&.profile&.first || ''
  {
    id: element.id,
    expression: element.path.gsub("#{sd_decorator.type}.", ''),
    label: element.sliceName,
    min: element.min,
    max: element.max,
    profile: profile
  }
end

#build_section_data(section, elements) ⇒ Hash

Builds a full section metadata hash including code and entries.

Parameters:

  • section (FHIR::Element)

    Snapshot element for Composition.section (with sliceName)

  • elements (Array<FHIR::Element>)

    All snapshot elements from the Composition StructureDefinition

Returns:

  • (Hash)

    Section metadata hash including keys: :id, :short, :definition, :min, :max, :required, :mustSupport, :code, :entries



435
436
437
438
439
440
441
442
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 435

def build_section_data(section, elements)
  basic_section_data = build_basic_section_data(section)
  {
    **basic_section_data,
    code: section_code(section.id, elements),
    entries: get_section_entry_data(elements, section.id)
  }
end

#build_section_entry_data(entry) ⇒ Hash

Builds entry metadata from a section entry snapshot element (id, cardinality, mustSupport, profiles).

Parameters:

  • entry (FHIR::Element)

    Snapshot element for section entry (e.g. Composition.section:...entry:problem)

Returns:

  • (Hash)

    Entry metadata hash including keys: :id, :min, :max, :required, :mustSupport, :profiles



496
497
498
499
500
501
502
503
504
505
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 496

def build_section_entry_data(entry)
  {
    id: entry.id,
    min: entry.min,
    max: entry.max,
    required: entry.min.positive?,
    mustSupport: entry.mustSupport || false,
    profiles: get_section_entry_profiles(entry.id, entry)
  }
end

#build_section_resources(section_data) ⇒ Object



158
159
160
161
162
163
164
165
166
167
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 158

def build_section_resources(section_data)
  resources = {}
  section_data[:entries].each do |entry|
    entry[:profiles].each do |profile|
      requirements = requirements_for_profile(profile)
      resources[profile] = { 'requirements' => requirements }
    end
  end
  resources
end

#composition_extract_ms_elements_without_slicesArray<FHIR::Element>

Returns Composition snapshot elements that are mustSupport, non-sliced, and under Composition. Uses element.path (profile path) not element.base.path, so inherited sub-elements like Composition.subject.reference are included (base.path would be Reference.reference).

Returns:

  • (Array<FHIR::Element>)

    Snapshot elements; empty if no Composition StructureDefinition



265
266
267
268
269
270
271
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 265

def composition_extract_ms_elements_without_slices
  composition_structure_definition = get_structure_definition_by_type('Composition')
  return [] if composition_structure_definition.nil?

  elements = composition_structure_definition.snapshot.element
  elements.filter { |element| ms_composition_path?(element) }
end

#composition_extract_slicesObject



303
304
305
306
307
308
309
310
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 303

def composition_extract_slices
  composition_structure_definition = get_structure_definition_by_type('Composition')
  return [] if composition_structure_definition.nil?

  elements = composition_structure_definition.snapshot.element
  filtered_elements = elements.filter { |element| element_is_slice?(element) }
  filtered_elements.map { |element| (element) }
end

#composition_mandatory_ms_slicesObject



287
288
289
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 287

def composition_mandatory_ms_slices
  composition_extract_slices.filter { |slice| slice[:mustSupport] == true && slice[:min].positive? }
end

#composition_mandatory_ms_slices_pathsObject



291
292
293
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 291

def composition_mandatory_ms_slices_paths
  composition_mandatory_ms_slices.map { |slice| slice[:path] }
end

#composition_ms_sections_elementsObject



146
147
148
149
150
151
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 146

def composition_ms_sections_elements
  filtered = composition_extract_ms_elements_without_slices.filter do |element|
    element&.path&.include?('Composition.section.')
  end
  filtered.map { |element| section_element_expression_min(element) }.uniq
end

#composition_optional_ms_slicesObject



295
296
297
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 295

def composition_optional_ms_slices
  composition_extract_slices.filter { |slice| slice[:mustSupport] == true && slice[:min].zero? }
end

#composition_optional_ms_slices_pathsObject



299
300
301
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 299

def composition_optional_ms_slices_paths
  composition_optional_ms_slices.map { |slice| slice[:path] }
end

#element_is_slice?(element) ⇒ Boolean

Returns:

  • (Boolean)


337
338
339
340
341
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 337

def element_is_slice?(element)
  element.id.include?(':') && element&.sliceName &&
    !element.path.include?('section') &&
    !element.path.include?('extension')
end

#extract_ms_elements_by_predicate(predicate) ⇒ Array<String>

Filters Composition mustSupport elements (no slices) by predicate and returns path suffixes. Uses element.path so suffixes are relative to Composition (e.g. subject.reference), not the base type.

Parameters:

  • predicate (Proc)

    Called with each element; keeps element when truthy (e.g. min.zero?, min.positive?)

Returns:

  • (Array<String>)

    Sorted unique paths with "Composition." prefix removed (e.g. subject.reference)



251
252
253
254
255
256
257
258
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 251

def extract_ms_elements_by_predicate(predicate)
  elements = composition_extract_ms_elements_without_slices.filter do |element|
    predicate.call(element)
  end
  elements.map do |element|
    element.path.gsub('Composition.', '')
  end.uniq.sort
end

#extract_optional_all_ms_elementsvoid

This method returns an undefined value.

Populates @composition_optional_ms_elements with mustSupport elements where min is 0.



211
212
213
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 211

def extract_optional_all_ms_elements
  extract_ms_elements_by_predicate(->(element) { element.min.zero? })
end

#extract_optional_ms_elementsObject



219
220
221
222
223
224
225
226
227
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 219

def extract_optional_ms_elements
  @composition_optional_ms_elements = extract_optional_all_ms_elements.filter do |path|
    path_is_not_slice?(path) && !path.include?('.') && path != 'section'
  end + ['event']
  @composition_optional_ms_sub_elements = extract_optional_all_ms_elements.filter do |path|
    path_is_not_slice?(path) && path.include?('.') && !SUB_ELEMENTS_TO_SKIP.include?(path)
  end
  @composition_optional_ms_slices = composition_optional_ms_slices
end

#extract_profilesvoid

This method returns an undefined value.

Populates @profiles with AU PS StructureDefinitions (url, name, title, required).



177
178
179
180
181
182
183
184
185
186
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 177

def extract_profiles
  @profiles = main_profiles.map do |profile|
    {
      url: profile.url.to_s,
      name: profile.name,
      title: profile.title,
      required: profile_required?(profile)
    }
  end
end

#extract_required_all_ms_elementsvoid

This method returns an undefined value.

Populates @composition_mandatory_ms_elements with mustSupport elements where min > 0.



232
233
234
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 232

def extract_required_all_ms_elements
  extract_ms_elements_by_predicate(->(element) { element.min.positive? })
end

#extract_required_ms_elementsObject



236
237
238
239
240
241
242
243
244
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 236

def extract_required_ms_elements
  @composition_mandatory_ms_elements = extract_required_all_ms_elements.filter do |path|
    path_is_not_slice?(path) && !path.include?('.') && path != 'section'
  end
  @composition_mandatory_ms_sub_elements = extract_required_all_ms_elements.filter do |path|
    path_is_not_slice?(path) && path.include?('.') && !SUB_ELEMENTS_TO_SKIP.include?(path)
  end
  @composition_mandatory_ms_slices = composition_mandatory_ms_slices
end

#extract_resource_filtersObject



94
95
96
97
98
99
100
101
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 94

def extract_resource_filters
  @resources_filters = RESOURCES_FILTERS_MAPPING.map do |resource_profile, filters|
    {
      resource_profile: resource_profile,
      filters: filters
    }
  end
end

#find_structure_definition_by_base_url(base_url) ⇒ FHIR::StructureDefinition?

Finds a StructureDefinition by canonical base URL (version stripped).

Parameters:

  • base_url (String)

    Canonical URL without version (e.g. http://hl7.org/fhir/StructureDefinition/Patient)

Returns:

  • (FHIR::StructureDefinition, nil)


383
384
385
386
387
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 383

def find_structure_definition_by_base_url(base_url)
  get_resources_by_type('StructureDefinition').find do |resource|
    resource.url.to_s.split('|').first == base_url
  end
end

#generate_metadata_for_compositionvoid

This method returns an undefined value.

Populates @composition_sections from the Composition StructureDefinition. No-op when no Composition StructureDefinition is present in the IG.



415
416
417
418
419
420
421
422
423
424
425
426
427
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 415

def 
  composition_structure_definition = get_structure_definition_by_type('Composition')
  return if composition_structure_definition.nil?

  elements = composition_structure_definition.snapshot.element
  sections = elements.filter do |element|
    element.path == 'Composition.section' && !element.sliceName.nil?
  end

  sections.each do |section|
    @composition_sections << build_section_data(section, elements)
  end
end

#get_elements_from_structure_definition(sd_data) ⇒ Object



590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 590

def get_elements_from_structure_definition(sd_data)
  structure_definition_data = StructureDefinitionDecorator.new(sd_data)
  elements = structure_definition_data.simple_elements(include_str: "#{sd_data.type}.")
  filtered_elements = elements.reject { |element| element.id.include?(':') }
  filtered_elements.map do |element|
    {
      id: element.id,
      expression: element.path.gsub("#{sd_data.type}.", ''),
      min: element.min
    }
  end.uniq
end

#get_extension_slices_from_structure_definition(sd_data) ⇒ Object



567
568
569
570
571
572
573
574
575
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 567

def get_extension_slices_from_structure_definition(sd_data)
  # Return mandatory MS extension slices
  sd_decorator = StructureDefinitionDecorator.new(sd_data)
  extension_slices = sd_decorator.extension_slices
  filtered_extension_slices = extension_slices.filter { |element| element.mustSupport == true }
  filtered_extension_slices.map do |element|
    build_normalized_element_data(element, sd_decorator)
  end.uniq
end

#get_resources_by_type(type) ⇒ Array<FHIR::Model>

Returns IG resources whose resourceType matches the given type.

Parameters:

  • type (String)

    FHIR resource type (e.g. StructureDefinition)

Returns:

  • (Array<FHIR::Model>)


347
348
349
350
351
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 347

def get_resources_by_type(type)
  @ig_resources.filter do |resource|
    resource.resourceType == type
  end
end

#get_section_entry_data(elements, section_id) ⇒ Array<Hash>

Collects entry elements for a section and builds entry metadata for each.

Parameters:

  • elements (Array<FHIR::Element>)

    Snapshot elements

  • section_id (String)

    Section element id (e.g. Composition.section:sectionProblems)

Returns:



481
482
483
484
485
486
487
488
489
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 481

def get_section_entry_data(elements, section_id)
  entries = elements.filter do |element|
    element.id.include?("#{section_id}.entry")
  end

  entries.map do |entry|
    build_section_entry_data(entry)
  end
end

#get_section_entry_profiles(entry_id, element) ⇒ Array<String>

Resolves Reference type targetProfile URLs to "resourceType|profile" using IG StructureDefinitions.

Parameters:

  • entry_id (String)

    Entry element id (for error messages when profile is missing)

  • element (FHIR::Element)

    Snapshot element with type Reference and targetProfile

Returns:

  • (Array<String>)

    Strings in the form "resourceType|profile" for each target profile

Raises:



514
515
516
517
518
519
520
521
522
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 514

def get_section_entry_profiles(entry_id, element)
  ref_types = element.type&.select { |t| t.code == 'Reference' } || []
  profile_urls = ref_types.flat_map(&:targetProfile).to_a.compact

  profile_urls.map do |profile_url|
    sd = get_structure_definition_by_profile(profile_url, entry_id)
    "#{sd.type}|#{profile_url}"
  end
end

#get_structure_definition_by_profile(profile_url, entry_id = nil) ⇒ FHIR::StructureDefinition

Finds a StructureDefinition in ig_resources whose canonical URL matches the given profile. Matches by URL with or without version (canonical form "url|version").

Parameters:

  • profile_url (String)

    Canonical profile URL (e.g. from Reference.type.targetProfile)

  • entry_id (String, nil) (defaults to: nil)

    Optional entry element id for error context

Returns:

  • (FHIR::StructureDefinition)

Raises:

  • (RuntimeError)

    when no StructureDefinition in ig_resources has this profile URL



370
371
372
373
374
375
376
377
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 370

def get_structure_definition_by_profile(profile_url, entry_id = nil)
  base_url = profile_url.to_s.split('|').first
  sd = find_structure_definition_by_base_url(base_url)
  return sd if sd

  available = structure_definition_urls
  raise profile_not_found_error(profile_url, entry_id, available)
end

#get_structure_definition_by_type(type) ⇒ FHIR::StructureDefinition?

Finds the StructureDefinition for a logical resource type (e.g. Composition, Patient).

Parameters:

  • type (String)

    Logical type (e.g. Composition)

Returns:

  • (FHIR::StructureDefinition, nil)


357
358
359
360
361
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 357

def get_structure_definition_by_type(type)
  get_resources_by_type('StructureDefinition').find do |resource|
    resource.type == type
  end
end

#initiate_buildvoid

This method returns an undefined value.

Generates composition section metadata from IG resources (in-memory only). Populates the internal composition sections and related metadata used by #save_to_file.



79
80
81
82
83
84
85
86
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 79

def initiate_build
  
  extract_required_ms_elements
  extract_optional_ms_elements
  extract_profiles
  extract_resource_filters
  normalize_sections_data
end

#main_profilesArray<FHIR::StructureDefinition>

StructureDefinitions from the IG whose URL is an AU PS profile (http://hl7.org.au/fhir/ps/StructureDefinition/...)

Returns:

  • (Array<FHIR::StructureDefinition>)


200
201
202
203
204
205
206
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 200

def main_profiles
  @ig_resources.filter do |resource|
    next unless resource.resourceType == 'StructureDefinition'

    resource.url.to_s.include?('http://hl7.org.au/fhir/ps/StructureDefinition/')
  end
end

#mandatory_ms_sub_elementsObject



528
529
530
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 528

def mandatory_ms_sub_elements
  @composition_mandatory_ms_sub_elements.map { |element| normalize_path_to_hash(element) }
end

#metadata_to_dumpObject



103
104
105
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 103

def 
  .merge().merge()
end

#normalize_path_to_hash(path) ⇒ Object



524
525
526
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 524

def normalize_path_to_hash(path)
  { expression: path, label: path }
end

#normalize_section_data(section_id) ⇒ Object



135
136
137
138
139
140
141
142
143
144
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 135

def normalize_section_data(section_id)
  section_data = @composition_sections.find { |section| section[:id] == section_id }
  return section_data if section_data.nil?

  {
    'code' => section_data[:code],
    'display' => section_data[:short],
    'resources' => build_section_resources(section_data)
  }
end

#normalize_sections_dataObject



88
89
90
91
92
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 88

def normalize_sections_data
  @normalized_sections_data = @composition_sections.map do |section|
    normalize_section_data(section[:id])
  end
end

#path_is_not_slice?(path) ⇒ Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 215

def path_is_not_slice?(path)
  !composition_mandatory_ms_slices_paths.include?(path) && !composition_optional_ms_slices_paths.include?(path)
end

#profile_not_found_error(profile_url, entry_id, available) ⇒ String

Builds the error message when a profile has no matching StructureDefinition.

Parameters:

  • profile_url (String)

    Requested profile URL

  • entry_id (String, nil)

    Optional entry id for context

  • available (Array<String>)

    List of available StructureDefinition URLs

Returns:

  • (String)

    Error message suitable for RuntimeError



402
403
404
405
406
407
408
409
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 402

def profile_not_found_error(profile_url, entry_id, available)
  context = entry_id ? " (entry: #{entry_id})" : ''
  hint = 'Add JSON via ADDITIONAL_IG_RESOURCES or additional_resources_path.'
  sample = available.join(', ')
  "No StructureDefinition found in IG resources for profile: #{profile_url.inspect}#{context}. " \
    "Ensure the IG includes it or #{hint} " \
    "Available URLs (#{available.size}): #{sample}"
end

#profile_required?(profile) ⇒ Boolean

Returns whether the given AU PS StructureDefinition is required.

Parameters:

  • profile (FHIR::StructureDefinition)

    AU PS StructureDefinition

Returns:



192
193
194
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 192

def profile_required?(profile)
  REQUIRED_PROFILES.include?(profile.url.to_s)
end

#requirements_for_profile(profile) ⇒ Object



169
170
171
172
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 169

def requirements_for_profile(profile)
  filter = @resources_filters.find { |f| f[:resource_profile] == profile }
  filter ? filter[:filters] : []
end

#section_code(section_id, elements) ⇒ String?

Extracts the LOINC (or other) section code from the section's code element.

Parameters:

  • section_id (String)

    Section element id (e.g. Composition.section:sectionProblems)

  • elements (Array<FHIR::Element>)

    All snapshot elements

Returns:

  • (String, nil)

    First coding code from the section's pattern CodeableConcept, or nil if absent



467
468
469
470
471
472
473
474
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 467

def section_code(section_id, elements)
  filtered_element = elements.find do |element|
    element.id == "#{section_id}.code"
  end
  return nil if filtered_element.nil?

  filtered_element.patternCodeableConcept.coding.first.code
end

#structure_definition_urlsArray<String>

Collects all non-empty canonical URLs from StructureDefinitions in the IG.

Returns:

  • (Array<String>)

    Sorted list of URL strings



392
393
394
# File 'lib/au_ps_inferno/generator/metadata_manager.rb', line 392

def structure_definition_urls
  get_resources_by_type('StructureDefinition').map { |r| r.url.to_s }.reject(&:empty?).sort
end