Table of Contents | ||
---|---|---|
|
...
Only authenticated and authorized employee with appropriate scope can create a Composition.
Request should be signed with DS.
The composition is created asynchronously.
The composition can be created both for persons and for prepersons.
When system validate resource and for current composition type config non exist, system skip validation
All validations using dictionaries apply only to those dictionary values where is_active=true
Specification
...
be created both for persons and for prepersons.
When system validate resource and for current composition type config non exist, system skip validation
All validations using dictionaries apply only to those dictionary values where is_active=true
Specification
Example for Dummy Submit Composition
Type: DRIVERS Category: DRIVERS_GROUP1
Expand | ||
---|---|---|
| ||
|
Type: DRIVERS Category: DRIVERS_GROUP2
Expand | ||
---|---|---|
| ||
|
Type: ADOPTION Category: ADOPTER
Expand | ||
---|---|---|
| ||
|
Type: ADOPTION Category: ADOPTER_RELATIVE
Expand | ||
---|---|---|
| ||
|
Authorization
Verify the validity of access token
in case of error - return 401 (“Invalid access token”) in case of validation fails
Verify that token is not expired
in case of error - return 401 (“Invalid access token”)
Check user and client scopes in order to perform this action (scope = 'composition:write')
return 403 (“Your scope does not allow to access this resource. Missing allowances: composition:write”) in case of invalid scope(s)
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")
If BLOCK_DECEASED_PARTY_USERS is true, check that party is not deceased (party_verification record does not equal to: dracs_death_verification_status = VERIFIED and dracs_death_verification_reason = MANUAL_CONFIRMED):
in case of error - return 403 ("Access denied. Party is deceased")
...
a. get config by type and category (of composition) from [prm
].composition
а.1 in case there is no record in PRM.configurations with requested combination of type and category return 422 - (“Category {{Composition.category}} is not allowed for type {{Composition.type}}”)
b. get setting and compare config.condition data to composition data to find the desired setting (in case when some values isn’t exist - skip validation)
c. compare data from config.check with data from composition
...
Expand | ||
---|---|---|
|
...
Expand | ||
---|---|---|
|
...
Check (7) possibility to create composition for PREperson - COMPOSITION_PREPERSON_ALLOW.
Return 422 ("Forbidden to create composition with such category for preperson") in case of error
Validate (10) person age between min and max values in config - COMPOSITION_PERSON_AGE.
Skip this validation in case the patient is preperson with an empty age parameter
Calculating logic of person age:
...
Check employee data who sign composition. Get employee data from Composition.attester and execute next validations:
Check
composition.Attester.mode.coding.system
= "eHealth/compositionCOMPOSITION_attesterATTESTER_modesMODES"
&composition.attester.mode.coding.code
is a value from dictionary eHealth/compositionCOMPOSITION_attesterATTESTER_modesMODESCheck (18) that attester of composition work in same LE as custodian parameter:
сomposition.attester
legal_entity_id =composition.custodian
Return 422 ("Attester of composition must work in same LE as custodian") in case of error
Check (19) that attester employee is in active status
Return 422 ('Attester is not active') in case of error
Check (19.1) that
composition.attester
array has only one itemReturn 422 ("Only one attester for composition must be submitted") in case of error
Extract (21) user_id from token. Check that attester belongs to the employee user who sign composition.
Return 422 ('Attester id doesn’t belongs to employee id from token') in case of error
...
Check (20) that attester verification status based on config - COMPOSITION_ATTESTER_VERIFICATION_STATUS.
Return 422 ("Employee with such verification status can’t sign composition") in case of error
Check (17) that author of composition work in same LE with attester:
сomposition.author.legal_entity_id
=composition.attester.legal_entity_id
. Need validate when "sign_check" value = true - COMPOSITION_ATTESTER_SIGN_CHECK.Return 422 ("Author and Attester of composition must work in same LE as custodian") in case of error
Check (22) that attester type based on config - COMPOSITION_ATTESTER_TYPE.
Return 422 ("Forbidden to create composition with this attester type") in case of error
Check (23) that attester position based on config - COMPOSITION_ATTESTER_POSITION.
Return 422 ("Forbidden to create composition with this attester position") in case of error
Check (24) that attester speciality is in allowed values from config - COMPOSITION_ATTESTER_SPECIALITY.
Return 422 ("Forbidden to create composition with this attester speciality") in case of error
Check (24.1) that attester has combination of allowed specialisation and position from config - COMPOSITION_ATTESTER_SPECIALITY_POSITION
Return 422 ("Forbidden to create composition with selected referenced attester speciality and position") in case of error
Check (26) that attester main speciality (
employee.accreditation.speciality_officio
= true ) is in allowed values from config - COMPOSITION_ATTESTER_MAIN_SPECIALITYReturn 422 ("Forbidden to create composition with this attester main speciality") in case of error
...
When (39) composition type = “DRIVERS“ and
composition.event.code
= "DRIVERS_GROUP1_ADMIT" or "DRIVERS_GROUP2_ADMIT" -composition.event.period.start
andcomposition.event.period.end
is requiredReturn 422 ("Event period start and period end is required") in case of error
When (40) composition type = “DRIVERS“ and
composition.event.code
= "DRIVERS_GROUP1_DENY" or "DRIVERS_GROUP2_DENY" -composition.event.period.start
is required andcomposition.event.period.end
must be emptyReturn 422 ("Event period start is required and event period end must be empty") in case of error
When (40.1) composition type = “ADOPTION“ and composition.event.code = "ADOPTION_ADOPTER_INELIGIBLE" or "ADOPTION_ADOPTER_RELATIVE_INELIGIBLE" -
composition.event.period.start
is required andcomposition.event.period.end
must be emptyReturn 422 ("Event period start is required and event period end must be empty") in case of error
Check (38.1) all
event.code
must be unique. In case when composition has more than one eventReturn 422 ("Event codes must be unique") in case of error
Check (37.1) that
composition.event.code
corresponds to appropriate dictionary - COMPOSITION_EVENTSReturn 422 ('value is not allowed in enum") in case of error
...
When (25) composition type = “DRIVERS“ check that
event.period
(event.period.end
-event.period.start
) less than duration (depending on person age and compositionevent.code
). Base on config - COMPOSITION_EVENT_PERIOD_DURATION
Calculating logic:composition.event.period.end
-composition.event.period.start
<config.check
valueReturn 422 ("Composition event period duration must be less than <check.value> <check.units>") in case of error
Check (38) all
composition.event.code
in composition - it must corresponds to appropriate config and match with at least one combination of statuses - COMPOSITION_EVENT_CODE
examples:
if composition category = “DRIVERS_GROUP1“ check whatcomposition.event.code
must be:
"DRIVERS_GROUP1_ADMIT"
OR
"DRIVERS_GROUP1_DENY" and “DRIVERS_GROUP2_DENY“if composition category = “DRIVERS_GROUP2“ check that
composition.event.code
match with one of combination:
“DRIVERS_GROUP1_ADMIT“ and “DRIVERS_GROUP2_DENY“
OR
“DRIVERS_GROUP1_ADMIT“ and “DRIVERS_GROUP2_ADMIT“
OR
“DRIVERS_GROUP1_DENY“ and “DRIVERS_GROUP2_DENY“if composition category = “ADOPTERS“ check that
composition.event.code
match with one of combination:
”ELIGIBLE”
OR
”INELIGIBLE”Return 422 ("Invalid event code for current composition category") in case of error
Check (28.1) that
composition.event.period.start
<composition.event.period.end
Return 422 ("Period end of event must be later than event start period") in case of error
13. АuthorizeInform with
Validate value in the field $.authorize_withinform_with, string, optional.
Check that authentication method with type = 'THIRD_PERSON' is submitted in $.authorize_with for person (in composition.subject) that must be authorized by confidant person using following logic:persons age < no_self_registration_age global parameter;persons age between no_self_registration_age and person_full_legal_capacity_age global parameters and person does not have document with type from PERSON_LEGAL_CAPACITY_DOCUMENT_TYPES config parameter;persons age > person_full_legal_capacity_age global parameter and exists at least one active and approved confidant person relationship for person (using following process Check confidant person relationship with person_id = person_id from request - expected :ok, :approved response)in case of error - return 422 ('Authentication method with type THIRD_PERSON must be submitted for this person')
Check that $.
authorize_withinform_with is a valid uuidin case error - return 422 ('string does not match pattern') with uuid regexp
Check that authentication method exists in MPI database,
person_authentication_methods
table (with is_active = true), belongs to the same patient as set in the create composition request, is active (ended_at > now() or ended_at is null) and type != NAin case error - return 422 ('Authentication method doesn't exist, is inactive or does not belong to this person')
Get value of
THIRD_PERSON_CONFIDANT_PERSON_RELATIONSHIP_CHECK
config parameter, if it is set totrue
- for authentication method with type = ‘THIRD_PERSON’ check that person from value is an approved confidant for a patient from create composition request – exists active and approved confidant person relationship between person from request and person_id from authentication method value (using following logic: Check confidant person relationship withperson_id
= person_id from request andconfidant_person_id
= value from auth method - expected:ok, :approved
response)in case of error - return 422 ('
Authentication method doesn't exist, is inactive or does not belong to this person''Auth method is not active or confidant person relationship is invalid')
14. Title
Get count of records in ME.requisition_number where requisition_number is equal to Composition.title and entity is equal to “composition” and type is equal to Composition.type.coding[0].code and patient_id = patient_id from the request
if count = 0 Return 422 ("Composition title is invalid
or expired") in case of error
Check there is no Composition with the same title in the DB
in case of error return 422 “Composition with title <title> already exists“
...
Check (43) count of medical records in
composition.section.entry
<= then value from config - COMPOSITION_SECTION_ENTRY_LIMIT.Return 422 ("Limit of medical records for this composition type and category must be less or equal <RECORDS_LIMIT>") in case of error
Check (41) codes for all records from
composition.section.entry
whereresource.type
= "observation" on prohibited values for composition (all records not include prohibited codes), depends on event codes which included in config - COMPOSITION_SECTION_ENTRY_PROHIBITED_CODES whereconfig.resource_type
= "observation"Return 422 ("Prohibited observation code - <code> in section.entry for current composition") in case of error
Check (41.1) codes for all records from
composition.section.entry
whereresource.type
= "condition" on prohibited values for composition (all records not include prohibited codes), depends on event codes which included in config - COMPOSITION_SECTION_ENTRY_PROHIBITED_CODES whereconfig.resource_type
= "condition"Return 422 ("Prohibited condition code - <code> in section.entry for current composition") in case of error
Check (42) codes for all records from
composition.section.entry
whereresource.type
= "observation" on required values for composition (at least one record composition entry must contain) which depends onsection.code
wich included in config - COMPOSITION_SECTION_ENTRY_REQUIRED_CODES whereconfig.resource_type
= "observation"Return 422 ("Empty required codes in section.entry for current composition") in case of error
Check (42.1) codes for all records from
composition.section.entry
whereresource.type
= "condition" on required values for composition (at least one record composition entry must contain) which depends onsection.code
wich included in config - COMPOSITION_SECTION_ENTRY_REQUIRED_CODES whereconfig.resource_type
= "condition"Return 422 ("Empty required codes in section entry for current composition") in case of error
Check (44 + 45) existing in composition required and optional sections codes which depends on
section.code
- COMPOSITION_SECTION_CONFIG
Logic description:
Find allconfig.code
where parameterconfig.mandatory
= true and compare all codes tocomposition.section.[n].code
. In case when config has nested sections but parametermandatory
= false - don't compare codes to nested sections.
Logic description:in case when object from
config
orconfig.sections.[n]
havemandatory
= true butcomposition.section.code
orcomposition.section.section.[n].code
hasn’t same value inconfig.code
orconfig.sections.[n].code
- return errorin case when
composition.section.code
has code wich hasn’tconfig.code
- return errorReturn 422 ("Invalid section content. Mandatory section
{{code}}
is missed") in case of error with empty required fields
Check (45.1) section codes for nested sections hierarchy from config which depends on config - COMPOSITION_SECTION_CONFIG
Logic description:
Check that all values fromcomposition.section.code
equal toconfig.code
fromconfig.sections
on the same nested level whereconfig.sectionAllowed
= truein case when value from
composition.section.code
hasn’t same values with nestedconfig.code
(fromconfig.sections
) orcomposition.section.code
has codes wich doesn’t exist inconfig.code
(fromconfig.sections
) - return error Return 422 ("Invalid section hierarchy for nested section") in case of error with empty required fields
examples
success case:
Composition -composition.section.code
= MAIN, nested section -composition.section.section.code
= PEDIATRIST
Config -config.sectionAllowed
= true,config.code
= MAIN,config.section.code
= PEDIATRIST
error case 1:
Composition -composition.section.code
= MAIN, nested section -composition.section.section.code
= NURSING
Config -config.sectionAllowed
= true,config.code
= MAIN,config.section.code
= PEDIATRIST
error case 2:
Composition -composition.section.code
= MAIN, nested section -composition.section.section.code
= PEDIATRIST
Config -config.sectionAllowed
= true,config.code
= MAIN,config.section.code
= PEDIATRIST +config.section.code
= MAINCheck (45.2) section content for all sections which depends on section code - COMPOSITION_SECTION_CONFIG
Configuration parameters description:
if
sectionAllowed
= true current section can contain nested sectionsif
isEmpty
= true current section can contain emptyReason parameter instead ofentry
arrayif
containsResources
= true current section can containentry
andorderBy
parameters
Validate section content:
Check that current section contains just one of:
nested
section
parameteremptyReason
parameterentry
parameterin case of error an error return 422 ("Section {{section_code}} must contain one AND only one of: nested
section
,emptyReason
orentry
")
In case section contains
entry
parameter check thatcontainsResources
= truein case
containsResources
= false return 422 ("Section {{section_code}} can not containentry
")
In case section contains emptyReason check that
isEmpty
= truein case
isEmpty
= false return 422 ("Section {{section_code}} can not contain emptyReason")
In case section contains nested
section
check thatsectionAllowed
= truein case
sectionAllowed
= false return 422 ("Section {{section_code}} can not contain nestedsection
")
Check (46) nesting level of sections <= the allowed limit - COMPOSITION_SECTION_NESTING_LEVEL
Return 422 ("Prohibited nested level for composition section") in case of error
Check (47) count of section <= than value from - COMPOSITION_SECTION_COUNT_LIMIT
Return 422 ("Prohibited amount of composition section") in case of error
...
Check (48) composition.section.title
Check that composition.section.title is not empty.
Also check value from COMPOSITION_SECTION_TITLE_MANUAL_FILL config (depends on
composition.section.code
)if config.value = "true" (or section with same code doesn't exist) - don’t validate
composition.section.title
else if value = "false"
get display value from COMPOSITION_SECTION_CODES dictionary where key=
composition.section.code
check
composition.section.title
= display
Return 422 ("Invalid title for composition.section") in case of error
Check (48.1) that section code (
composition.section.code
) corresponds to appropriate dictionary - COMPOSITION_SECTION_CODESReturn 422 ("Section code value is not allowed in enum") in case of error
Check (48.2) that section order by parameter (
composition.section.orderby
) corresponds to appropriate dictionary - COMPOSITION_SECTION_ORDERBYReturn 422 ("Section order by value is not allowed in enum") in case of error
Check (48.3) that empty reason (
composition.section.emptyreason
) corresponds to appropriate config - COMPOSITION_SECTION_EMPTY_REASON. In case whencomposition.section.emptyreason
is not emptyReturn 422 ("Empty reason value is not allowed in enum") in case of error
Check (50) that person from all records in
composition.section.entry
the same ascomposition.subject
(or merged person inmpi.merged_person
)Return 422 ("Person from section.entry must be the same as composition.subject or composition.section.focus") in case of error
Check (54) that author position from
section.author
based on config - COMPOSITION_SECTION_AUTHOR_POSITION for selectedsection.code
Return 422 ("Section author position does not allow to create such composition") in case of error
Check (55) that author speciality from
section.author
based on config - COMPOSITION_SECTION_AUTHOR_SPECIALITY for selectedsection.code
Return 422 ("Section author speciality does not allow to create such composition") in case of error
Check (55.1) that author main speciality (
employee.accreditation.speciality_officio
= true ) fromsection.author
based on based on config - COMPOSITION_SECTION_AUTHOR_MAIN_SPECIALITYReturn 422 ("Section author main speciality does not allow to create such composition") in case of error
Check (56) count of resources from
composition.section.entry
selectedsection.code
- COMPOSITION_SECTION_SECTION_ENTRY_LIMITReturn 422 ("Max count of resources in
section.entry
- <count>") in case of error
Check (56.1) that the resource type of the resource in
composition.section.entry
is allowed by config COMPOSITION_SECTION_SECTION_ENTRY_RESOURCESfor thissection.code
andevent.code
Return 422 ("Resource type is not allowed in this section for this event code") in case of error
...