Introduction
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
Validation
Authorization
Verify the validity of access token
in case of error return 401 ('Access denied')
Check user scope encounter:write in order to perform this action
in case of error generate 403 response ('Invalid scopes')
Request validation
Note: No update operations are allowed. All IDs, submitted as PK, should be unique for eHealth.
Validate patient status
db.patients.status for this patient must "active"
in case of error return 409 - "Patient is not active"
Validate request according to JSON Schema (link)
Return 422 with list of validation errors in case validation fails
Validate Visit
$.visit.id is unique
in case of error return 422 - "Visit with such id already exists"
$.visit.end is filled
in case of error return - "End date of visit must be filled"
Validate DS
Validate that DS belongs to the performer of encounter
validate that drfo from DS and party.drfo of performer matches
Validate that performer of encounter is a current user
validate that one of users employee is a performer of encounter
validate that client_id from token == PRM.performer.legal_entity
Validate encoded signed content according to JSON Schema (link)
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
Validate encounter id as a primary key (Primary Key Validation)
Validate that the date is within acceptable limits
$.encounter.date<= current_date
$.encounter.date>=current_date-encounter_max_days_passed
Validate "episode" is an active episode that belongs to the current patient
$.encounter.episode.identifier.value is one of ME.patinet{patient_id}.episodes{*}.id
in case of error return 422 "Episode with such ID is not found"
$.encounter.episode.identifier.value is an ID of an Episode that meets the requirements:
ME.patient{patinet_id}.episodes{episode_id}.status = 'active'
in case of error return 422 "Episode is not active"
ME.patient{patinet_id}.episodes{episode_id}.managing_organization==token.client_id
in case of error return 422 "Managing_organization in the episode does not correspond to user`s legal_entity"
Validate "visit" is a visit that belongs to the current patient
$.encounter.visit.identifier.value=$.visit.id OR ID of already existing Visit in ME.patient{patient_id}.visit.id
in case of error return 422 "Visit with such ID is not found"
Validate referrals
As a referral it can be referenced electronic (registered in the system) OR paper service request
Validate ($.encounter.incoming_referrals OR $.encounter.paper_referral) or none in request
Validate incoming referrals as References (Submit Encounter Data Package#Referencevalidation)
Validate paper referral as Object (paper_referral)
Validate incoming referrals that corresponds to $.encounter.incoming_referrals[*].identifier.value have:
..used_by_legal_entity.identifier.value==token.client_id OR null
in case of error return 409 "Service request is used by another legal_entity"
..status==active or program_processing_status=in_progress (any status is valid in case program_processing_status= in_progress)
in case of error return 409 "Invalid service request status"
..if program is defined program_processing_status=new, in_queue or in_progress
check that service_request contains based_on parameter
in case based_on present in service_request
verify care_plan:
It should be in active status
Care plan's period end (if exist) should be greater than current date or equal.
verify activity:
It has activity.detail.kind=service_request; activity.detail.product_reference=service_id.
It has scheduled, in_progress status
in case based_on not present in request skip previous validations.
Validate performer
$.encounter.performer.identifier.value is an ID of existing employee in PRM.Employees
in case of error return "There is no Employee with such id"
$.encounter.performer.identifier.value == PRM.Employees.id where (PRM.Employees.status==`active`)
in case of error return "Employee is not active"
$.encounter.performer.identifier.value == PRM.Employees.id where (PRM.Employees.legal_entity== client_id)
"User can not create encounter for this legal_entity"
validate employee type according to encounter.class - use config file (employee_encounter_classes)
in case error return
409, "invalid employee type"422, "Employee.type $type is forbidden for your encounter class"
according to employee.type as stated in employee_encounter_types
in case error return 422, msg "Employee.type $type is forbidden for your encounter type"
division
$.encounter.division.identifier.value must meet the following requirements
PRM.division.status = "ACTIVE"
in case of error return 409 "Division is not active "
PRM.division.legal_entity= token.client_id
in case of error return 409 "User is not allowed to create encouners for this division"
Validate supporting_info as References (Submit Encounter Data Package#Referencevalidation)
Validate encounter.class
according to legal_entity.type - use config file (legal_entity_encounter_classes)
in case error return 409, msg "Encounter.class $class is forbidden for your legal entity type"
according to episode.type - use config file (episode_type_encounter_classes)
in case error return 409, msg "Encounter.class $class is forbidden for your episode type"
according to employee.type as stated in (employee_encounter_classes)
in case error return 409, msg "Encounter.class $class is forbidden for your employee type"
Validate encounter.type
according to encounter.class - use config file (encounter_class_encounter_types)
in case error return 409, msg "Encounter.type $type is forbidden for your encounter class"
Validate actions
Validate actions presence according to encounter class validations
in case error return '422', msg 'TBC'
Defined in the system that corresponds to encounter class validations
in case error return '422', msg 'TBC'
Validate action_references
Note. For encounter.action_references pass only "service", and the "service_group" does not passValidate action_references presence according to encounter class validations
in case error return '422', msg 'At least one of action references, diagnostic reports or procedures should exist in encounter package'
Validate code as a Reference(Submit Encounter Data Package#Referencevalidation)
Validate action_references is in prm.services, has status ACTIVE and is_active = true
in case error return '422', msg 'Service with such ID is not found'
in case error return '422', msg 'Service should be active'
Validate diagnoses
Validate conditions as References (Submit Encounter Data Package#Referencevalidation)
Validate encounter has exactly one diagnosis where $.encounter.diagnoses[?(@.role.coding[0].code=="primary")]
in case of error return 422 "Encounter must have exactly one primary diagnosis"
Validate condition.id is in DB or in current Encounter package
Validate that each condition is active (verification_status != entered_in_error)
in case of error return 409 "Conditions in diagnoses must be active"
Validate that primary diagnosis defined in the system that corresponds to encounter class validations
in case of error "Primary diagnosis should be defined in {$.encounter.diagnoses[*].role.coding[*].system } system"
Validate reasons
Validate reasons presence according to encounter class validations
in case error return '422', msg 'Validation failed. You can find validators description at our API Manifest: http://docs.apimanifest.apiary.io/#introduction/interacting-with-api/errors .', description 'can't be blank.
Validate hospitalization
Validate hospitalization presence according to encounter class validations
in case error return 422, msg "Hospitalization block is forbidden for encounter.class = $encounter.class"
Validate all fields according to schemata
destination
discharge_disposition
pre_admission_identifier
admit_source
re_admission
discharge_department
If encounter.type.code = "discharge" than encounter.hospitalization.admit_source is required, encounter.hospitalization.discharge_disposition is required, encounter.hospitalization.discharge_department is required
in case error return 422, msg "<parameter> is required for encounter.type.code = "discharge"
Validate destination is a valid legal_entity in prm with status is ACTIVE and is_active = true
in case error return 422, "Legal entity is not active"
Validate patient_id for encounter.type == "patient_identity"
$patient_id should exist in mpi.prepersons.id, have status =='ACTIVE' and is_active = true
in case error return 'TBC', msg 'TBC'
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
If service_requests.code.identifier.value is service, validate $resourse.code.identifier.value = service_requests.code.identifier.value
in case error return 409, "Service in $resourse differ from service in service request"
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')
in case error return 409, "Service in $resourse differ from services in service request's service_group"
Validate $resourse.service.is_active = true
in case error return 409, "Service should be active"
If patient is person - validate verification status:
If encounter has incoming referral with service request, then skip this validation.
Else check patient's verification_status is not equal to NOT_VERIFIED.
in case NOT_VERIFIED - return error 409, "Patient is not verified"
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
Validation | PHC | AMB | INPATIENT |
---|---|---|---|
employees.type | as stated in config file employee_encounter_classes | ||
encounter.type | as stated in config file encounter_class_encounter_types | ||
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 |
|
|
|
hospitalisation | is absent in request | is absent in request | if encounter.type == "discharge" - this block is mandatory
For other encounter types
|
action_references | is absent in request | if encounter.type == "patient_identity"
For other encounter types
| if encounter.type == "patient_identity"
For other encounter types
|
division | Division must be filled |
Validate Conditions
Validate conditions ids as primary keys (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of conditions is a current encounter
$.conditions[*].context.identifier.value == $.encounter.id
in case of error return "Submitted context is not allowed for the condition"
Validate code depending on encounter class
if $.encounter.class = PHC - allowed both eHealth/ICPC2/condition_codes and eHealth/ICD10_AM/condition_codes
if $.encounter.class in (AMB, INPATIENT) - allowed only eHealth/ICD10_AM/condition_codes
Validate code.coding depending on the qty of codes
Maximum one code from one dictionary (eHealth/ICPC2/condition_codes and eHealth/ICD10_AM/condition_codes) is allowed
in case of error return 422 with msg "Only one code from one dictionary is allowed"
$.condition[*].onset_date>=current_date-condition_max_days_passed
in case of error "Onset date must be greater than {{current_date-condition_max_days_passed}}"
$.conditions[*].onset_date <= current_date
in case of error "Onset date must be in past"
Validate that the date is within acceptable limits
in case of error "Onset date must be in past"
$.conditions[*].asserted_date <= current_date
in case of error "Asserted date must be in past"
$.conditions[*].evidences[*].detail[*].identifier.value is an ID of existing observation in MedicalEvents.Observations or one of $.observations[*]
in case of error 409 "Observation with such id is not found"
$.conditions[*].evidences[*].detail[*].identifier.value meet follownig conditions
MedicalEvents.Observation.Patient == patient_id (from url)
Error 409 "Evidence can not reference another patient"
MedicalEvents.Observation.Status != "entered_in_error"
Error 409 "Observation in "entered_in_error" status can not be used as an evidence"
Validate asserter.
$.conditions.asserter.identifier.value is an ID of one of users employee
in case of error return "Employee is not performer of encounter"
according to logic Submit Encounter Data Package#Performer(asserter)validation
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>')
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>')
Validate Observations
Validate observations ids as primary keys (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of observation is a current encounter
$.observations[*].context.identifier.value==$.encounter.id
in case of error return "Submitted context is not allowed for the observation"
Validate that the date is within acceptable limits
$.observations[*].issued <= current_time
in case of error return "Issued date must be in past"
$.observations[*].issued>=current_date-observation_max_days_passed
in case of error "Issued must be greater than {{current_date-observation_max_days_passed}}"
Validate performer(asserter)
Validate$.observations[*].components[*].value_period as a Period
Validate $.observations[*].value_quantity
$.observations[*].value must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].comparator can take the following values : [">", ">=", "=", "<=", "<"]
in case of error return "value is not allowed in enum"
$.observations[*].unit can take values from dictionary eHealth/ucum/units
in case of error return "value is not allowed in enum"
Validate $.observations[*].value_codeable_concept
$.observations[*].code validate that the code belongs to the dictionary system
in case of error return "Value is not allowed in enum"
Validate $.observations[*].value_boolean
$.observations[*].value_boolean must be boolean type
in case of error return "type mismatch. Expected boolean but got {entered type}"
Validate $.observations[*].value_string
$.observations[*].value_string must be string type
in case of error return "type mismatch. Expected string but got {entered type}"
Validate $.observations[*].value_sampled_data
$.observations[*].data must be string type
in case of error return "type mismatch. Expected string but got {entered type}"
$.observations[*].origin must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].period must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].factor must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].lower_limit must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].upper_limit must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
$.observations[*].dimensions must be with number type
in case of error return "type mismatch. Expected number but got {entered type}"
Validate $.observations[*].value_range
$.observations[*].low must be with object type
in case of error return "type mismatch. Expected object but got {entered type}"
$.observations[*].high must be with object type
in case of error return "type mismatch. Expected object but got {entered type}"
Validate $.observations[*].value_ratio
$.observations[*].numerator must be with object type
in case of error return "type mismatch. Expected object but got {entered type}"
$.observations[*].denominator must be with object type
in case of error return "type mismatch. Expected object but got {entered type}"
Validate $.observations[*].value_time
$.observations[*].value_time must be with string type
in case of error return "type mismatch. Expected string but got {entered type}"
Validate $.observations[*].value_date_time
$.observations[*].value_date_time must be with string type
in case of error return "type mismatch. Expected string but got {entered type}"
Validate diagnostic report is one of reports in the current package
$.observations[*].diagnostic_report.identifier.value == one of $.diagnostic_report[*].identifier.value
in case of error "Invalid reference"
Validate $.observations[*].reaction_on
check that the appropriate immunizations.status != "entered_in_error"
in case of error return 409 "Immunization with status ‘entered_in_error’ can not be use"
Validate $.observations.code
if observations.code.coding[*].code value is included in chart variables 'OBSERVATION_CODES_WITH_<VALUE_TYPE>_REQUIRED', <value_type> field is mandatory
in case of error return 422 “This field is required for code = <code>“
Validate observations for encounter.type == "patient_identity"
EDP with type == "patient_identity" should have list of special observations.
Such list can contain limited set of codes, some of them are mandatory
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 Immunizations
Validate immunizations ids as primary keys (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of immunizations is a current encounter
$.immunizations[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the immunization"
Validate that the date is within acceptable limits
$.immunizations[*].date <= current_time
in case of error "Date must be in past"
$.immunizations[*].date>=current_date-immunization_max_days_passed
in case of error "Date must be greater than {{current_date-immunization_max_days_passed}}"
Validate performer according to the Rule
Validate that observation submitted as a detail of reaction is an existing observation that belongs to the current patient
$.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
in case of error return 422 "There is no observation with such id"
Validate Allergy Intolerances
Validate allergy intolerances ids as primary keys (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of allergy_intolerances is a current encounter
$.allergy_intolerances[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the allergy_intolerances"
Validate asserter according to the Rule
Validate that the date is within acceptable limits
$.allergy_intolerances[*].onset_date_time<= current date_time
in case of error "Onset date time must be in past"
$.allergy_intolerances[*].onset_date_time>=current_date-allergy_intolerance_max_days_passed
in case of error "Onset date time must be greater than {{current_date-allergy_intolerance_max_days_passed}}"
Validate that asserted_date is in past
$.allergy_intolerances[*].asserted_date<= current date_time
in case of error "Asserted date must be in past"
Validate that last_occurrence is in past
$.allergy_intolerances[*].last_occurrence<= current date_time
in case of error "Last occurrence must be in past"
Validate Risk Assessments
Validate risk assessment id as a primary key (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of risk_assessments is a current encounter
$.risk_assessments[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the risk_assessments"
Validate that asserted_date is within acceptable limits
$.risk_assessments [*].asserted_date<= current date_time
in case of error "Asserted date must be in past"
$.risk_assessments [*].asserted_date>=current_date-risk_assessment_max_days_passed
in case of error "Asserted date must be greater than {{current_date-risk_assessment_max_days_passed}}"
Validate performer according to the Rule
validate performer is an active doctor from current legal_entity
$..performer.identifier.value is an ID of existing employee in PRM.employee
in case of error "Employee with such id is not found"
$..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" and PRM.employees.employee_type=="DOCTOR")
"Employee is not an active doctor"
Validate only one of these fields are filled: reason_reference , reason_codeable_concept
Validate reason_reference as a Reference(Submit Encounter Data Package#Referencevalidation)
Validate basis as a Reference(Submit Encounter Data Package#Referencevalidation)
Validate when_period as a Period (Submit Encounter Data Package#period_validationPeriodValidation)
Validate only one of the fields is filled: prediction.when_period or prediction.when_range
Validate only one of the fields is filled: prediction.probability_decimal or prediction.probability_range
Validate Devices
Validate device id as a primary key (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of devices is a current encounter
$.devices[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the device"
Validate that asserted_date is within acceptable limits
$.devices[*].asserted_date<= current date_time
in case of error "Asserted date must be in past"
$.devices[*].asserted_date>=current_date-device_max_days_passed
in case of error "Asserted date must be greater than {{current_date-device_max_days_passed}}"
Validate asserter according to the Rule
Validate usage_period as a period (Submit Encounter Data Package#period_validationPeriodValidation)
Validate Medication Statement
Validate medication statement id as primary key (Submit Encounter Data Package#Primarykeyvalidation)
Validate that context of medication statement is a current encounter
$.medication_statements[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the medication statement"
Validate that asserted_date is within acceptable limits
$.medication statements[*].asserted_date<= current date_time
in case of error "Asserted date must be in past"
$.medication statements[*].asserted_date>=current_date-medication statement_max_days_passed
in case of error "Asserted date must be greater than {{current_date-medication statement_max_days_passed}}"
Validate asserter according to the Rule
Validate based_on as a Reference(Submit Encounter Data Package#Referencevalidation) to OPS.medication_request
Validate Medication Administration
Validate medication statement id as primary key (Submit Encounter Data Package#Primarykeyvalidation)
Validate part_of
validate procedure or medication_administration is made for the same patient
procedure.patient_id=@person_id
medication_administration.patient_id=@person_id
in case error return 409 "Procedure/Medication administration was made for another person"
validate procedure or medication_administration is not in status `entered_in_error`
in case error return 409, "Procedure/Medication administration is not active"
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"
Validate medication
validate that medication is of type 'BRAND'
in case error return 422, "Medication should be of type brand"
medication corresponds to the INNM_DOSAGE medication from request.medication
"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"
Validate that context of medication administration is a current encounter
$.medication_administration[*].context.identifier.value == $.encounter.id
in case of error "Submitted context is not allowed for the medication administration"
validate performed_date_time <= now()
in case error return 422, "performed_date_time should be in the past"
Validate performer according to the Rule
validate performer is an active doctor from current legal_entity
$..performer.identifier.value is an ID of existing employee in PRM.employee
in case of error "Employee with such id is not found"
$..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" and PRM.employees.employee_type in ("DOCTOR","SPECIALIST"))
"Employee is not an active doctor"
validate reason_references
validate Condition|Observation|DiagnosticReport as Reference
validate Condition|Observation|DiagnosticReport is not in status "entered_in_error"
in case error return 409, "Reason reference should be active"
validate Condition|Observation|DiagnosticReport is made for the same person
in case error return 409, "Reason reference was made for another person"
validate Condition|Observation|DiagnosticReport exist in DB or in payload
in case error return 422, "Condition|Observation|DiagnosticReport with such id is not found"
Validate request
validate medication_request as a reference
validate medication_request is in active status. medication_request.status='ACTIVE' and is_active=true
in case error return 409, "medication request is not active"
validate medication request is made for the same person
in case error return 409, "medication request was made for another person"
Validate medication_request.started_at < now()
in case error return 409, "Medication request started at should be in the past"
Validate dosage
Validate Diagnostic Report
Validate diagnostic reports ids as primary keys (Submit Encounter Data Package#Primarykeyvalidation)
Validate based_on as Reference(Submit Encounter Data Package#Referencevalidation)
Validate that service_request, referenced as based_on, is
in status is
active
or program_processing_status=in_progress (any status is valid in case program_processing_status= in_progress)in case of error return 409 "Invalid service request status"
if program is defined than used_by_legal_entity==token.client_id OR null
in case of error return 409 "Service request is used by another legal_entity"
if program is defined than program_processing_status == new, in_queue or in_progress
check that service_request contains based_on parameter
in case based_on present in service_request
verify care_plan:
It should be in active status
Care plan's period end (if exist) should be greater than current date or equal.
verify activity:
It has activity.detail.kind=service_request; activity.detail.product_reference=service_id.
It has scheduled, in_progress status
in case based_on not present in request skip previous validations.
category
Validate that one of diagnostic reports categories corresponds to service category, that is references as code in DR
$.diagnostic_report.category[?]=PRM.services.category where PRM.services.id=$.diagnostic_report.code.identifier.value
in case of error return 422 "None of the diagnostic report categories matches with the service category"
Validate code
Validate code as Reference(Submit Encounter Data Package#Referencevalidation)
If service_requests.code.identifier.value is service, validate $diagnostic_report.code.identifier.value = service_requests.code.identifier.value
in case error return 409, "Service in diagnostic_report differ from service in service request"
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')
in case error return 409, "Service in diagnostic_report differ from services in service request's service_group"
Validate diagnostic_report.service.is_active = true
in case error return 409, "Service should be active"
Validate effective_period as a period (Submit Encounter Data Package#period_validationPeriodValidation)
Validate that issued is within acceptable limits
$.diagnostic_reports[*].issued<= current date_time
in case of error 422 "Asserted date must be in past"
$.diagnostic_reports[*].issued>=current_date-diagnostic_report_max_days_passed
in case of error 422 "Issued must be greater than {{current_date-diagnostic_report_max_days_passed}}"
Validate recorded_by as Employee (Submit Encounter Data Package#Employeevalidation)
Validate encounter
$.diagnostic_reports[*].encounter.identifier.value == $.encounter.id
in case of error 409 "Invalid reference"
Validate performer.identifier as Employee (Submit Encounter Data Package#Employeevalidation)
Validate managing_organization is a current legal_entity
$.managing_organization.identifier.value==token.client_id
in case of error 409 "Managing organization does not correspond to user's legal entity."
Validate result_interpreter.identifier as Employee (Submit Encounter Data Package#Employeevalidation)
Validate result_interpreter.identifier is an employee with employee_type = DOCTOR or SPECIALIST
Validate only One of the fields is filled:
$.diagnostic_report[*].results_interpreter.reference OR $.diagnostic_report[*].results_interpreter.text
$.diagnostic_report[*].performer.reference OR $.diagnostic_report[*].performer.text
Validate primary_source
If primary_source==true, then
Managing organization MUST be filled
If primary_source==false, then
report_origin OR performer.text must be filled
performer.reference must NOT be filled
results_enterpreter.reference must NOT be filled
If patient is person - validate verification status:
If diagnostic report has based_on with service request, then skip this validation.
Else check patient's verification_status is not equal to NOT_VERIFIED.
in case NOT_VERIFIED - return error 409, "Patient is not verified"
Validate Procedures
Validate by json schema
Validate procedure id as primary key (Submit Encounter Data Package#Primarykeyvalidation)
Validate code
Validate code as Reference(Submit Encounter Data Package#Referencevalidation)
Validate procedure.service.is_active = true
in case error return 409, "Service is not active"
Validate that service_request, referenced as based_on, is
check that service_request contains based_on parameter
in case based_on present in service_request
verify care_plan:
It should be in active status
Care plan's period end (if exist) should be greater than current date or equal.
verify activity:
It has activity.detail.kind=service_request; activity.detail.product_reference=service_id.
It has scheduled, in_progress status
in case based_on not present in request skip previous validations.
Validate encounter
$.procedure[*].encounter.identifier.value == $.encounter.id
in case error return 409, "Submitted encounter is not allowed for procedure"
Validate performed_date_time
performed_date_time is real
in case error return 422, "Performed_date_time in invalid"
performed_date_time <= now
in case error return 422 "Procedure cannot be registered in future"
Validate recorded_by
Validate recorded_by as Reference(Submit Encounter Data Package#Referencevalidation)
$..recorded_by.identifier.value is an ID of existing employee in PRM.employee
in case of error return 422, "Employee with such id is not found"
Validate recorded_by is employee with status='APPROVED' and is_active= true and end_date is null or more than today
in case error return 409, "This action is prohibited for current employee"
Validate employees.legal_entity_id=$managing_organization.identifier.value
in case error return 409, "Employee should be from current legal entity"
Validate asserter
Validate division
Validate division as Reference (Submit Encounter Data Package#Referencevalidation)
$division is an ID in PRM.divisions
in case return 422, "Division with such id is not found"
division.status=ACTIVE and is_active=true
in case error return 409, "Division is not active"
division.legal_entity_id = $client_id or division.legal_entity_id=$managing_organization.identifier.value
in case error return 409, "Division is not in current legal_entity"
Validate managing_organization is a current active legal_entity with proper type
as Reference (Submit Encounter Data Package#Referencevalidation)
$managing_organization is an ID in PRM.legal_entities
in case return 422, "Legal entity with such id is not found"
validate managing_organization status is 'ACTIVE' and is_active=true
in case error return 422 ('Legal entity is not active')
validate legal_entity type is in ('PRIMARY_CARE','MSP','MSP_PHARMACY','MSP_PHARMACY') (use `ME_ALLOWED_TRANSACTIONS_LE_TYPES` from charts)
in case error return 422, "Legal entity with type $legal_entity.type cannot perform procedures"
validate $managing_organization.identifier.value = $client_id
in case of error 409 "Managing organization does not correspond to user's legal entity."
Validate reason_references
Validate reason_reference as a Reference (Submit Encounter Data Package#Referencevalidation)
Validate reason_refernce.identifier.value is condition not in status `entered_in_error`
in case error return 422, "Condition is canceled"
Validate outcome
validate outcome as a Reference (Submit Encounter Data Package#Referencevalidation)
validate outcome.coding.object.system is in dictionary eHealth/procedure_outcomes
in case error return 422, "outcome not in dictionary eHealth/procedure_outcomes"
Validate complication_details
validate complication_details as a Reference (Submit Encounter Data Package#Referencevalidation)
validate complication_details.identifier.value refer to condition in the same encounter package
in case error return 422, "complication_details does not correspond to condition in this encounter package"
Validate category
according to the dictionary 'eHealth/procedure_categories' - by schemata
Validate that procedure category corresponds to service category, that is references as code in procedure
$.procedure.category=PRM.services.category where PRM.services.id=$.procedure.code.identifier.value
in case of error return 422 "Procedure category does not match with the service category"
If patient is person - validate verification status:
If procedure has based_on with service request, then skip this validation.
Else check patient verification_status is not equal to NOT_VERIFIED.
in case NOT_VERIFIED - return error 409, "Patient is not verified"
Validate Clinical impression
Validate by json schema
Validate clinical impression id as primary key (Primarykeyvalidation)
Validate status
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')
Check it has value = completed
in case of error - return 422 ('value is not allowed in enum')
Validate code
Check that the code belongs to the dictionary system (eHealth/clinical_impression_patient_categories)
in case of error - return 422 ('value is not allowed in enum')
Validate code.coding depending on the qty of codes. Maximum one code is allowed
in case of error - return 422 ('Only one code is allowed')
Check by code.coding[0].code and code.coding[0].system active rules in rule_engine_rules collection
in case any active rules present - check request only with following validations
in case rule present in collection - check request with following validations and with additional from rule engine rule
Validate description
Check that value with string type
in case of error - return 422 ('type mismatch. Expected string but got {entered type}')
Validate encounter
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')
Check the value is valid reference on encounter resource
Check that $.clinical_impressions[*].encounter.identifier.value == $.encounter.id
in case error - return 422 ('Invalid reference')
Validate effective_period as a period (PeriodValidation)
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')
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}}')
Validate effective_date_time
Check that field $.effective_date_time with string type
in case of error - return 422 ('type mismatch. Expected string but got {entered type}')
Check that field $.effective_date_time <= current_time
in case of error - return 422 ('Date must be in past')
Check that field $.effective_date_time >= 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}}')
Validate assessor
Validate assessor as Reference (Referencevalidation)
$.assessor.identifier.value is an ID of existing employee in PRM.employee
in case of error - return 422 ('Employee with such id is not found')
Validate assessor is employee with status='APPROVED' and is_active= true and end_date is null or more than today
in case of error - return 422 ('Invalid employee status')
Validate previous
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')
Validate problems
Check that value is an array with references of type condition
in case of error - return 422 ('value is not allowed in enum')
Check that each condition is active (verification_status is not entered_in_error)
in case of error - return 422 ('Condition in "entered_in_error" status can not be referenced')
Check the value is valid reference on condition resource
Check that encounter belongs to patient ($.subject)
in case of error - return 422 ('Condition with such id is not found')
Validate finding
Check that value is an array with objects
Validate item_reference
Check that value is an object with reference of resource condition, observation (further <Medical event resource>)
in case of error - return 422 ('value is not allowed in enum')
Check that <Medical event resource> is active (status is not entered_in_error)
in case of error - return 422 ('<Medical event resource> in "entered_in_error" status can not be referenced')
Check that each reference:
is valid ME of defined type above
belongs to the patient ($.subject)
in case of error - return 422 (<Medical event resource> with such ID is not found')
Validate basis
Check that value with string type
in case of error - return 422 ('type mismatch. Expected string but got {entered type}')
In case some rules present in collection rule_engine_rules validate them
in case of error - return 422 ('Value is not correspond to rule engine rule')
Validate supporting_info
Check that value is an array with references of type episode_of_care, procedure, diagnostic report, encounter (further <Medical event resource>)
in case of error - return 422 ('value is not allowed in enum')
Check that <Medical event resource> is active (status is not entered_in_error)
in case of error - return 422 ('<Medical event resource> in "entered_in_error" status can not be referenced')
Check that each reference:
is valid ME of defined type above
belongs to the patient ($.subject)
in case of error - return 422 (<Medical event resource> with such ID is not found')
In case some rules present in collection rule_engine_rules validate them
in case of error - return 422 ('Value is not correspond to rule engine rule')
Validate note
Check that value with string type
in case of error - return 422 ('type mismatch. Expected string but got {entered type}')
Validate patient
In case some rules present in collection rule_engine_rules validate them
in case of error - return 422 ('Value is not correspond to rule engine rule')
Primary key validation
Validate that IDs of all submitted entities in the array are unique
validate that $.{collection}[*].id from the payload are all unique among themselves
in case of error return 409 "All primary keys must be unique"
validate there is no entity with such id in the corresponding Medical events collection
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.
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
in case of errror return 422 "There is no {$..identifier.type.coding[0].code} with such id"
Validate that this entity is not in status entered_in error
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
case $..primary_source==true
$..performer(or $..asserter) must be filled
in case of error "Performer (asserter) must be filled"
$..report_origin must be absent
in case of error "Report_origin can not be submitted in case primary_source is true"
validate performer(asserter) is a valid value from corresponding dictionary
$..performer.identifier.type.coding[*].system == "eHealth/resources"
in case of error "Submitted system is not allowed for this field"
$..performer.identifier.type.coding[*].code=="employee"
in case of error "Submitted code is not allowed for this field"
validate performer(asserter) is a active employee from current legal_entity
$..performer.identifier.value is an ID of existing employee in PRM.employee
in case of error "Employee with such id is not found"
$..performer.identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" and PRM.employees.employee_type=="DOCTOR" or "SPECIALIST" or "ASSISTANT")
case primary_source==false
$..report_origin must be filled
in case of error "Report_origin must be filled"
if $..primary_source==false then $..performer(asserter) must be absent
in case of error "Performer(asserter) can not be submitted in case primary_source is false"
validate report_origin
$..report_origin.coding[*].system == "eHealth/report_origins"
in case of error "Submitted system is not allowed for this field"
Period Validation
$..period.start <= current_dateTime
in case of error return 422- "Start date must be in past"
if $..period.end is filled:
$..period.end > visit.period.start
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.
$...identifier.value exists in PRM.employees
in case of error 409 "Employee not found"
$...identifier.value == PRM.employees.id where (PRM.employees.status == "APPROVED" and PRM.employees.legal_entity==token.client_id)
in case of error 409 "Submitted employee is not an active employee from current legal entity"
Related care plan validation
If entities (encounter.incoming_referral, procedure.based_on, diagnostic_report.based_on) has reference on service request and service_request[].activity.detail.quantity was set - check possibility to create EDP depending on service_request[].activity remaining quantity
calculate the quantity of artifacts that are contained in the $.activity.outcome_reference by service_request.based_on[].activity[].id
calculate the quantity of artifacts that are contained in the request and have a link to the service request
compare quantity from outcome_reference with the artifact quantity
check that difference is greater then or equal to zero
in case of error return 409 "The total amount of the prescribed service quantity exceeds quantity in care plan activity"
Postprocessing
Save signed_content to Media Storage
Save data to corresponding collections in DBs
Save link to the signed content to the encounter
Enrich encounter.diagnoses:
select condition.code from Medical Events DB(or from request body) where condition.id==diagnoses[@].condition.identifier.value
set diagnoses[@].code = select 1
Save diagnoses from encounter to episodes.current_diagnoses
ME.patients.episodes.diagnoses = $.encounter.diagnoses
Add a record to the ME.patient.episodes{episode_id}.diagnoses_hstr
date = current_date
evidence = reference to encounter ($.encounter.id)
diagnoses = $.encounter.diagnoses
Set display_value to employees for all submitted objects
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))
ME.patients.encounters{encounter_id}.performer.display== Select 1
ME.conditions{condition_id}.asserter.display == Select 1
ME.observations{observation_id}.performer.display == Select 1
ME.patients.immunizations{immunization_id}.performer.display == Select 1
ME.patients.allergy_intolerance{ai_id}.asserter.display == Select 1
ME.patients.devices{device_id}.asserter.display == Select 1
ME.patients.medication_statements{ms_id}.asserter.display == Select 1
ME.patients.risk_assessment{rs_id}.asserter.display == Select 1
ME.patients.diagnostic_reports{dr_id}.performer.reference.display == Select 1
ME.patients.diagnostic_reports{dr_id}.recorded_by.reference.display == Select 1
ME.patients.diagnostic_reports{dr_id}.results_interpreter.reference.display == Select 1
In case there are reactions ($.observations[?].reaction_on) in the request, update corresponding immunizations with the reactions:
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
Set display_value for legal_entities
ME.patients.diagnostic_reports{dr_id}.managing_organization.display
Set managing_organization for submitted observations, conditions, encounter
ME.conditions{cond_id}.managing_organization=token.client_id
ME.observations{observ_id}.managing_organization=token.client_id
ME.encounters{encounter_id}.managing_organization=token.client_id
In case encounter.incoming_referral was filled, set episode_origin to encounter
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))
In case diagnostic_reports.based_on was filled, set episode_origin to diagnostic report
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))
In case encounter.incoming_referral was filled set $.encounter.id to related to $.service_request activity[].outcome_reference
In case procedures.based_on was filled set $.procedures.id to related to $.service_request $.activity[].outcome_reference
In case diagnostic_reports.based_on was filled set $.diagnostic_reports.id to related to $.service_request activity[].outcome_reference
Update $ .activity.status to in_progress if previous activity status was scheduled
Update the $ .activity.remaining_quantity parameter by subtracting the quantity of artifacts that have a reference on service request that contains an $.based_on.[]activity
Enrich encounter data with performer speciality:
SELECT speciality -> 'speciality' FROM employees WHERE speciality ->> 'speciality_officio' = 'true' AND id = $.encounter.performer.identifier.value
Set encounter.performer_speciality as CodeableConcept type with system = SPECIALITY_TYPE
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)