Π•Π‘ΠžΠ— - ΠΏΡƒΠ±Π»Ρ–Ρ‡Π½Π° докумСнтація

RC_[UPD]_Submit Encounter Package

Purpose

Web service "Submit Encounter Package" allows to transmit all the data collected during the encounter into eHealth DB using one single endpoint. I.e. all the data such as conditions, observations, allergy intolerances should be aggregated in one single data package in order to be registered in eHealth.

Β 

Specification

Link

https://medicaleventsmisapi.docs.apiary.io/#reference/medical-events/encounter-data-package/submit-encounter-package

Resource

/api/patients/{{id}}/encounter_package

Scope

encounter:write

Components

Episode of Care

Microservices

API paragraph not found

Protocol type

REST

Request type

POST

Sync/Async

Async

Public/Private/Internal

Public

Β 

Logic

Using this web service you can submit:

Object

Required

Part of Signed content

Object

Required

Part of Signed content

Visit

0-1

false

Encounter

1-1

true

Condition

0-*

true

Observation

0-*

true

Allergy intolerance

0-*

true

Immunization

0-*

true

Risk assessment

0-*

true

Device

0-*

true

Medication statement

0-*

true

Medication administration

0-*

true

Diagnostic report

0-*

true

Procedure

0-*

true

Clinical impression

0-*

true

You can send the same request (with the same body) multiple times, but a new job will not be created before previous is not performed.

Β 

Global and configurable parameters

Variables

Medical Events Dictionaries and configurations | employee_encounter_classes

Medical Events Dictionaries and configurations | employee_encounter_types

Medical Events Dictionaries and configurations | legal_entity_episode_types

Medical Events Dictionaries and configurations | episode_type_encounter_classes

Medical Events Dictionaries and configurations | eHealth/encounter_classes

Medical Events Dictionaries and configurations | encounter_class_encounter_types

Medical Events Dictionaries and configurations | PSYCHIATRY_ICPC2_DIAGNOSES_EVIDENCE_CHECK

Medical Events Dictionaries and configurations | PSYCHIATRY_ICD10_AM_CONDITION_EVIDENCE_ALLOWED

Medical Events Dictionaries and configurations | <system>_ASSISTANT_EMPLOYEE_CONDITIONS_ALLOWED

Medical Events Dictionaries and configurations | <system>_ICD10_AM_MED_COORDINATOR_EMPLOYEE_CONDITIONS_ALLOWED

Medical Events Dictionaries and configurations | ICD10_AM_<SPECIALITY_TYPE>_SPECIALITY_CONDITIONS_ALLOWED

Β 

Dictionaries

Dictionaries_general

Β 

Request structure

See on Apiary

Example:

{ "visit": { "id": "90a9e15b-b71b-4caf-8f2e-ff247e8a5600", "period": { "start": "2018-08-02T10:45:16.000Z", "end": "2018-08-02T10:45:16.000Z" } }, "signed_data": "'ew0KICAicGVyaW9kIjogew0KIC...'" }

Β 

Authorize

  • Verify the validity of access token

    • in case of error - return 401Β ('Invalid access token')

  • Verify that token is not expired

    • in case of error - return 401 ('Invalid access token')

  • Check user scopeΒ encounter:writeΒ in order to perform this action

    • in case of errorΒ generate 403 response ('Invalid scopes')

  • IfΒ BLOCK_UNVERIFIED_PARTY_USERS is true, then check party's data match following condition: verification_status != NOT_VERIFIED or (verification_status = NOT_VERIFIED and updated_at <= current_date - UNVERIFIED_PARTY_PERIOD_DAYS_ALLOWED):

    • in case not match - return 403 ("Access denied. Party is not verified")

Β 

Headers

  • Content-Type:application/json

  • Authorization:Bearer {{access_token}}

  • API-key:{{secret}}

Β 

Request data validation

Note: No update operations are allowed. All IDs, submitted as PK, should be unique for eHealth.Β 

  1. Validate patient status

    1. db.patients.status for this patient must "active"

      1. in case of error return 409 - "Patient is not active"

  2. Validate request according to JSON Schema

    1. Return 422 with list of validation errors in case validation failsΒ 

  3. Validate Visit

    1. $.visit.id is unique

      1. in case of error return 422 - "Visit with such id already exists"

    2. $.visit.period.start <= current_dateTime

      1. in case of error return 422- "Start date must be in past"

    3. $.visit.period.end <= current_dateTime

      1. in case of error return 422- "End date must be in past"

    4. $.visit.period.end > visit.period.start

      1. in case of error return 422 - "End date must be greater than the start date"

  4. Validate DS

    1. Validate thatΒ  DS belongs to the performer of encounter

      1. validate that drfo from DS and party.drfo of performer matches

    2. Validate that performer of encounter is a current userΒ 

      1. validate that one of users employee is a performer of encouner

      2. validate that client_id from token == PRM.performer.legal_entity

  5. Validate encoded signed content according to JSON Schema

    1. Return 422 with list of validation errors in case validation fails

Validate Legal Entity Type

Validate legal entity from token: legal_entities.type should be in me_allowed_transactions_le_types andΒ legal_entities.status =='active'Β 

Validate Encounter

Global validations

  1. Validate encounter id as a primary key

  2. Validate that the date is within acceptable limits

    1. $.encounter.date<= current_date

    2. $.encounter.date>=current_date-encounter_max_days_passed

    3. $.encounter.date>=episode.period.start where episode.id=$encounter.episode.identifier.value

      1. in case of error return 422 "Encounter’s date must be equal to or greater than start date ofΒ episode"

  3. Validate that the period is within acceptable limits

    1. $.encounter.period.start<= current_date

      1. in case of error return 422 "Date must be in past"

    2. $.encounter.period.start>=current_date-encounter_max_days_passed

      1. in case of error return 422 "Date must be greater than {{current_date-encounter_max_days_passed}}"

    3. $.encounter.period.start>=episode.period.start where episode.id=$encounter.episode.identifier.value

      1. in case of error return 422 "Encounter’s date must be equal to or greater than start date ofΒ episode"

    4. $.encounter.period.end>=Β $.encounter.period.start

      1. in case of error return 422 "End date must be greater than start date"

  4. Validate "episode" is an active episode that belongs to the current patient

    1. $.encounter.episode.identifier.valueΒ is one ofΒ  ME.patinet{patient_id}.episodes{*}.id

      1. in case of error return 422 "Episode with such ID is not found"

    2. $.encounter.episode.identifier.value is an ID of an Episode that meets the requirements:

      1. ME.patient{patinet_id}.episodes{episode_id}.status = 'active'

        1. in case of error return 422 "Episode is not active"

      2. ME.patient{patinet_id}.episodes{episode_id}.managing_organization==token.client_id

        1. in case of error return 422 "Managing_organization in the episode does not correspond to user`s legal_entity"

  5. Validate "visit" is a visit that belongs to the current patient

    1. $.encounter.visit.identifier.value=$.visit.idΒ  ORΒ Β ID of already existing Visit in ME.patient{patient_id}.visit.id

      1. in case of error return 422 "Visit with such ID is not found"

  6. Validate referrals

    1. As a referral it can be referenced electronic (registered in the system) OR paper service request

    2. Validate ($.encounter.incoming_referrals OR $.encounter.paper_referral) or none in request

    3. Validate incoming referrals asΒ  References

    4. Validate paper referral as Object (paper_referral)

    5. Validate incoming referrals that corresponds toΒ $.encounter.incoming_referrals[*].identifier.value have:

      1. ..used_by_legal_entity.identifier.value==token.client_id OR null

        1. in case of error return 409 "Service request is used by another legal_entity"

      2. ..status==active orΒ program_processing_status=in_progress (any status is valid in caseΒ program_processing_status=Β in_progress)

        1. in case of error return 409 "Invalid service request status"

      3. ..if program is defined program_processing_status=new, in_queue or in_progress

      4. check thatΒ service_requestΒ contains based_on parameter

        1. in caseΒ based_onΒ present inΒ service_request

          1. verifyΒ care_plan:

            1. It should be inΒ activeΒ status

            2. Care plan's periodΒ endΒ (if exist) should be greater than current date or equal.

          2. verifyΒ activity:

            1. It has activity.detail.kind=service_request; activity.detail.product_reference=service_id.Β 

            2. It hasΒ scheduled, in_progressΒ status

        2. in caseΒ based_onΒ not present in request skip previous validations.

      5. Check if service request quantity is not exhausted as described at Submit Encounter Package | Related service request validation

  7. Validate performer

    1. $.encounter.performer.identifier.value is an ID of existing employee in PRM.Employees

      1. in case of error return "There is no Employee with such id"

    2. $.encounter.performer.identifier.valueΒ  ==Β PRM.Employees.id where (PRM.Employees.status==`active`)

      1. in case of error returnΒ "Employee is not active"

    3. $.encounter.performer.identifier.valueΒ  ==Β PRM.Employees.idΒ where (PRM.Employees.legal_entity== client_id)

      1. "User can not create encounter for this legal_entity"

    4. validate employee type according to encounter.classΒ - use config fileΒ (employee_encounter_classes)

      1. in case error return 422, "Employee.type $type is forbidden for your encounter class"

    5. according toΒ employee.typeΒ as stated inΒ employee_encounter_types

      1. in case error returnΒ 422, msgΒ "Employee.type $type is forbidden for your encounter type"

  8. division

    1. $.encounter.division.identifier.valueΒ must meet the following requirements

      1. PRM.division.status = "ACTIVE"

        1. in case of error return 409 "Division is not active "Β 

      2. PRM.division.legal_entity=Β token.client_id

        1. in case of error return 409 "User is not allowed to create encouners for this division"

  9. Validate supporting_info asΒ References

  10. Validate encounter.classΒ Β 

    1. according toΒ legal_entity.type - use config fileΒ (legal_entity_episode_types)

      1. in case error return 409, msg "Encounter.class $class is forbidden for your legal entity type"

    2. according to episode.type - use config file (episode_type_encounter_classes)

      1. in case error returnΒ 409, msg "Encounter.class $class is forbidden for your episode type"

    3. according toΒ employee.typeΒ as stated inΒ encounter class validations

      1. in case error returnΒ 409, msg "Encounter.class $class is forbidden for your employee type"

  11. ValidateΒ encounter.typeΒ according to encounter.class - use config file encounter_class_encounter_types

    1. in case error return 409, msg "Encounter.type $type is forbidden for your encounter class"

  12. Validate actionsΒ 

    1. Validate actions presence according toΒ Β encounter class validations

      1. in case error return '422', msgΒ 'TBC'

    2. Defined in the system that corresponds toΒ Β encounter class validations

      1. in case error return '422', msgΒ 'TBC'

  13. Validate action_referencesΒ 
    Note.Β For encounter.action_referencesΒ pass onlyΒ "service",Β and the "service_group" does not pass

    1. Validate action_references presence according toΒ Β encounter class validations

      1. in case error return '422', msgΒ 'At least one of action references, diagnostic reports or procedures should exist in encounter package'

    2. Validate code as aΒ Reference

    3. Validate action_referencesΒ is in prm.services, has status ACTIVE and is_active = true

      1. in case error return '422', msgΒ 'Service with such ID is not found'

      2. in case error return '422', msgΒ 'Service should be active'

      3. Validate that action_referencesΒ is service with service.category==”counselling” in case encounter.class=”AMB”

        1. in case error return β€˜422', msgΒ 'Invalid service category for AMB encounter class'

  14. Β ValidateΒ diagnosesΒ 

    1. Validate conditions asΒ  References

    2. Validate that encounter type= 'intervention'. If not, than:

      1. Validate encounter has exactly one diagnosis whereΒ $.encounter.diagnoses[?(@.role.coding[0].code=="primary")]

      2. in case of error return 422 "Encounter must have exactly one primary diagnosis"

    3. Validate http://condition.id is in DB or in current Encounter packageΒ 

    4. Validate that each condition is active (verification_status != entered_in_error)

      1. in case of error return 409 "Conditions in diagnoses must be active"

    5. ValidateΒ that primaryΒ diagnosis defined in the system that corresponds toΒ Β encounter class validations

      1. in case of errorΒ "Primary diagnosis should be defined in {$.encounter.diagnoses[*].role.coding[*].systemΒ } system"

    6. Validate that rank

      1. Rank value should be integer and >= 1

        1. in case of error return 422 "expected the value to be >= 1"

      2. Rank value should be integer and <= 10

        1. in case of error return 422 "expected the value to be <= 10"

  15. Validate reasons

    1. Validate reasons presence according toΒ encounter class validations

      1. in case error return 422, msgΒ 'Validation failed. You can find validators description at our API Manifest: Nebo #15 API Manifest Β· Apiary .', description 'can't be blank.

  16. ValidateΒ hospitalizationΒ 

    1. ValidateΒ hospitalizationΒ presence according toΒ Β encounter class validations

      1. in case error return 422, msg "Hospitalization block is forbidden for encounter.class = $encounter.class"Β 

    2. Validate all fields according to schemata

      1. destination

      2. discharge_disposition

      3. pre_admission_identifier

      4. admit_source

      5. re_admission

      6. discharge_department

    3. If encounter.type.code = "discharge" than encounter.hospitalization.admit_source is required, encounter.hospitalization.discharge_disposition is required, encounter.hospitalization.discharge_department is required

      1. in case error return 422, msg "<parameter> is required for encounter.type.code = "discharge"

    4. ValidateΒ destination is a valid legal_entity in prm with status is ACTIVE and is_active = true

      1. in case error return 422, "Legal entity is not active"

  17. Β Validate patient_id for encounter.type == "patient_identity"

    1. $patient_id should exist inΒ mpi.prepersons.id, have status =='ACTIVE' and is_active = true

      1. in case error return 'TBC', msgΒ 'TBC'

  18. IfΒ incoming referralsΒ exists and incoming_referral (service request) category not in ('transfer_of_care', 'hospitalization') and encounter.class in ("AMB", "INPATIENT") and encounter.type <> Β "patient_identity"Β validate service for encounter.actions OR diagnostic_report.code OR procedure.code

    1. IfΒ service_requests.code.identifier.value is service, validate $resourse.code.identifier.value = service_requests.code.identifier.value

      1. in case error return 409, "Service in $resourseΒ differ from service in service request"

    2. ifΒ service_requests.code.identifier.value is service_group, validate $resourse.code.identifier.value in (SELECT service_id from service_inclusions where service_group_id='service_requests.code.identifier.value')

      1. in case error return 409, "Service inΒ $resourse differ from services in service request's service_group"

    3. Validate $resourse.service.is_active = true

      1. in case error return 409, "Service should be active"

  19. Validate patient verification status:

    1. If encounter has incoming referral with valid and active service request, then skip this validation.

    2. Else check patient'sΒ verification_status is not equal to NOT_VERIFIED.

      1. in case of error return 409, "Patient is not verified"

  20. Validate priority

    1. Validate priority presence according to eHealth/encounter_priority

      1. in case error return 409, ""

    2. If encounter.class.code = "INPATIENT", priority is required

      1. in case error return 422, "Priority for encounter is required"

Validations for encounter classes

Β 

Important

This validations is applicable for all encounter types except covid. Specific validations for covid encounter type described in separate page

Encounter class validations

Validation

PHC

AMB

INPATIENT

Validation

PHC

AMB

INPATIENT

employees.type

as stated in config file employee_encounter_types

as stated in config file employee_encounter_types

as stated in config file employee_encounter_types

encounter.type

as stated in config file encounter_class_encounter_types

as stated in config file encounter_class_encounter_types

as stated in config file encounter_class_encounter_types

actions

  • at least one required

  • is in dictionaryΒ eHealth/ICPC2/actions

is absent in request

is absent in request

diagnoses

diagnoses.primary is a condition with codeΒ in dictionary "eHealth/ICPC2/condition_codes"

diagnoses.primary is a condition with codeΒ in dictionary "eHealth/ICD10_AM/condition_codes"

diagnoses.primary is a condition with codeΒ in dictionary "eHealth/ICD10_AM/condition_codes"

reasons

  • at least one required

  • is in dictionaryΒ eHealth/ICPC2/reasons

  • optional (if passed - must be in dictionaryΒ eHealth/ICPC2/reasons)

  • optional (if passed - must be in dictionaryΒ eHealth/ICPC2/reasons)

hospitalisation

is absent in request

is absent in request

if encounter.type == "discharge" - this block is mandatory

  • discharge_disposition is mandatory

  • discharge_department is mandatory

For other encounter types

  • optional

action_references

is absent in request

if encounter.type == "patient_identity"Β 

  • no validations

For other encounter types

  • one of mustΒ exist:

    1. action_references in encounter

    2. OR diagnostic report in package

    3. OR procedure in package

if encounter.type == "patient_identity"Β 

  • no validations

For other encounter types

  • one of mustΒ exist:

    1. action_references (service.category=counselling) in encounter

    2. OR diagnostic report in package

    3. OR procedure in package

division

Β 

Β 

Division must be filled

Validate Conditions

  1. Validate conditions ids asΒ  primary keys

  2. Validate that context of conditions is a current encounter

    1. $.conditions[*].context.identifier.value == $.encounter.id

      1. in case of error return "Submitted context is not allowed for the condition"

  3. Validate code depending on encounter class

    1. if $.encounter.class = PHC - allowed bothΒ eHealth/ICPC2/condition_codes andΒ eHealth/ICD10_AM/condition_codes

    2. if $.encounter.class in (AMB, INPATIENT) - allowed onlyΒ eHealth/ICD10_AM/condition_codes

  4. Validate code.codingΒ depending on the qty of codes

    1. Maximum one code from one dictionary (eHealth/ICPC2/condition_codes andΒ eHealth/ICD10_AM/condition_codes) is allowed

      1. in case of error return 422 with msgΒ "Only one code from one dictionary is allowed"

  5. Validate that the date is within acceptable limits

    1. $.conditions[*].onset_date <= current_date

      1. in case of error "Onset date must be in past"

    2. $.condition[*].onset_date>=current_date-condition_max_days_passed

      1. in case of error "Onset date must be greater thanΒ  {{current_date-condition_max_days_passed}}"

  6. $.conditions[*].onset_date <= current_date

    1. in case of error "Onset date must be in past"

  7. $.conditions[*].asserted_date <= current_date

    1. in case of error "Asserted date must be in past"

  8. $.conditions[*].evidences[*].detail[*].identifier.value is an ID of existing observation in MedicalEvents.Observations or one of $.observations[*]
    ORΒ $.conditions[*].evidences[*].detail[*].identifier.value is an ID of existing condition in MedicalEvents.Conditions

    1. in case of error 422Β "<medical_event> with such id is not found

  9. $.conditions[*].evidences[*].detail[*].identifier.valueΒ meet follownig conditions

    1. MedicalEvents.Observation.Patient == patient_id (from url)

      1. Error 409 "Evidence can not reference another patient"

    2. MedicalEvents.Observation.StatusΒ != "entered_in_error"

      1. Error 409 "Observation inΒ "entered_in_error" status can not be used as an evidence"

  10. ValidateΒ $.conditions[*].evidences[*].detail[*].identifier.value
    for eachΒ $.conditions[*].evidences
    check:

    1. MedicalEvents.<MedicalEvent>.Patient == patient_id (from url)

      • Error 422 "<medical_event> with such id is not found"

    2. MedicalEvents.<MedicalEvent>.StatusΒ != "entered_in_error"

      • Error 422 "<medical_event> inΒ "entered_in_error" status can not be used as an evidence"

    3. in case ifΒ PSYCHIATRY_ICPC2_DIAGNOSES_EVIDENCE_CHECKΒ chart parameterΒ containsΒ $.conditions[*].code.coding.code
      check if at least one item from $.conditions[*].evidencesΒ meets requirements:Β 

      1. check if $.conditions[*].evidences[*].detail[*].identifier.type.coding.code == "condition"Β 

        • Error 422 "Condition must be entered as an evidence to set condition code <$.conditions[*].code.coding.code>"

      2. MedicalEvents.Condition.Code.CodingΒ array contains at least one of codes fromΒ PSYCHIATRY_ICD10_AM_CONDITION_EVIDENCE_ALLOWEDΒ chart parameter.

        • Error 422 "Condition can not be used as an evidence to set condition code <$.conditions[*].code.coding.code>"

  11. Validate asserter.

    1. $.conditions.asserter.identifier.value is an ID of one of users employeeΒ 

      1. in case of error return "Employee is not performer of encounter"

    2. according to logicΒ Submit Encounter Data Package#Performer(asserter)validation

      1. check if asserter's employee_type == "ASSISTANT" then define allowed conditions from ASSISTANT_EMPLOYEE_CONDITIONS_ALLOWED

        in case condition code is not allowed for the employee_type - return 409 error ('Asserter has no required employee type to set condition code <code>')

      2. checkΒ if asserter's employee_type == "MED_COORDINATOR" then define allowedΒ conditions fromΒ ICD10_AM_MED_COORDINATOR_EMPLOYEE_CONDITIONS_ALLOWED

        1. in caseΒ condition code isΒ not allowed for theΒ employee_typeΒ - return 409 error ('Asserter has no required employee type to set condition code <code>')

  12. Validate primary_source:

    • if primary_source = true and code hasΒ eHealth/ICD10_AM/condition_codesΒ dictionary value:

      • define allowed specialities for ICD10_AM condition code using a set of chart variablesΒ ICD10_AM_<SPECIALITY_TYPE>_SPECIALITY_CONDITIONS_ALLOWED

      • check if asserter's speciality in allowed specialities defined on previous step

        • in case speciality not allowed for the condition code - return 409 error ('Asserter has no required speciality to set condition code <code>')

    • if primary_source = false - skip this check

Validate Observations

Several approaches are used for validating observations. This is driven by the natural growth of the system, which implies increased complexity and the different requirements for various groups, categories of observations and even the contexts in which they (observations) were created.

Currently, the following approaches are used:

  1. Basic validations for all observations

  2. Validation of observations for the encounter type "patient_identity".

  3. A set of validations for rehabilitation observations based on ICF (International Classification of Functioning, Disability, and Health) dictionaries.

  4. Validation of observations based on a configuration set defined for a specific observation code (new).

Basic validation and REHAB

  1. Validate observations ids asΒ  primary keys

  2. Validate that context of observation is a current encounter

    1. $.observations[*].context.identifier.value==$.encounter.id

      1. in case of error return "Submitted context is not allowed for the observation"

  3. Validate that the date is within acceptable limits

    1. $.observations[*].issued <= current_time

      1. in case of error return "Issued date must be in past"

    2. $.observations[*].issued>=current_date-observation_max_days_passed

      1. in case of error "Issued must be greater thanΒ  {{current_date-observation_max_days_passed}}"

  4. Validate performer(asserter)

  5. Validate $.observations[*].components

    1. Β if $.observations[*].code.coding[*].system is "eHealth/ICF/classifiers":

      1. Check number of component items withΒ $.observations[*].components[*].code.coding[*].system =Β "eHealth/ICF/qualifiers":Β 

        1. ifΒ $.observations[*].code.coding[*].codeΒ starts from "b" letter, thenΒ components must contain exact 1 item with:

          1. $.observations[*].components[*].code.coding[*].code = "extent_or_magnitude_of_impairment"Β 

            1. in case of missing qualifier - return 422 "Missing components with qualifiers <list of missing qualifiers>"

            2. in case of incorrect number of qualifiers - return 422 "Required 1 component, but got <number of items>"

            3. in case value is not active in dictionary - return 422 "Value is not active"

        2. if $.observations[*].code.coding[*].codeΒ starts from "s" letter, thenΒ components must contain exactΒ 3 items with:

          1. $.observations[*].components[*].code.coding[*].code = "extent_or_magnitude_of_impairment"

          2. $.observations[*].components[*].code.coding[*].code = "nature_of_change_in_body_structure"

          3. $.observations[*].components[*].code.coding[*].code = "anatomical_localization"

            1. in case of missing qualifier - returnΒ 422 "Missing components with qualifiers <list of missing qualifiers>"

            2. in case of incorrect number of qualifiers - return 422 "Required 3 components, but got <number of items>"

            3. in case value is not active in dictionary - return 422 "Value is not active"

        3. if $.observations[*].code.coding[*].codeΒ starts from "d" letter, thenΒ components must contain exactΒ 2 items with:

          1. $.observations[*].components[*].code.coding[*].code = "performance"

          2. $.observations[*].components[*].code.coding[*].code = "capacity"

            1. in case of missing qualifier - returnΒ 422 "Missing components with qualifiers <list of missing qualifiers>"

            2. in case of incorrect number of qualifiers - return 422 "Required 2 components, but got <number of items>"

            3. in case value is not active in dictionary - return 422 "Value is not active"

        4. if $.observations[*].code.coding[*].codeΒ starts from "e" letter, thenΒ components must contain exactΒ 1 item with:

          1. $.observations[*].components[*].code.coding[*].code = "barrier_or_facilitator"

            1. in case of missing qualifier - returnΒ 422 "Missing components with qualifiers <list of missing qualifiers>"

            2. in case of incorrect number of qualifiers - return 422 "Required 1 component, but got <number of items>"

            3. in case value is not active in dictionary - return 422 "Value is not active"

      2. CheckΒ $.observations[*].components[*].value_codeable_conceptΒ is present in each item withΒ $.observations[*].components[*].code.coding[*].system =Β "eHealth/ICF/qualifiers" andΒ Β $.observations[*].components[*].value_codeable_concept.coding[*].system corresponds toΒ $.observations[*].components[*].code.coding[*].code

        1. in case not present or doesn't correspond -Β  return 422 "Doesn't correspond to $.observations[i].components[i].code"

          • in case code value is not active in dictionary - return 422 "Value is not active"

  6. if observations[*].categories[0].coding[0].system == "eHealth/ICF/observation_categories" - skip validation of observations[*].value and make this fields optional

    1. else - check that one off this fields present:

      1. Validate$.observations[*].value_periodΒ as aΒ Period

    2. ValidateΒ $.observations[*].value_quantity

      1. $.observations[*].value must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      2. $.observations[*].comparatorΒ can take the following values :Β [">", ">=", "=", "<=", "<"]

        1. in case of error return "value is not allowed in enum"

      3. $.observations[*].unit can take values from dictionaryΒ eHealth/ucum/unitsΒ 

        1. in case of error return "value is not allowed in enum"

    3. ValidateΒ $.observations[*].value_codeable_concept

      1. $.observations[*].code validate that the code belongs to the dictionary system

        1. in case of error return "Value is not allowed in enum"

    4. ValidateΒ $.observations[*].value_boolean

      1. $.observations[*].value_booleanΒ must be boolean type

        1. in case of error return "type mismatch. ExpectedΒ boolean but got {entered type}"

    5. ValidateΒ $.observations[*].value_string

      1. $.observations[*].value_stringΒ must be string type

        1. in case of error return "type mismatch. ExpectedΒ string but got {entered type}"

    6. ValidateΒ $.observations[*].value_sampled_data

      1. $.observations[*].dataΒ must be string type

        1. in case of error return "type mismatch. ExpectedΒ string but got {entered type}"

      2. $.observations[*].origin must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      3. $.observations[*].period must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      4. $.observations[*].factor must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      5. $.observations[*].lower_limit must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      6. $.observations[*].upper_limit must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

      7. $.observations[*].dimensions must be with number type

        1. in case of error return "type mismatch. Expected number but got {entered type}"

    7. ValidateΒ $.observations[*].value_range

      1. $.observations[*].low must be with object type

        1. in case of error return "type mismatch. Expected object but got {entered type}"

      2. $.observations[*].high must be with object type

        1. in case of error return "type mismatch. Expected object but got {entered type}"

    8. ValidateΒ $.observations[*].value_ratio

      1. $.observations[*].numerator must be with object type

        1. in case of error return "type mismatch. Expected object but got {entered type}"

      2. $.observations[*].denominator must be with object type

        1. in case of error return "type mismatch. Expected object but got {entered type}"

    9. ValidateΒ $.observations[*].value_time

      1. $.observations[*].value_timeΒ must be with string type

        1. in case of error return "type mismatch. Expected string but got {entered type}"

    10. ValidateΒ $.observations[*].value_date_time

      1. $.observations[*].value_date_timeΒ must be with string type

        1. in case of error return "type mismatch. Expected string but got {entered type}"

  7. ValidateΒ $.observations[*].value_boolean

    1. $.observations[*].value_booleanΒ must be boolean type

      1. in case of error return "type mismatch. ExpectedΒ boolean but got {entered type}"

  8. ValidateΒ $.observations[*].value_string

    1. $.observations[*].value_stringΒ must be string type

      1. in case of error return "type mismatch. ExpectedΒ string but got {entered type}"

  9. ValidateΒ $.observations[*].value_sampled_data

    1. $.observations[*].dataΒ must be string type

      1. in case of error return "type mismatch. ExpectedΒ string but got {entered type}"

    2. $.observations[*].origin must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

    3. $.observations[*].period must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

    4. $.observations[*].factor must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

    5. $.observations[*].lower_limit must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

    6. $.observations[*].upper_limit must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

    7. $.observations[*].dimensions must be with number type

      1. in case of error return "type mismatch. Expected number but got {entered type}"

  10. ValidateΒ $.observations[*].value_range

    1. $.observations[*].low must be with object type

      1. in case of error return "type mismatch. Expected object but got {entered type}"

    2. if observations[*].code.coding[*].system is "eHealth/ICF/classifiers", then:

      1. CheckΒ observations[*].categories[*].coding[*].system should contain "eHealth/ICF/observation_categories"

        1. in case of error return 422 β€œCode doesn't match observation categoryβ€œ

      2. CheckΒ observations[*].components are presented

        1. in case of error return 422 β€œComponents requiredβ€œ

    3. Validate $.observations.code.coding[*].code is active in corresponding dictionary

      1. in case of error return 409, β€œValue is not active”

  11. ValidateΒ $.observations[*].value_ratio

    1. $.observations[*].numerator must be with object type

      1. in case of error return "type mismatch. Expected object but got {entered type}"

    2. $.observations[*].categories[*].coding[*].system is "eHealth/observation_categories" or "eHealth/ICF/observation_categories"Β 

      1. in case of error return 422 "Value is not allowed in enum"

    3. $.observations[*].categories[*].coding[*].code corresponds to the system

      1. in case of error return 422 "Value is not allowed in enum"

    4. Validate $.observations.categories[*].coding[*].code is active in corresponding dictionary

      1. in case of error return 409, β€œValue is not active”

    5. If $.observations[*].categories[*].coding[*].system = "eHealth/ICF/observation_categories",Β then $.observations[*].code should be filled from "eHealth/ICF/classifiers" dictionary.

      1. in case of error return 422 β€œCode doesn't match observation categoryβ€œ

  12. ValidateΒ $.observations[*].value_time

    1. $.observations[*].value_timeΒ must be with string type

      1. in case of error return "type mismatch. Expected string but got {entered type}"

  13. ValidateΒ $.observations[*].value_date_time

    1. $.observations[*].value_date_timeΒ must be with string type

      1. in case of error return "type mismatch. Expected string but got {entered type}"

  14. Validate diagnostic report is one of reports in the current package

    1. $.observations[*].diagnostic_report.identifier.value == one of $.diagnostic_report[*].identifier.value

      1. in case of error "Invalid reference"

  15. Validate $.observations[*].reaction_on

    1. check that the appropriate immunizations.status != "entered_in_error"

      1. in case of error return 409 "Immunization with status β€˜entered_in_error’ can not be use"

  16. Validate $.observations.code

    1. if observations.code.coding[*].codeΒ value is included in chart variablesΒ 'OBSERVATION_CODES_WITH_<VALUE_TYPE>_REQUIRED', <value_type> field is mandatory

      1. Β in case of error return 422 β€œThis field is required for code = <code>β€œ

  17. Validate specimen,Β if submitted:

    1. Check the fieldΒ is aΒ ReferenceΒ on a specimen resource

      1. in case of error return 422 β€œnot allowed in enum”

    2. Check it exists in DB or within current package, and belongs to the sameΒ patient:

      1. in case of error return 422 "Specimen not found"

    3. Check status:

      1. is available if the specimen was found in the DB

        1. in case of error return 422 "Specimen created beforeΒ the current package should be available"

      2. is unavailableΒ if the specimen not found in the DB, but in the package

        1. in case of error return 422 "Specimen created in the current package should be unavailable"

Validate observations for encounter.type == "patient_identity"Β 

  1. EDP with type == "patient_identity" should have list of special observations.Β 

  2. Such list can contain limited set of codes, some of them are mandatory

code

M/O

code

M/O

height

M

weight

M

sex

M

stature

O

eye_colour

O

hair_ color

O

hair_length

O

beard

O

mustache

O

clothes

O

peculiarity

O

Validate observations using configuration set

This validations must be done on top of Basic validations and only in case there is defined configuration set for such observation

Search for active configuration set (is_active = true) using observation code (code + system) and perform additional validation. If there is no configuration for such code then this additional validations must be skipped

Category

  1. Check that observation.categories.coding.system and observation.categories.coding.code matches with one of the options in CATEGORY configuration parameter

    1. values in CATEGORY.check means all allowed and observation category must match at least one

    2. If CATEGORY is missing or is empty then skip this validation

    3. in case of error return 422 β€œCategory is not allowed for this observation codeβ€œ

Components

  1. Check that all components in observation.components are unique and not duplicated if COMPONENTS_UNIQUE is set to true. Otherwise skip this step

    1. in case of error return 422 β€œObservation components must be uniqueβ€œ

  2. Check that all required components are present in observation.components (declared in COMPONENTS_REQUIRED)

    1. values in COMPONENTS_REQUIRED.check means all required and observation components must include all of them

    2. if COMPONENTS_REQUIRED is missing or is empty then skip this validation

    3. in case of error return 422 β€œNot all required components provided for this observation codeβ€œ

  3. Check that there are no items in observation.components other than those allowed, which are defined by the COMPONENTS_ALLOWED

    1. values in COMPONENTS_ALLOWED.check means all allowed (except COMPONENTS_REQUIRED) observation components that could be used for this observation code

    2. if COMPONENTS_ALLOWED.check is empty then no additional components are allowed

    3. if COMPONENTS_ALLOWED is missing then skip this validation

    4. in case of error return 422 β€œComponent code is not allowed for this observation codeβ€œ

  4. Check that component value type matches with COMPONENTS_TYPE configuration parameter

    1. search for related configuration in COMPONENTS_TYPE.condition using observation.component.code.coding.system and observation.component.code.coding.code

    2. check that observation.component.value[x] type matches with the type declared in COMPONENTS_TYPE.check

    3. if COMPONENTS_TYPE is missing or is empty or there is no matched configuration then skip this validation

    4. in case of error return 422 β€œtype mismatch. ExpectedΒ {COMPONENTS_TYPE.check} but got {entered type}β€œ

  5. Check that dictionary used to represent component with value type codeable_concept matches with declared in COMPONENTS_BINDING configuration parameter

    1. Must be done only in case when component value type is codeable_concept (observation.component.value[x] type is codeable_concept)

    2. search for related configuration in COMPONENTS_BINDING.condition using observation.component.code.coding.system and observation.component.code.coding.code

    3. check that observation.component.value_codeable_concept.coding.system matches with the system (dictionary) declared in COMPONENTS_BINDING.check

    4. if COMPONENTS_BINDING is missing or is empty or there is no matched configuration then skip this validation

    5. in case of error return 422 β€œIncorrect dictionary. ExpectedΒ {COMPONENTS_TYPE.check}β€œ

  6. Check that code system and value used to represent quantity in component are allowed according to COMPONENTS_QUANTITY_CODES configuration parameter

    1. Must be done only in case when component value type is quantity (observation.component.value[x] type is quantity)

    2. search for related configuration in COMPONENTS_QUANTITY_CODES.condition using observation.component.code.coding.system and observation.component.code.coding.code

    3. check that observation.component.value_quantity.coding.system and observation.component.value_quantity.coding.code matches respectively with one of configurations in COMPONENTS_QUANTITY_CODES.check

    4. if COMPONENTS_QUANTITY_CODES is missing or is empty or there is no matched configuration then skip this validation

    5. in case of error return 422 β€œSuch quantity system and quantity code are not allowed in this componentβ€œ

  7. Check that component value is within the declared in COMPONENTS_QUANTITY_BOUNDARIES configuration parameter boundaries

    1. Must be done only in case when component value type is quantity (observation.component.value[x] type is quantity)

    2. search for related configuration in COMPONENTS_QUANTITY_BOUNDARIES.condition using (observation.component.code.coding.system and observation.component.code.coding.code for COMPONENTS_QUANTITY_BOUNDARIES.condition.component_code) and (observation.component.value_quantity.system and observation.component.value_quantity.code for COMPONENTS_QUANTITY_BOUNDARIES.condition.quantity_code)

    3. check that configuration.check.min <= observation.component.value_quantity.value >= configuration.check.max

    4. if COMPONENTS_QUANTITY_BOUNDARIES is missing or is empty or there is no matched configuration then skip this validation

    5. in case of error return 422 β€œIncorrect value. Expected value to be in rangeΒ {configuration.check.min} and {configuration.check.max}β€œ

  8. Check that only allowed extensions are used in components (declared in COMPONENTS_ALLOWED_EXTENSIONS)

    1. values not declared in COMPONENTS_ALLOWED_EXTENSIONS.check is prohibited and is not allowed in observation.components

    2. if COMPONENTS_ALLOWED_EXTENSIONS.check is empty then no extension allowed

    3. if COMPONENTS_ALLOWED_EXTENSIONS is missing then no extension allowed

    4. check that observation.component.value_codeable_concept.coding.extension contains only extensions declared in COMPONENTS_ALLOWED_EXTENSIONS.check

      1. in case of error return 422 β€œExtension {observation.component.value_codeable_concept.coding.extension} is not allowedβ€œ

    5. check that there are no duplicated extensions in observation.component.value_codeable_concept.coding.extension

      1. in case of error return 422 β€œDuplicated extensionβ€œ

    6. check that extension is valid according to https://e-health-ua.atlassian.net/wiki/spaces/REHABILIT/pages/18431246564/UPD+Medical+Events+MongoDB+Data+Model#Predefined-extensions

      1. in case of error return 422 β€œInvalid extensionβ€œ

  9. Check that extension value is correct according to COMPONENT_SCORE configuration parameter

    1. Must be done only in case when component value type is codeable_concept (observation.component.value[x] type is codeable_concept)

    2. search for the score associated with provided value (declared in COMPONENT_SCORE configuration parameter) using component value (observation.component.value_codeable_concept.coding.system and observation.component.value_codeable_concept.coding.code) and component code (observation.component.code.coding.system and observation.component.code.coding.code).

    3. check that extension value (observation.component.value_codeable_concept.coding.extension(code = item_weight).value_decimal) is equal value declared in COMPONENT_SCORE.check for such component

    4. in case of error return 422 β€œIncorrect component scoreβ€œ

Value

  1. Check that observation value type matches with RESULT_TYPE configuration parameter

    1. check that observation.value[x] type matches with the type declared in RESULT_TYPE.check

    2. if RESULT_TYPE is missing or is empty then skip this validation

    3. in case of error return 422 β€œtype mismatch. ExpectedΒ {RESULT_TYPE.check} but got {entered type}β€œ

  2. Check that dictionary used to represent observation value matches with declared in RESULT_BINDING configuration parameter

    1. Must be done only in case when observation value type is codeable_concept (observation.value[x] type is codeable_concept)

    2. check that observation.value_codeable_concept.coding.system matches with the system (dictionary) declared in RESULT_BINDING.check

    3. if RESULT_BINDING is missing or is empty then skip this validation

    4. in case of error return 422 β€œIncorrect dictionary. ExpectedΒ {RESULT_BINDING.check}β€œ

  3. Check that code system and value used to represent quantity in observation are allowed according to RESULT_QUANTITY_CODES configuration parameter

    1. Must be done only in case when component value type is quantity (observation.value[x] type is quantity)

    2. check that observation.value_quantity.coding.system and observation.value_quantity.coding.code matches respectively with one of configurations in RESULT_QUANTITY_CODES.check

    3. if RESULT_QUANTITY_CODES is missing or is empty or there is no matched configuration then skip this validation

    4. in case of error return 422 β€œSuch quantity system and quantity code are not allowed in observation resultβ€œ

  4. Check that observation value is within the declared in RESULT_BOUNDARIES configuration parameter boundaries

    1. Must be done only in case when observation value type is quantity (observation.value[x] type is quantity)

    2. search for related configuration in RESULT_BOUNDARIES.condition using observation.value_quantity.coding.system and observation.value_quantity.coding.code

    3. check that configuration.check.min <= observation.value_quantity.value >= configuration.check.max

    4. if RESULT_BOUNDARIES is missing or is empty or there is no matched configuration then skip this validation

    5. in case of error return 422 β€œIncorrect value. Expected value to be in rangeΒ {RESULT_BOUNDARIES.check.min} and {RESULT_BOUNDARIES.check.max}β€œ

  5. Check that observation value calculated correctly according to the method declared in RESULT_SCORE_CALCULATION configuration parameter

    1. There are different supported methods to calculate and control result (β€œSUM”)

    2. If `SUM` specified

      1. go through all observation.components

      2. sum all scores provided in item_weight extension observation.component.value_codeable_concept.coding.extension(code = item_weight).value_decimal and all components where component value type is quantity and quantity system = eHealth/ucum/units and quantity code = ScoreOf

    3. ensure that this result is equal to observation.component.value_quantity.value

    4. if RESULT_SCORE_CALCULATION is missing or is empty then skip this validation

    5. in case of error return 422 β€œIncorrect observation resultβ€œ

Validate Immunizations

  1. Validate immunizations ids asΒ  primary keys

  2. Validate primary_source

    1. in case primary_source == true

      1. $..performer must be filled

        1. in case of error return 422 with msg "performer must be present if primary_source is true"

      2. $..report_origin must beΒ absent

        1. in case of error return 422 with msg "Only one of the parameters must be present"

      3. check not_given parameter

        1. in case not_given == false

          1. $..explanation.reasons, $..manufacturer, $..lot_number, $..expiration_date, $..dose_quantity.value, $..dose_quantity.unit, $..dose_quantity.code, $..site, $..route, $..vaccination_protocols.dose_sequence, $..vaccination_protocols.authority, $..vaccination_protocols.series, $..vaccination_protocols.series_doses, $..vaccination_protocols.target_diseases must be filled (inclusive with those that are mandatory according to the apiary)

            1. in case of error return 422 with msg "<reasons|manufacturer|lot_number|expiration_date|value|unit|code|site|route|dose_sequence|authority|series|series_doses|target_diseases> must be present if primary_source is true and not_given is false"

          2. $..explanation.reasons_not_given must beΒ absent

            1. in case of error return 422 with msg "Only one of the parameters must be present"

        2. in case not_given == true

          1. $..explanation.reasons_not_given, $..vaccination_protocols.dose_sequence, $..vaccination_protocols.authority, $..vaccination_protocols.series, $..vaccination_protocols.series_doses, $..vaccination_protocols.target_diseases must be filled (inclusive with those that are mandatory according to the apiary)

            1. in case of error return 422 with msg "<reasons_not_given|dose_sequence|authority|series|series_doses|target_diseases> must be present if primary_source and not_given is true"

          2. $..explanation.reasons must beΒ absent

            1. in case of error return 422 with msg "Only one of the parameters must be present"

    2. in case primary_source == false

      1. $..report_origin must be filled

        1. in case of error return 422 with msg "report_origin must be present if primary_source is false"

      2. $..performer must beΒ absent

        1. in case of error return 422 with msg "Only one of the parameters must be present"

      3. check not_given parameter

        1. in case not_given == true return error 422 with msg "Only completed immunizations can be filled if primary_source is false and not_given is true"

        2. in case not_given == false

          1. $..explanation.reasons, $..dose_quantity.value, $..dose_quantity.unit, $..vaccination_protocols.authority, $..vaccination_protocols.target_diseases must be filled (inclusive with those that are mandatory according to the apiary)

            1. in case of error return 422 with msg "<reasons|value|unit|authority|target_diseases> must be present if primary_source and not_given is false"

          2. if vaccination_protocols.authority == MoH $..vaccination_protocols.dose_sequence, vaccination_protocols.series, vaccination_protocols.series_doses must be filled

            1. in case of error return 422 with msg "<dose_sequence|series|series_doses> must be present if primary_source and not_given is false"

          3. $..explanation.reasons_not_given must beΒ absent

            1. in case of error return 422 with msg "Only one of the parameters must be present"

          4. $..manufacturer must be optional

  3. Validate that context of immunizations is a current encounter

    1. $.immunizations[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the immunization"

  4. Validate that the date is within acceptable limits

    1. $.immunizations[*].date <= current_time

      1. in case of error "Date must be in past"

    2. $.immunizations[*].date>=current_date-immunization_max_days_passed

      1. in case of error "Date must be greater thanΒ  {{current_date-immunization_max_days_passed}}"

  5. Validate performer according to the RuleΒ 

  6. Validate that observation submitted as a detail of reaction is an existing observation that belongs to the current patient

    1. $.immunizations[*].reactions[*].detail.identifier.value is an ID of existing observation in ME.observations where (ME.observations.patient_id==patient_id from url)Β OR one of $.observations[*].id

      1. in case of error return 422 "There is no observation with such id"

Validate Allergy Intolerances

  1. Validate allergy intolerances ids asΒ  primary keys

  2. Validate that context ofΒ allergy_intolerances is a current encounter

    1. $.allergy_intolerances[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the allergy_intolerances"

  3. Validate asserter according to the Rule

  4. Validate that the date is within acceptable limits

    1. $.allergy_intolerances[*].onset_date_time<= current date_time

      1. in case of error "Onset date time must be in past"

    2. $.allergy_intolerances[*].onset_date_time>=current_date-allergy_intolerance_max_days_passed

      1. in case of error "Onset date time must be greater thanΒ  {{current_date-allergy_intolerance_max_days_passed}}"

  5. Validate that asserted_date is in past

    1. $.allergy_intolerances[*].asserted_date<= current date_time

      1. in case of error "Asserted date must be in past"

  6. Validate that last_occurrence is in past

    1. $.allergy_intolerances[*].last_occurrence<= current date_time

      1. in case of error "Last occurrence must be in past"

Validate Risk Assessments

  1. Validate risk assessment id as a primary key

  2. Validate that context ofΒ risk_assessments is a current encounter

    1. $.risk_assessments[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the risk_assessments"

  3. Validate that asserted_dateΒ  is within acceptable limits

    1. $.risk_assessments [*].asserted_date<= current date_time

      1. in case of error "Asserted dateΒ  must be in past"

    2. $.risk_assessments [*].asserted_date>=current_date-risk_assessment_max_days_passed

      1. in case of error "Asserted date must be greater thanΒ  {{current_date-risk_assessment_max_days_passed}}"

  4. Validate performerΒ according to the Rule

    1. validateΒ performer is an active doctor from current legal_entity

      1. $..performer.identifier.value is an ID of existing employee in PRM.employee

        1. in case of error "Employee with such id is not found"

      2. $..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" andΒ PRM.employees.employee_type in ("DOCTOR", "SPECIALIST")

        1. in case of error return 422 "Invalid employee type"

  5. Validate only one of these fields are filled: reason_reference , reason_codeable_concept

  6. Validate reason_referenceΒ as a Reference

  7. Validate basis as a Reference

  8. Validate when_period as a Period

  9. Validate only one of the fields is filled: prediction.when_period or prediction.when_range

  10. Validate only one of the fields is filled: prediction.probability_decimal or prediction.probability_range

Validate Devices

  1. Validate device id as a primary key

  2. Validate that context of devices is a current encounter

    1. $.devices[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the device"

  3. Validate that asserted_dateΒ  is within acceptable limits

    1. $.devices[*].asserted_date<= current date_time

      1. in case of error "Asserted dateΒ  must be in past"

    2. $.devices[*].asserted_date>=current_date-device_max_days_passed

      1. in case of error "Asserted date must be greater thanΒ  {{current_date-device_max_days_passed}}"

  4. Validate asserter according to the Rule

  5. Validate usage_period as a period

Validate Medication Statement

  1. Validate medication statement id as primary key

  2. Validate that context ofΒ medication statement is a current encounter

    1. $.medication_statements[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the medication statement"

  3. Validate that asserted_dateΒ  is within acceptable limits

    1. $.medication statements[*].asserted_date<= current date_time

      1. in case of error "Asserted dateΒ  must be in past"

    2. $.medication statements[*].asserted_date>=current_date-medication statement_max_days_passed

      1. in case of error "Asserted date must be greater thanΒ  {{current_date-medication statement_max_days_passed}}"

  4. Validate asserter according to the Rule

  5. Validate based_on as aΒ Reference to OPS.medication_request

Validate Medication Administration

  1. Validate medication statement id as primary key

  2. Validate part_ofΒ 

    1. validate procedure or medication_administration is made for the same patient

      1. procedure.patient_id=@person_id

      2. medication_administration.patient_id=@person_id

        1. in case error returnΒ 409 "Procedure/Medication administration was made for another person"

    2. validate procedure or medication_administration is not in status `entered_in_error`

      1. in case error return 409, "Procedure/Medication administration is not active"

    3. if part_of.identifier.value is a procedure validate it is a procedure in DB or in payload

      • in case error return 422, "Procedure with such id is not found"

  3. ValidateΒ medication

    1. validate that medication is of type 'BRAND'

      1. in case error return 422, "Medication should be of type brand"

    2. medication corresponds to the INNM_DOSAGE medication from request.medicationΒ 

      1. "select count(*) from ingredients where parent_id=β€˜medication_administration.medication.id’ and medication_child_id = β€˜medication_request.medication_id’ " >=1

        in case error return 422,Β  "Medication should correspond to the one in request"

  4. Validate that context ofΒ medication administration is a current encounter

    1. $.medication_administration[*].context.identifier.value == $.encounter.id

      1. in case of errorΒ "Submitted context is not allowed for the medication administration"

  5. validateΒ performed_date_time <= now()

    1. in case error return 422, "performed_date_time should be in the past"

  6. Validate performerΒ according to the Rule

    1. validateΒ performer is an active doctor from current legal_entity

      1. $..performer.identifier.value is an ID of existing employee in PRM.employee

        1. in case of error "Employee with such id is not found"

      2. $..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" andΒ PRM.employees.employee_type in ("DOCTOR","SPECIALIST"))

        1. "Employee is not an active doctor"

  7. validateΒ reason_references

    1. validateΒ Β Condition|Observation|DiagnosticReportΒ asΒ Reference

    2. validate Condition|Observation|DiagnosticReport is not in status "entered_in_error"

      1. in case error return 409, "Reason reference should be active"

    3. validate Condition|Observation|DiagnosticReport is made for the same person

      1. in case error return 409, "Reason reference was made for another person"

    4. validate Condition|Observation|DiagnosticReport exist in DB or in payload

      1. in case error return 422, "Condition|Observation|DiagnosticReport with such id is not found"

  8. ValidateΒ request

    1. Β validate medication_request as a reference

    2. validate medication_request is in active status. medication_request.status='ACTIVE' and is_active=true

      1. in case error return 409, "medication request is not active"

    3. validate medication request is made for the same person

      1. in case error return 409, "medication requestΒ was made for another person"

    4. Validate medication_request.started_atΒ < now()

      1. in case error return 409, "Medication request started at should be in the past"

  9. ValidateΒ dosage

Validate Diagnostic Report

  1. Validate diagnostic reports ids as primary keys

  2. Validate based_on asΒ Reference

  3. Validate that service_request, referenced as based_on, is

    1. in status is activeΒ orΒ program_processing_status=in_progress (any status is valid in caseΒ program_processing_status=Β in_progress)

      1. in case of error return 409 "Invalid service request status"

    2. if program is defined than used_by_legal_entity==token.client_id OR null

      1. in case of error return 409 "Service request is used by another legal_entity"

    3. if program is defined than program_processing_status == new, in_queue or in_progress

    4. check thatΒ service_requestΒ contains based_on parameter

      1. in caseΒ based_onΒ present inΒ service_request

        1. verifyΒ care_plan:

          1. It should be inΒ activeΒ status

          2. Care plan's periodΒ endΒ (if exist) should be greater than current date or equal.

        2. verifyΒ activity:

          1. It has activity.detail.kind=service_request; activity.detail.product_reference=service_id.Β 

          2. It hasΒ scheduled, in_progressΒ status

      2. in caseΒ based_onΒ not present in request skip previous validations.

    5. Check if service request quantity is not exhausted as described atΒ related service request validation

  4. category

    1. Validate that one of diagnostic reports categories corresponds to service category, that is references as code in DR

      1. $.diagnostic_report.category[?]=PRM.services.category whereΒ PRM.services.id=$.diagnostic_report.code.identifier.value

        1. in case of error return 422 "None of the diagnostic report categories matches with the service category"

    2. Validate $.diagnostic_report[*].categories

      1. is an array with only one item

        1. in case of error return 422 "Expected a maximum of 1 items but got <number of elements>"

    3. Validate that $.diagnostic_report[*].category.coding.code is eHealth/diagnostic_report_categories dictionary, required

      1. in case of error return 422 "value is not allowed in enum"

    4. Validate that diagnostic reports category corresponds to service category, that is references as code in DR

      1. $.diagnostic_report[*].category=PRM.services.category whereΒ PRM.services.id=$.diagnostic_report[*].code.identifier.value

        1. in case of error return 422 "Diagnostic report category does not match with the service category"

  5. ValidateΒ code

    1. Validate code asΒ Reference

    2. IfΒ service_requests.code.identifier.value is service, validate $diagnostic_report.code.identifier.value = service_requests.code.identifier.value

      1. in case error return 409, "Service inΒ diagnostic_report differ from service in service request"

    3. ifΒ service_requests.code.identifier.value is service_group, validateΒ $diagnostic_report.code.identifier.value in (SELECT service_id from service_inclusions where service_group_id='service_requests.code.identifier.value')

      1. in case error return 409, "Service inΒ diagnostic_report differ from services in service request's service_group"

    4. Validate diagnostic_report.service.is_active = true

      1. in case error return 409, "Service should be active"

  6. Validate effective_periodΒ as a period

  7. Validate that issued is within acceptable limits

    1. $.diagnostic_reports[*].issued<= current date_time

      1. in case of error 422 "Asserted dateΒ  must be in past"

    2. $.diagnostic_reports[*].issued>=current_date-diagnostic_report_max_days_passed

      1. in case of error 422 "Issued must be greater thanΒ  {{current_date-diagnostic_report_max_days_passed}}"Β 

  8. Validate conclusion_code:

    1. $.diagnostic_reports[*].conclusion_code.coding[*].code validate that the code belongs to the dictionary system 'eHealth/ICD10_AM/condition_codes'

      1. in case of error return "Value is not allowed in enum"

    2. Check that there is only one code in conclusion_code.coding array

      1. if more - return error "Only one code from one dictionary is allowed"

  9. Validate recorded_by as Employee

  10. Validate encounter

    1. $.diagnostic_reports[*].encounter.identifier.value == $.encounter.id

      1. in case of error 409 "Invalid reference"

  11. Validate performer:

    1. as Employee

    2. according to logic Performer(asserter) validation

  12. Validate managing_organization is a current legal_entity

    1. $.managing_organization.identifier.value==token.client_id

      1. in case of error 409 "Managing organization does not correspond to user's legal entity."

  13. Validate result_interpreter.identifier as Employee

  14. Validate result_interpreter.identifier is an employee with employee_type = DOCTOR or SPECIALIST

  15. Validate only One of the fields is filled:

    1. $.diagnostic_report[*].results_interpreter.reference ORΒ $.diagnostic_report[*].results_interpreter.text

    2. $.diagnostic_report[*].performer.reference ORΒ $.diagnostic_report[*].performer.text

  16. ValidateΒ primary_source

    1. If primary_source==true, then

      1. Managing organization MUST be filled

      2. performer.referenceΒ MUST be filled

    2. If primary_source==false, then

      1. report_origin must be filled

      2. performer.reference must NOT be filled

      3. results_enterpreter.reference must NOT be filled

  17. Validate patient verification status:

    1. If diagnostic report has based_on with valid and active service request, then skip this validation.

    2. Else check patient'sΒ verification_status is not equal to NOT_VERIFIED.

      1. in case of error return 409, "Patient is not verified"

  18. Validate specimens, if submitted:

    1. Check field has array with elements ofΒ ReferenceΒ type on specimen resource

      1. in case of error return 422 β€œnot allowed in enum”

    2. For each specimen check:

      1. Check it exists in DB or within current package, and belongs to the sameΒ patient:

        1. in case of error return 422 "Specimen not found"

      2. Check it is present in the only one diagnostic report within the package.

        1. in case of error return 422 "Specimen is already used in another diagnostic report"

      3. Check status:

        1. is available if the specimen found in the DB

          1. in case of error return 422 "Specimen created beforeΒ the current package should be available"

        2. is unavailable if the specimen not found in the DB, but in the package

Validate Procedures

  1. Validate by json schema

  2. Validate procedure id as primary key

  3. Validate status

    1. On createΒ procedure status could be completed or not_done.Β `entered_in_error` could be set on update procedure.

      1. error 422 by json schema

  4. ValidateΒ code

    1. Validate code asΒ Reference

    2. Validate procedure.service.is_active = true

      1. in case error return 409, "Service is not active"

  5. Validate encounter

    1. $.procedure[*].encounter.identifier.value == $.encounter.id

      1. in case error return 409, "SubmittedΒ encounter is not allowed for procedure"

  6. ValidateΒ performed_date_time

  7. ValidateΒ performed_period/performed_date_time:

    1. if $.status == "not_done" check that Β performed_period/performed_date_timeΒ fields are not present in request

      1. in case error return 422Β entry:Β "$.performed_period" (or "$.performed_date_time"), rules[0].description: "Must not be present in procedure with status <$.status>"

    2. else,Β if $.status == "completed":

      1. Check that only one of this parameters present

        1. in case error return 422 "Only one of the parameters must be present"

      2. ValidateΒ performed_date_time

        1. Β performed_date_time is real

          1. in case error return 422, "Performed_date_time in invalid"

        2. performed_date_timeΒ <= now

          1. in case error return 422 "Procedure cannot be registered in future"

      3. ValidateΒ performed_period

        1. $.performed_period.start<= now

          1. in case of error return 422 "Procedure cannot be registered in future"

        2. $.performed_period.end>=Β $.performed_period.start

          1. in case of error return 422 "End date must be greater than start date"

        3. performed_period.end <= now

          1. in case error return 422 "Procedure cannot be registered in future"

        4. Validate $.performed_periodΒ as required field in case if procedure based on service request with quantity that has code=MINUTE (system=SERVICE_UNIT)

          1. in case of error return 422 "can't be blank"

  8. ValidateΒ recorded_by

    1. ValidateΒ recorded_by asΒ Reference

    2. $..recorded_by.identifier.value is an ID of existing employee in PRM.employee

      1. in case of errorΒ  return 422, "Employee with such id is not found"

    3. ValidateΒ recorded_by is employee with status='APPROVED' and is_active= true and end_date is null or more than today

      1. in case error return 409, "This action is prohibited for current employee"Β 

    4. Validate employees.legal_entity_id=$managing_organization.identifier.value

      1. in case error return 409, "Employee should be from current legal entity"

  9. Validate asserter

  10. ValidateΒ division

    1. Validate divisionΒ asΒ Reference

    2. $division is an IDΒ in PRM.divisions

      1. in case return 422, "Division with such id is not found"

    3. division.status=ACTIVE and is_active=true

      1. in case error return 409, "Division is not active"

    4. division.legal_entity_id =Β $client_id orΒ division.legal_entity_id=$managing_organization.identifier.value

      1. in case error return 409, "Division is not in current legal_entity"

  11. Validate managing_organization is a current active legal_entity with proper type

    1. Β asΒ Reference

    2. $managing_organization is an IDΒ in PRM.legal_entities

      1. in case return 422, "Legal entity with such id is not found"

    3. validateΒ managing_organization status is 'ACTIVE' and is_active=true

      1. in case error return 422 ('Legal entity is not active')

    4. validate legal_entity type is in ('PRIMARY_CARE','MSP','MSP_PHARMACY','MSP_PHARMACY') (use `ME_ALLOWED_TRANSACTIONS_LE_TYPES` from charts)

      1. in case error return 422, "Legal entity with type $legal_entity.type cannot perform procedures"

    5. validate $managing_organization.identifier.value = $client_id

      1. in case of error 409 "Managing organization does not correspond to user's legal entity."

  12. Validate reason_references

    1. Validate reason_referenceΒ as a ReferenceΒ (Reference)

    2. ValidateΒ reason_refernce.identifier.type.coding.[0].codeΒ is condition or observation

      1. in caseΒ error return 422 "value is not allowed in enum"

    3. ValidateΒ reason_refernce.identifier.value isΒ condition or observation not in statusΒ ENTERED_IN_ERROR

      1. in case error return 422, "Observation in "entered_in_error" status can not be referenced" if observation, else - "Condition is canceled"

  13. ValidateΒ outcome

    1. validate outcomeΒ as a ReferenceΒ 

    2. validateΒ outcome.coding.object.system is in dictionaryΒ eHealth/procedure_outcomes

      1. in case error return 422, "outcome not in dictionaryΒ eHealth/procedure_outcomes"

  14. ValidateΒ complication_details

    1. validateΒ complication_details as a ReferenceΒ 

    2. validate complication_details.identifier.value refer to condition in the same encounter package

      1. in case error return 422, "complication_detailsΒ does not correspond to condition in this encounter package"

  15. Validate category

    1. according to the dictionary 'eHealth/procedure_categories' - by schemata

    2. Validate that procedure category corresponds to service category, that is references as code in procedure

      1. $.procedure.category=PRM.services.category whereΒ PRM.services.id=$.procedure.code.identifier.value

        1. in case of error return 422 "Procedure category does not match with the service category"

  16. Validate patient verification status:

    1. If procedure has based_on with valid and active service request, then skip this validation.

    2. Else check patient verification_status is not equal to NOT_VERIFIED.

      1. in case of error return 409, "Patient is not verified"

  17. Validate used_codes

    1. CheckΒ that the $.used_codes[*].coding[*].codeΒ belongs to the dictionary in $.used_codes[*].coding[*].system

      1. in case of error - return 422Β "Value is not allowed in enum"

    2. Validate 'used_codes.coding.code'Β  is_active = true

      1. in case error return 409, "Value is not active"

Validate Clinical impression

  1. Validate by json schema

  2. Validate clinical impression id as primary key (Primarykeyvalidation)

  3. Validate status

    1. Check that the code belongs to the dictionary systemΒ (eHealth/clinical_impression_statuses)

      • in case of error - return 422 ('value is not allowed in enum')

    2. Check it has value = completed

      • in case of error - return 422 ('value is not allowed in enum')

  4. ValidateΒ code

    1. CheckΒ that the code belongs to the dictionary system (eHealth/clinical_impression_patient_categories)

      1. in case of error - return 422 ('value is not allowed in enum')

    2. Validate code.coding depending on the qty of codes. Maximum one code is allowed

      1. in case of error - return 422 ('Only one code is allowed')

    3. Check by code.coding[0].code and code.coding[0].system active rulesΒ inΒ rule_engine_rules collection

      1. in case any active rules present - check request only with following validations

      2. in case rule present in collection -Β check request with following validationsΒ and with additional from rule engine rule

  5. Validate description

    1. Check thatΒ value withΒ string type

      1. in case of error - return 422 ('type mismatch. Expected string but gotΒ {entered type}')

  6. Validate encounter

    1. Check the value is valid reference onΒ encounter resource

      • Check that value is an object with references of type encounter

        • in case of error - return 422 ('value is not allowed in enum')

    2. Check the value is valid reference on encounter resource

      • Check that $.clinical_impressions[*].encounter.identifier.value == $.encounter.id

        1. in case error - return 422 ('Invalid reference')

  7. Validate effective_period andΒ effective_date_time:

    1. Validate that at least one of the parameters are present

      • in case of error - return 422 ('At least one of the parameters must be present')

  8. Validate effective_periodΒ as a period (PeriodValidation)

    1. Validate value in the field $.effective_period

      • Check that $.effective_period.start <= encounter.date

        • in case of error - return 422 ('Start date must be in the past')

      • Check that $.effective_period.end >= $.effective_period.start

        • in case of error - return 422 ('End date must be greater than or equal the start date')

    2. Validate that $.effective_period.end is within acceptible limits

      • Check that $.effective_period.end <= current_time

        • in case of error - return 422 ('Date must be in past')

      • Check that $.effective_period.end >= current_date-clinical_impression_max_days_passed

        • in case of error - return 422 ('Date must be greater than {{current_date-clinical_impression_max_days_passed}}')

  9. ValidateΒ effective_date_time

    1. CheckΒ that field $.effective_date_timeΒ withΒ string type

      1. in case of error - return 422 ('type mismatch. Expected string but gotΒ {entered type}')

    2. Check that field $.effective_date_time <= current_time

      1. in case of error - return 422 ('Date must be in past')

    3. Check that field $.effective_date_time >= current_date-clinical_impression_max_days_passed

      1. in case of error - return 422 ('Date must be greater than {{current_date-clinical_impression_max_days_passed}}')

  10. ValidateΒ assessor

    1. ValidateΒ assessor asΒ Reference (Referencevalidation)

      1. $.assessor.identifier.value is an ID of existing employee in PRM.employee

        1. in case of error - return 422Β ('Employee with such id is not found')

    2. ValidateΒ assessor is employee with status='APPROVED' and is_active= true and end_date is null or more than today

      1. in case of error - return 422 ('Invalid employee status')

  11. ValidateΒ previous

    1. Check the value is valid reference onΒ clinical impression resource

      • Check that value is an object with references of type clinical_impression

        • in case of error - return 422 ('value is not allowed in enum')

      • Check thatΒ clinical impression is active (status is not entered_in_error)

        • in case of error - return 422 ('Clinical impression in "entered_in_error" status can not be referenced')

      • Check thatΒ clinical impression belongs to patient ($.subject)

        • in case of error - return 422 ('Clinical impression with such id is not found')

  12. ValidateΒ problems

    1. Check that value is an array with references of type condition

      • in case of error - return 422 ('value is not allowed in enum')

    2. Check that each condition is active (verification_status is not entered_in_error)

      1. in case of error - return 422 ('Condition in "entered_in_error" status can not be referenced')

    3. Check that condition belongs to the patient ($.subject)

      • in case of error - return 422 ('Condition with such id is not found')

  13. Validate finding

    1. Check that value is an array with objects

      1. ValidateΒ item_reference

        1. Check that value is an object with reference of resource condition, observation (furtherΒ <Medical event resource>)

          1. in case of error - return 422 ('value is not allowed in enum')

        2. Check thatΒ <Medical event resource>Β is active (status is not entered_in_error)

          1. in case of error - return 422 ('<Medical event resource> in "entered_in_error" status can not be referenced')

        3. Check that each reference:

          1. is valid ME of defined type above

          2. belongs to the patient ($.subject)

            1. in case of error - return 422 (<Medical event resource> with such ID is not found')

        4. In case some resources present in active rule, check that they correspond to configured rule

          1. Check that value is an object with reference of resource condition, observation (further <Medical event resource>)

            1. in case of error - return 422 'entry': '$.clinical_impressions[0].code', 'entry_type': 'json_data_property', 'rules': [{'description': '<description_text of the failed rule>, rule: <number of failed rule>', …

      2. ValidateΒ basis

        1. Check thatΒ value withΒ string type

          1. in case of error - return 422 ('type mismatch. Expected string but gotΒ {entered type}')

  14. ValidateΒ supporting_info

    1. Check that value is an array with references of type episode_of_care, procedure, diagnostic report, encounter (furtherΒ <Medical event resource>)

      1. in case of error - return 422 ('value is not allowed in enum')

    2. Check thatΒ <Medical event resource>Β is active (status is not entered_in_error)

      1. in case of error - return 422 ('<Medical event resource> in "entered_in_error" status can not be referenced')

    3. Check that each reference:

      1. is valid ME of defined type above

      2. belongs to the patient ($.subject)

        1. in case of error - return 422 (<Medical event resource> with such ID is not found')

    4. In case some resources present in active rule, check that they correspond to configured rule

      1. in case of error - return 422 'entry': '$.clinical_impressions[0].code', 'entry_type': 'json_data_property', 'rules': [{'description': '<description_text of the failed rule>, rule: <number of failed rule>', …

  15. Validate note

    1. Check thatΒ value withΒ string type

      1. in case of error - return 422 ('type mismatch. Expected string but gotΒ {entered type}')

  16. Validate patient

    1. In case patient params present in active rule, get them through subject and check that they correspond to configured rule

      1. in case of error - return 422 'entry': '$.clinical_impressions[0].code', 'entry_type': 'json_data_property', 'rules': [{'description': '<description_text of the failed rule>, rule: <number of failed rule>', …

    2. In case medication dispense data presents in active rule, get medication dispense data in patient context (through subject) and check that it correspond to configured rule

      1. in case of error - return 422 'entry': '$.clinical_impressions[0].code', 'entry_type': 'json_data_property', 'rules': [{'description': '<description_text of the failed rule>, rule: <number of failed rule>', …

Validate Specimen

  1. Validate by json schema

  2. Validate specimens ids asΒ  primary keys (Submit Encounter Data Package#Primarykeyvalidation)

  3. Validate that context of specimen is a current encounter

    1. $.specimens[*].context.identifier.value==$.encounter.id

      1. in case of error return 422 "Submitted context is not allowed for the specimen"

  4. Validate specimen's root attributes:

    1. ValidateΒ requests, type, condition, registered_by, managing_organizationΒ as described at Create Specimen: Validate specimen

    2. Validate parentΒ as described atΒ Create Specimen: Validate specimen,Β but also check it within current package

    3. Validate status:

      1. Check the value is available or unavailable, according to theΒ specimen_statusesΒ dictionaryΒ 

        1. in case of error return 422 "value is not allowed in enum"

      2. Specimen is unavailable if there is at least one entity thatΒ references specimen (Observations where ($.observations[*].specimen.reference == specimen.id) or Diagnostic Reports whereΒ ($.diagnostic_reports[*].specimen.reference == specimen.id))

        1. in case of error return 422 "Specimen that is not referenced in Observation or Diagnostic Report must be in 'available' status"

  5. Validate collection attributes:

    1. Validate collector, collected, quantity, duration, method, body_site, fasting statusΒ as described at Create Specimen: Validate collection

    2. Validate procedure in the field $.collection.procedure, Reference type, optional

      • Check it references to procedure resource

        • in case of error - return 422 ('value is not allowed in enum')

      • Check that procedure exists in the DB and belongs to the patient, or it is within current package

        • in case of error - return 422 ('Procedure not found')

      • Validate that entity is not in status "entered_in_error"

        • in case of error - return 422 ("Entity in status "entered_in_error" can not be referenced")

  6. Validate container attributes as described at Create specimen: Validate container

  7. ValidateΒ received_time as described at Process Specimen: Validate received datetime

    1. received_time must be emptyΒ if there are no other entities that reference specimen (NOΒ Observations where ($.observations[*].specimen.reference == specimen.id) and NO Diagnostic Reports whereΒ ($.diagnostic_reports[*].specimen.reference == specimen.id))

      1. in case of error return 422 "Received time must not be set for available specimen"

  8. Validate status_reason:

    1. is set to codeable concept with system = specimen_invalidate_reasons and code = used, if the specimen status is unavailable (i.e. at least one entity thatΒ references specimen).

      1. in case of error return 422 ('value is not allowed in enum')

    2. is empty, if the specimen status is available.

      1. in case of error return 422 ('Status reason must not be set for available specimen')


Validate Device Dispense

  1. Validate by json schema

    1. Return 422 with list of validation errors in case validation failsΒ 

  2. Validate device dispenses ids asΒ  primary keys (https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/edit-v2/18492261105#Primary-key-validation )

  3. Validate device dispenses's root attributes:

    1. Validate performer, location as described at https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18493276353/RC_+UPD+Create+Device+dispense#Validate-dispense

    2. Validate $.status is COMPLETED or DECLIEND

      1. else - return 422 ("value is not allowed in enum")

  4. If based_on is present, validate:

    1. Check it references to device_request resource

      1. in case of error - return 422 ('value is not allowed in enum')

    2. Check that device request exists and belongs to the same patient

      1. in case of error - return 422 ('Device request not found')

    3. Π‘heck that device request is in status 'active'

      1. in case of error - return 409 error ('Device request is not active')

    4. Check that intent specified in Device request is order

      1. in case of error - return 409 error ('Only device request with intent = 'order' can be dispensed')

    5. Check that program in device request is empty (device_requests.program = null)

      • in case of error - return 409 ('Device request with program can not be referenced')

    6. Verify care plan Activity as described in https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18493276302/RC_+UPD+Qualify+Device+Request+by+ID#Validate-related-Care-plan

  5. validate when_handed_over

    1. If based_on is present check that when_handed_over is equal or greater then device_request.authored_on
      1. in case of error - return 409 error ('when_handed_over date can not be lesser then the authored_onΒ  date of the related Device request')

  6. Validate encounter:

    1. Validate encounter references the current encounter, submitted within the same package

      1. $.device_dispenses[*].encounter.identifier.value==$.encounter.id

        1. in case of error return 422 "Device dispense can only reference encounter from the same package"

    2. Validate encounter period fully contains when_handed_over date

      1. $.encounter.period.start<$.device_dispenses[*].when_handed_over and $.encounter.period.end_date>$.device_dispenses[*].when_handed_over

        1. in case of error return 422 "Device dispense when_handed_over date doesn’t match with encounter period”

  7. Validate part_of:

    1. Check it references to procedure resource

      • in case of error - return 422 ('value is not allowed in enum')

    2. Validate that procedure reference one of procedures, submitted within the same package

      • in case of error return 422 "Device dispense can only reference procedure from the same package"

    3. Validate that procedure is not in status "entered_in_error" or β€œnot_done”

      • in case of error - return 422 ("Procedure in status "entered_in_error" or β€œnot_done” can not be referenced")

  8. Validate supporting_info:

    1. Check it references condition, observation, diagnostic_report, procedure, encounter, episode, device or device_association resource

      • in case of error - return 422 ('value is not allowed in enum')

    2. Check that {resource} exists and belongs to the same patient, or it is within current package

      • in case of error - return 422 ('{resource} not found')

    3. Validate that {resource} is not in status "entered_in_error"

      • in case of error - return 422 ("{resource} in status "entered_in_error" can not be referenced")

  9. Validate $.details.device_code if present:

    1. if based_on is present validate Dispense details as described at https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18493276353/RC_+UPD+Create+Device+dispense#Validate-device_code

    2. if based_on is NOT present:

      1. Check system($.details.device_code.coding.system) = device_definition_classification_type

        1. in case of error - return 422 ('value is not allowed in enum')

      2. Get device_code from the dictionary device_definition_classification_type ($.details.device_code.coding.code) and check parameter is_active = true

        1. in case of error - return 422 ('Device code not found')

    3. Check that $.device_code.coding[] array contains only 1 element

      • in case of error - return 422 ('Exceeded max count of elements in the array')

    4. Check that $.device_code.coding[].code is an active value from the dictionary specified in $.device_code.coding[].system

      • in case of error - return 422 ('Value <code> not found in the dictionary <system>')

  10. Validate $.details.device If reference on Device definition is present there:

    1. if based_on is present: https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18493276353/RC_+UPD+Create+Device+dispense#Validate-device_code

    2. if based_on is NOT present

      1. Check code ($.details.device.identifier.type.coding.code) = device_definition

        1. in case of error - return 422 ('value is not allowed in enum')

      2. Get device definition by id ($.details.device.identifier.value)

        1. device_definition.is_active = true

          1. in case of error - return 422 ('Device definition not found')

    3. Check the remainder of the division ($.details.quantity.value/device_definition.packaging_count) is equal to 0

      • in case of error - return reject_reason = οΏ½οΏ½οΏ½The quantity must be divisible to packaging_count of prescribed Device Definition”

  11. Validate $.details.device If reference on Device is present there:

    1. Check that device exists and belongs to the same patient, or it is within current package

      • in case of error - return 422 ('Device not found')

    2. Validate that device status is not in status "entered_in_error"

      • in case of error - return 422 ("Device in 'entered_in_error' status can not be referenced")

    3. If based_on is present, validate:

      1. if referenced Device request($.based_on) contains code (device_request.code)

        1. Check that the type in the Device($.details.device) is equal to the code in the Device request($.based_on)

          1. in case of error - return 422 ("Dispensed device doesn’t match with prescribed device")

      2. if referenced Device request($.based_on) contains code_reference (device_request.code_reference)

        1. Check that the definition in the Device($.details.device) is equal to the code_reference in the Device request($.based_on)

          1. in case of error - return 422 ("Dispensed device doesn’t match with prescribed device")

  12. Validate quantity

    1. if based_on is present validate quantity as described at https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/18493276353/RC_+UPD+Create+Device+dispense#Valdate-quantity ,but also include Device dispenses from the current package in remaining_quantity calculation

    2. else validate quantity.value is an integer bigger than 0

  13. Validate related Care plan

    1. Verify care plan Activity as described in Qualify Device request | Validate related Care plan

  14. Validate primary_source

    1. if $.primary_source = true, then check $.report_origin isΒ absent

      1. in case of error - return 422 ("Report_origin can not be submitted in caseΒ primary_source is true")

    2. if $.primary_source = false, then check $.report_origin isΒ present

      1. in case of error - return 422 (β€œcan't be blank”)

  15. Validate report_origin

    1. Check $.report_origin.coding[].system is eHealth/report_origins dictionary

      1. in case of error - return 422Β ("value is not allowed in enum")

    2. Check that $.report_origin.coding[].code is an active value from the dictionary specified in code.coding[].system

      • in case of error - return 422 ('value is not allowed in enum')

Primary key validation

  1. Validate that IDs of all submitted entities in the array are unique

    1. validate that $.{collection}[*].id from the payload are all unique among themselves

      1. in case of error return 409 "All primary keys must be unique"Β Β 

    2. validate there is no entity with such id in the corresponding Medical events collection

      1. in case of error return 422 "{Entity} with such id already exists"

Reference validation

This validation is used to validate references to medical events data from patient's collection.Β 

  1. Validate that $..identifier.value is an existing value from $..identifier.type.coding[0].code collection in DB and it belongs to the patient OR it is a value from corresponding collection in the current requestΒ 

    1. in case of errror return 422 "There is noΒ {$..identifier.type.coding[0].code} with such id"

  2. Validate that this entity is not in status entered_in error

    1. in case of errror return 422 "Could not reference entity in status entered_in_error"

Example:

"identifier": { "type": { "coding": [ { "system": "eHealth/resources", "code": "observation" } ] }, "value": "9183a36b-4d45-4244-9339-63d81cd08d9c" } }

In this case validate thatΒ "9183a36b-4d45-4244-9339-63d81cd08d9c" is an existing observation from patients collection and it is not entered_in_error.

Performer(asserter) validation

  1. case $..primary_source==true

    1. $..performer(or $..asserter) must be filled

      1. in case of error "Performer (asserter) must be filled"

    2. $..report_origin must beΒ absent

      1. in case of error "Report_origin can not be submitted in caseΒ primary_source is true"Β 

    3. validate performer(asserter) is a valid value from corresponding dictionary

      1. $..performer.identifier.type.coding[*].system == "eHealth/resources"

        1. in case of error "Submitted system is not allowed for this field"

      2. $..performer.identifier.type.coding[*].code=="employee"

        1. in case of error "Submitted code is not allowed for this field"

    4. validateΒ performer(asserter) is a active doctor from current legal_entity

      1. $..performer.identifier.value is an ID of existing employee in PRM.employee

        1. in case of error "Employee with such id is not found"

      2. $..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" andΒ PRM.employees.employee_type=="DOCTOR" or "SPECIALIST") (in case of observation also ASSISTANT)

  2. case primary_source==false

    1. $..report_origin must be filledΒ 

      1. in case of error "Report_origin must be filled"

    2. if $..primary_source==false then $..performer(asserter) must be absent

      1. in case of errorΒ "Performer(asserter) can not be submitted in caseΒ primary_source is false"Β 

    3. validate report_origin

      1. $..report_origin.coding[*].system == "eHealth/report_origins"

        1. in case of errorΒ "Submitted system is not allowed for this field"

Period Validation

  1. $..period.start <= current_dateTime

    1. in case of error return 422- "Start date must be in past"

  2. if $..period.end is filled:

    1. $..period.end > visit.period.start

      1. in case of error return 422 - "End date must be greater than the start date"

Employee validation

Users can not reference employees between different legal entities. Employee that is not in status `approved` can not be referenced as well.

  1. Β $...identifier.value exists inΒ PRM.employees

    1. in case of error 409 "Employee not found"

  2. $...identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" andΒ PRM.employees.legal_entity==token.client_id)

    1. in case of error 409 "Submitted employee is not an active employee from current legal entity"

Related service request validation

  1. If service request referenced as based on in ME:

    1. if it has quantity:

      1. Check allowed quantity units for ME:

        1. if ME is Procedure, then service_request.quantity.code can have values MINUTE or PIECE (system=SERVICE_UNIT)

        2. if ME is Encounter or Diagnostic report, then service_request.quantity.code can have PIECE only

          1. in case of error return error 409 ("<ME type> cannot be measured in <quantity.code's value>")

      2. Check service_request remaining quantity parameter:

        1. if quantity.code = PIECE:

          1. count number of related MEs to the service request as used quantity.

          2. calculate remaining quantity by subtracting used quantity and number of current MEs that are related to theΒ service request from service request's quantity

          3. Validate remaining quantity is greater then or equal to zero

            1. in case of error return 409 "The total amount of medical events exceeds quantity in related service request with <id>"

        2. if quantity.code = MINUTE:

          1. select related Procedures to the service request.

          2. for each selected Procedure calculate duration as performedPeriod.end - performedPeriod.start without considering seconds. Result should be in minutes.

          3. calculate used quantity as sum of procedure durations

          4. calculate remaining quantity by subtracting used quantity and durations of current ProceduresΒ that are related to theΒ service requestΒ from service request's quantity

          5. Validate remaining quantity is greater then or equal to zero

            1. in case of error return 409 "The total amount of medical events exceeds quantity in related service request with <id>"

Related care plan validation

As for old care plan activities (has quantity w/o units) the amount of service request was no controlled, we should ensure that number of created medical events are not exceed its quantity:

  1. Validate remaining_quantity in activitiesΒ referenced by service requests in the EDP using the algorithm described for a quantity without units (code=null) inΒ PreQualify Service Request#Validate-service-requestΒ . But also, addΒ theΒ reserved at the moment quantity,Β that includes the number of medical events in the EDP related to the activity, to the used_quantity.

Β 

Processing

API paragraph not found

Β 

Response structure

See on Apiary

Example:

{ "data": { "status": "pending", "eta": "2018-08-02T10:45:16.000Z", "links": [ { "entity": "job", "href": "/Jobs/NBXk9EyErUZv1RhXgyvgg" } ] }, "meta": { "code": 202, "url": "http://example.com/resource", "type": "object", "request_id": "req-adasdoijasdojsda" } }

Β 

Β 

Post-processing processes

  1. Save signed_content to Media Storage

  2. Save data to corresponding collections in DBs

  3. Save link to the signed content to the encounter

  4. Enrich encounter.diagnoses:

    1. select condition.code from Medical Events DB(or from request body)Β  where condition.id==diagnoses[@].condition.identifier.valueΒ 

    2. set diagnoses[@].code = select 1

  5. Save diagnoses from encounter to episodes.current_diagnoses

    1. ME.patients.episodes.diagnoses = $.encounter.diagnosesΒ 

  6. Add a record to the ME.patient.episodes{episode_id}.diagnoses_hstr

    1. date = current_date

    2. evidence = reference to encounterΒ  ($.encounter.id)

    3. diagnoses = $.encounter.diagnosesΒ 

  7. Generate accession_identifier number:

    1. Generate requisition number (seeΒ Human readable requisition number) based on the specimen id. Note: requisition number should be unique for each specimen and should not match with number of another entities. So, if generated number match to existing in DB - it should be regenerated

    2. Encode and set it into $.accession_identifier attributeΒ 

  8. Set display_value to employees for all submitted objects

    1. Select PRM.parties.first_name, PRM.parties.second_name, PRM.parties.last_name from PRM.parties where (PRM.parties.id == (Select PRM.employees.party_id fromΒ  PRM.employeesΒ whereΒ PRM.employees.id==Β $.care_manager.identifier.value))

    2. ME.patients.encounters{encounter_id}.performer.display== Select 1

    3. ME.conditions{condition_id}.asserter.displayΒ == Select 1

    4. ME.observations{observation_id}.performer.display == Select 1

    5. ME.patients.immunizations{immunization_id}.performer.display == Select 1

    6. ME.patients.allergy_intolerance{ai_id}.asserter.display == Select 1

    7. ME.patients.devices{device_id}.asserter.display == Select 1

    8. ME.patients.medication_statements{ms_id}.asserter.display == Select 1

    9. ME.patients.risk_assessment{rs_id}.asserter.display == Select 1

    10. ME.patients.diagnostic_reports{dr_id}.performer.reference.display == Select 1

    11. ME.patients.diagnostic_reports{dr_id}.recorded_by.reference.display == Select 1

    12. ME.patients.diagnostic_reports{dr_id}.results_interpreter.reference.display == Select 1

    13. ME.specimens{specimen_id}.registered_by.reference.display == Select 1

    14. ME.specimens{specimen_id}.collector.reference.display == Select 1, if collector type is employeeΒ 

  9. In case there are reactions ($.observations[?].reaction_on) in the request, update corresponding immunizations with the reactions:

    1. Set in ME.patient.immunization.reaction.detail $.observation.id as a reference
      note:Β $.observations[?].reaction_on should not be saved in observation, only in corresponding immunization

  10. SetΒ display_value for legal_entities

    1. ME.patients.diagnostic_reports{dr_id}.managing_organization.display

    2. ME.specimens{specimen_id}.managing_organization.display_value

  11. Set managing_organization for submitted observations, conditions, encounter

    1. ME.conditions{cond_id}.managing_organization=token.client_id

    2. ME.observations{observ_id}.managing_organization=token.client_id

    3. ME.encounters{encounter_id}.managing_organization=token.client_id

  12. In case encounter.incoming_referral was filled, set episode_origin to encounter

    1. Select episode where id== (select ME.encounter.episode.identifier.value where encounter.id==(select ME.service_requests.context.identifier.value where id==$.encounter.incoming_referral.identifier.value))

  13. In case diagnostic_reports.based_on was filled, setΒ episode_origin to diagnostic report

    1. Select episode where id== (select ME.encounter.episode.identifier.value where encounter.id==(select ME.service_requests.context.identifier.value where id==$.diagnostic_reports.based_on.identifier.value))

  14. in case service request has reference on care plan and encounter.incoming_referralΒ was filled set $.encounter.id to related to $.service_request activity[].outcome_reference

  15. in case service request has reference on care plan and procedures.based_on was filled set $.procedures.id to related to $.service_request $.activity[].outcome_reference

  16. in case service request has reference on care plan and diagnostic_reports.based_onΒ was filled set $.diagnostic_reports.id to related to $.service_request activity[].outcome_reference

  17. in case reference on service request has reference on care plan updateΒ $ .activity.status to in_progress if previous activity status was scheduled

  18. in case reference on service request has reference on care plan update $ .activity.remaining_quantity parameter by subtracting the quantity of artifacts that have a reference on service request that contains an $.based_on.[]activity

  19. If there are at least one record for speciality where speciality_officio = true:

    1. Enrich encounter data with performer speciality:

      1. SELECTΒ speciality -> 'speciality' FROM employees WHEREΒ speciality ->> 'speciality_officio' = 'true' AND id =Β $.encounter.performer.identifier.value

      2. Β SetΒ encounter.performer_speciality as CodeableConcept type with system =Β SPECIALITY_TYPE

  20. In case encounter.clinical_impression was filled set $.context_episode_id to clinical_impressions data model (encounters.context.[].episode.value=clinical_impression.context_episode_id)

  21. If any available specimen, that has already stored in DB, is referenced in Observation or Diagnostic Report - change its (Specimen) status to unavailable in DB according to RC.__Specimen status model_EN . Also, set status_reason for a specimen: system = specimen_invalidate_reasons, code = used.

  22. Set origin_episode (if $.based_on in request and $.based_on.service_request.context != null) for Diagnostic Report:

    1. origin_episode is an object from the $.service_request.context.episode

  23. Set origin_episode (if $.based_on in request and $.based_on.service_request.context != null) for Procedure:

    1. origin_episode is an object from the $.service_request.context.episode d.

  24. Set following fields for device dispense:

    1. performer_legal_entity= client_id from token

    2. details.quantity.unit = description according to quantity code and system

    3. origin_episode_id= context_episode_id from device request referenced in based_on

    4. context_episode_id = episode referenced by current encounter

  25. If the Package contains Device Dispense in status completed, and related Device request has reference on an Activity as a device_request.based_on, then

    1. add reference on the device dispense resource to theΒ outcome_reference attribute of the activity

    2. if Activity.status is scheduled change it to in_progress

  26. If the Package contains Device Dispense with related Device request that has a quantity but no medical program:

    1. calculate remaining quantity of the related Device request (same as on https://e-health-ua.atlassian.net/wiki/spaces/EH/pages/17782015159#Service-logic):

      1. Select all Device dispenses in status completed related to the Device request, including Device dispenses from the current package

      2. Sum quantity in the filtered Device dispenses as dispensed_qty

      3. Calculate remaining_quantity = requested_quantity-Β dispensed_quantity

    2. If remaining_quantity is 0, change status of the related Device request($.based_on) to completed

Β 

HTTP status codes

HTTP status code

Message

What caused the error

HTTP status code

Message

What caused the error

202

Response

Β 

401

Access denied

Β 

403

Invalid scopes

Β 

404

Patient not found

Β 

409

Β 

Validation error

422

Β 

Validation error

Β 

Π•Π‘ΠžΠ— - ΠΏΡƒΠ±Π»Ρ–Ρ‡Π½Π° докумСнтація