...
Anchor | ||||
---|---|---|---|---|
|
Validate request using JSON schema
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{ "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "phone": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "MOBILE", "LANDLINE" ] }, "number": { "type": "string", "pattern": "^\\+38[0-9]{10}$" } }, "required": [ "type", "number" ], "additionalProperties": false }, "addressname": { "type": "objectstring", "propertiespattern": {"^(?!.*[ЫЪЭЁыъэё@%&$^#])[a-zA-ZА-ЯҐЇІЄа-яґїіє0-9№\\\"!\\^\\*)\\]\\[(._-].*$" }, "typetax_id": { "type": "string", "pattern": "^[1-9]([0-9]{7}|[0-9]{9})$", "enumminLength": [10 }, "RESIDENCEaddress",: { "type": "object", "REGISTRATION" "properties": { ] "type": { }, "countrytype": "string", { "typedescription": "stringDictionary: ADDRESS_TYPE" }, "areacountry": { "type": "string" }, "regionarea": { "type$ref": "string#/definitions/name" }, "settlementregion": { "type$ref": "string#/definitions/name" }, "settlement_type": { "type$ref": "string#/definitions/name" }, "settlement_idtype": { "type": "string" }, "streetsettlement_typeid": { "type": "string", "enum": [ }, "BOULEVARDstreet_type",: { "STREETtype",: "string" "AVENUE", }, "SQUAREstreet": { ] }, "street": { "type": "string""$ref": "#/definitions/name" }, "building": { "type": "string", "pattern": "^[1-9]([0-9]{1,32})?(([ \\-]{1})?(?![ЫЪЭЁыъэё])[А-ЯҐЇЄа-яґїє]{1})?((\\s)?(\\\\|\/)(\\s)?[1-9]([0-9]{1,32})?(([ \\-]{1})?(?![ЫЪЭЁыъэё])[А-ЯҐЇЄа-яґїє]{1})?)?$" }, "apartment": { "type": "string" }, "zip": { "type": "string", "pattern": "^[0-9]{5}$" } }, "required": [ "countrytype", "settlement_idcountry", "buildingarea" , ], "settlement", "settlement_type", "settlement_id", "building" ], "additionalProperties": false }, "document": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "PASSPORT", "NATIONAL_ID", "BIRTH_CERTIFICATE", "TEMPORARY_CERTIFICATE", "COURT_DECISION" ] }, "number": { "type": "string" } }, "required": [ "type", "number" ], "additionalProperties": false }, "authentication_method": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "SMSOTP", "SMS_TRUSTEE", "OFFLINE" ] }, "phone_number": { "type": "string", "pattern": "^\\+38[0-9]{10}$" } }, "required": [ "type", "phone_number" ], "additionalProperties": false } }, "type": "object", "properties": { "declaration_request": { "type": "object", "properties": { "start_date": { "type": "string", "format": "date-time", "description": "Should be defined on the client side." }, "end_dateperson": { "type": "stringobject", "formatproperties": "date-time", { "descriptionfirst_name": "Will{ be defined on eHealth side if it's not set." "type": "string", }, "person": { "items": { "type": "object", "properties$ref": { "#/definitions/name" "first_name": {}, "typeminLength": 1 "string" }, "last_name": { "type": "string" , }, "second_nameitems": { "type$ref": "string"#/definitions/name" }, "birth_date "minLength": {1 "type": "string", }, "formatsecond_name": "date-time"{ },"type": "string", "birth_placeitems": { "type$ref": "string"#/definitions/name" }, "genderminLength": {1 "type": "string"}, "enumbirth_date": [{ "type": "MALEstring", "FEMALEformat": "date" ] }, "emailbirth_country": { "type": "string", "formatminLength": 1 "email" }, "taxbirth_idsettlement": { "type": "string", "patternitems": "^[1-9]([0-9]{7}|[0-9]{9})$" }, "$ref": "#/definitions/name" "secret": { }, "type": "string" "minLength": 1 }, "documentsgender": { "type": "arraystring", "itemsenum": {[ "$ref": "#/definitions/documentMALE", } "FEMALE" }, ] "addresses": { "type": "array"}, "itemsemail": { "$reftype": "#/definitions/address"string", "format": "email" } }, "phonestax_id": { "type": "arraystring", "items": { "$ref": "#/definitions/phonetax_id" } }, "authentication_methodssecret": { "type": "arraystring", "items": { "$ref": "#/definitions/authentication_methodname" }, "minLength": 6 }, "emergency_contactdocuments": { "type": "objectarray", "propertiesminItems": { 1, "first_nameitems": { "type$ref": "string"#/definitions/document" } }, }, "last_nameaddresses": { "type": "stringarray", },"items": { "second_name$ref": {"#/definitions/address" }, "type": "string" "minItems": 2 }, }, "phones": { "type": "array", "items": { "$ref": "#/definitions/phone" } }, } },"authentication_methods": { "requiredtype": [ "array", "first_name",items": { "last_name","$ref": "#/definitions/authentication_method" "phones" } ] }, "confidantemergency_personcontact": { "type": "object", "properties": { "relationfirst_typename": { "type": "string", "enumitems": [{ "$ref": "TRUSTEE"#/definitions/name" }, "minLength": 1 ] }, "firstlast_name": { "type": "string", }, "last_name"items": { "type$ref": "string"#/definitions/name" }, "second_nameminLength": 1 { }, "type": "string" "second_name": { }, "birth_datetype": "string", { "typeitems": "string", { "format$ref": "date-time"#/definitions/name" }, "birth_place "minLength": {1 }, "type": "string" "phones": { }, "gendertype": "array", { "typeitems": "string", { "enum$ref": ["#/definitions/phone" "MALE"}, "FEMALEminItems": 1 ]} }, "tax_idrequired": { [ "type": "stringfirst_name", "pattern": "^[1-9]([0-9]{7}|[0-9]{9})$"last_name", "phones" }, ], "documents": { "additionalProperties": false "type": "array", }, "itemsconfidant_person": { "$reftype": "#/definitions/documentarray", "items": { } },"type": "object", "phonesproperties": { "relation_type": "array", { "itemstype": {"string", "$refenum": "#/definitions/phone"[ } "PRIMARY", } "SECONDARY" }, "required": [ ] "first_name", }, "last_name", "first_name": { "birth_date", "type": "birth_placestring", "gender" "items": { ], "description$ref": "#/definitions/name"Should be set if this Person is disabled, underage, etc." }, "renewal_consent": { "minLength": 1 "type": "boolean" }, "patientlast_signedname": { "type": "boolean"string", }, "items": { "disclosure_consent": { "type$ref": "boolean"#/definitions/name" }, }, "process_data_consent": { "typeminLength": 1 "boolean" } }, "required": [ "firstsecond_name",: { "last_name", "type": "birth_datestring", "birth_place", }, "gender", "secret"birth_date": { ], "descriptiontype": "string"Object, that described a Patient. Confidant person should be set for disabled persons, underage persons, etc." "format": "date" }, "employee_id": { }, "type": "string", "description": "Employee ID with `type=DOCTOR` selected from available Employees as a third contract party." "birth_country": { }, "division_idtype": {"string", "type": "string", "descriptionminLength": "Registered Medical Service Provider Division identifier." 1 }, "legal_entity_id": { "typebirth_settlement": "string",{ "descriptiontype": "string"Registered, Medical Service Provider Division identifier." }, "scopeitems": { "type": "string", "enum$ref": ["#/definitions/name" "FAMILY DOCTOR" }, ] } }, "minLength": 1 "required": [ "start_date", }, "person", "employee_id", "division_id","gender": { "type": "string", "legal_entity_id",enum": [ "scope"MALE", ] } } } |
Authorize
- Verify the validity of access token
- Check user scope declaration_request:create in order to perform this action
Validate doctor
Get employee details
Invoke Get employee details
Validate Response $.data.employee_type == DOCTOR
Calculate patient age
Calculate patient age
Code Block | ||
---|---|---|
| ||
age = MONTHS_BETWEEN (now(), $.declaration_request.person.birth_date) / 12 |
Check that doctor speciality meets the patient age requirements
Age requirements for doctor specialty
...
Check phone number
Validate phone number.
Invoke Check phone number WS in order to check phone number exists in DB
Code Block | ||||
---|---|---|---|---|
| ||||
curl -k -L 'http://ehealth.nebo15.com/api/otp_verifications/phone_number/+380508887700' |
Search pending declaration requests
Search pending declarations in IL_DB.declaration_requests using patient's tax_id and filtered by employee_id to prevent requests duplication
Code Block | ||
---|---|---|
| ||
WHERE IL_DB.declaration_requests.data.declaration_request.person.tax_id = :($.declaration_request.person.tax_id)
AND IL_DB.declaration_requests.data.declaration_request.employee_id = :($.declaration_request.employee_id)
AND IL_DB.declaration_requests.data.declaration_request.legal_entity_id = :($.declaration_request.legal_entity_id)
AND IL_DB.declaration_requests.status IN ('NEW', 'APPROVED') |
Cancel pending declaration requests
Change status of all found pending declarations to {CANCELED}. See available transitions
Code Block | ||
---|---|---|
| ||
SET IL_DB.declaration_requests.status = 'CANCELED'
WHERE IL_DB.declaration_requests.id IN (:LIST) |
Save declaration request
Check and calculate declaration end date
If $.declaration_request.end_date is empty
Code Block | ||
---|---|---|
| ||
end_date = $.declaration_request.start_date + GLOBAL_PARAMETER('TERM') |
Insert entity to IL_DB.declaration_request in {status} = NEW
Search MPI
Search patient in MPI using personal information
...
first_name
...
last_name
...
Code Block | ||||
---|---|---|---|---|
| ||||
curl -k -L 'http://ehealth.nebo15.com/api/persons?first_name=Олена&last_name=Пчілка&birth_date=1991-08-19&tax_id=3126509816&phone_number=%2B380508887700' |
Determine default auth method for new MPI
In case MPI not found
Invoke Gandalf API to determine Default auth method
Service description
Code Block | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
{
"phone_availability": true,
"preferable_auth_method": "OTP_TRUSTEE"
} |
Determine preferable auth method for existing MPI
In case MPI found
Get auth method, channel from Search MPI response
Save auth method to request
Update request object in IL_DB.declaration_request with auth method in order to resend sms if needed in future
Code Block | ||
---|---|---|
| ||
SET IL_DB.declaration_request.authentication_method_current = Search MPI Response $.data.authentication_method
WHERE IL_DB.declaration_request.id = :id |
Generate printout form
Invoke Man Template Rendering Service to obtain printout form. Service description
Request parameters
...
Save printout to IL_DB.declaration_request
Code Block | ||
---|---|---|
| ||
SET IL_DB.declaration_request.printout_content = Man Response $.data
WHERE IL_DB.declaration_request.id = :id |
Generate upload URL
Get environment parameter DECLARATION_REQUEST_OFFLINE_DOCUMENTS
Generate FILE_NAME for each document in DECLARATION_REQUEST_OFFLINE_DOCUMENTS
Invoke Media Content Storage to generate upload URL for each document in DECLARATION_REQUEST_OFFLINE_DOCUMENTS
Save all DECLARATION_REQUEST_OFFLINE_DOCUMENTS to declaration request
Code Block | ||
---|---|---|
| ||
SET IL_DB.declaration_request.documents = :documents
WHERE IL_DB.declaration_request.id = :id |
Documents structure
Code Block | ||
---|---|---|
| ||
{
"documents":[
{
"type":"PASSPORT"
}
]
} |
Generate verification code
Invoke Initialize OTP Verification
...
"FEMALE"
]
},
"tax_id": {
"type": "string",
"items": {
"$ref": "#/definitions/tax_id"
}
},
"secret": {
"type": "string",
"items": {
"$ref": "#/definitions/name"
},
"minLength": 6
},
"documents_person": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/document"
}
},
"documents_relationship": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/document"
}
},
"phones": {
"type": "array",
"items": {
"$ref": "#/definitions/phone"
}
}
},
"required": [
"relation_type",
"first_name",
"last_name",
"birth_date",
"birth_country",
"birth_settlement",
"gender",
"secret",
"documents_person",
"documents_relationship"
],
"additionalProperties": false
},
"description": "Should be set if this Person is disabled, underage, etc."
},
"patient_signed": {
"type": "boolean",
"enum": [
false
]
},
"process_disclosure_data_consent": {
"type": "boolean",
"enum": [
true
]
}
},
"required": [
"first_name",
"last_name",
"birth_date",
"birth_country",
"birth_settlement",
"gender",
"secret",
"documents",
"addresses",
"authentication_methods",
"emergency_contact",
"patient_signed",
"process_disclosure_data_consent"
],
"additionalProperties": false,
"description": "Object that described a Patient. Confidant person should be set for disabled persons, underage persons, etc."
},
"employee_id": {
"type": "string",
"minLength": 36,
"description": "Employee ID with `type=DOCTOR` selected from available Employees as a third contract party."
},
"division_id": {
"type": "string",
"minLength": 36,
"description": "Registered Medical Service Provider Division identifier."
},
"scope": {
"type": "string",
"enum": [
"family_doctor"
]
}
},
"required": [
"person",
"employee_id",
"division_id",
"scope"
],
"additionalProperties": false
}
}
} |
Authorize
- Verify the validity of access token
- Check user scope declaration_request:create in order to perform this action
Validate doctor
Get employee details
Invoke Get employee details
Validate Response $.data.employee_type == DOCTOR
Calculate patient age
Calculate patient age
Code Block | ||
---|---|---|
| ||
age = MONTHS_BETWEEN (now(), $.declaration_request.person.birth_date) / 12 |
Get global parameters
Invoke Global parameters to get following parameters:
- ADULT_AGE
- DECLARATION_TERM
Code Block | ||||
---|---|---|---|---|
| ||||
curl -X GET \
{:host}/prm/api/global_parameters |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"meta": {
"url": "http://api-svc.prm/api/global_parameters",
"type": "object",
"request_id": "ikff7hcf0hhto5c06irl9i976kc3s41m",
"code": 200
},
"data": {
"verification_request_expiration": "30",
"employ_request_expiration": "30",
"declaration_term": "30",
"declaration_request_expiration": "30",
"billing_date": "2",
"adult_age": "18",
"type": "global_parameter"
}
} |
Check that doctor speciality meets the patient age requirements
Check age requirements according to values in response from previous step.
Doctor speciality | Age |
---|---|
FAMILY DOCTOR | All ages |
THERAPIST | Greater or equal to $.data.adult_age |
PEDIATRICIAN | Less than $.data.adult_age |
Check phone number
Invoke Check phone number WS in order to check phone number exists in DB.
Phone number: $.declaration_request.person.phones.[0].number
Code Block | ||||
---|---|---|---|---|
| ||||
curl -k -L '{:host}/verifications/+380508887700' |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"meta": {
"url": "http://dev.ehealth.world/verifications/+380936235985",
"type": "object",
"request_id": "b98ie5d0j3fn7vcbbmksa4k45ptue2ca",
"code": 200
},
"data": {
"phone_number": "+380936235985"
}
} |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"meta": {
"url": "http://dev.ehealth.world/verifications/+380936235986",
"type": "object",
"request_id": "b4adrhrj5og9ogqanb57dqj0v1qkbb9j",
"code": 404
},
"error": {
"type": "not_found"
}
} |
Search pending declaration requests
Search declarations in IL_DB.declaration_requests to prevent requests duplication:
Code Block | ||
---|---|---|
| ||
WHERE IL_DB.declaration_requests.data.declaration_request.person.tax_id = :($.declaration_request.person.tax_id)
AND IL_DB.declaration_requests.data.declaration_request.legal_entity_id = :($.declaration_request.legal_entity_id)
AND IL_DB.declaration_requests.status IN ('NEW', 'APPROVED') |
Cancel declaration requests
Change status of all found declarations:
Code Block | ||
---|---|---|
| ||
SET IL_DB.declaration_requests.status = 'CANCELED'
WHERE IL_DB.declaration_requests.id IN (:LIST) |
Calculate declaration end/start date
Start date:
Code Block |
---|
start_date = Current_date() |
End date:
Code Block |
---|
if (person.age < 18) {
end_date = min(birth_date + 18y - 1d, start_date + declaration_term);
} else {
end_date = start_date + declaration_term;
} |
Save declaration request
Insert record to IL.declaration_request in status 'NEW'
Search MPI
Search patient in MPI using personal information
Query param | Source |
---|---|
first_name | $.declaration_request.person.first_name |
last_name | $.declaration_request.person.last_name |
second_name | $.declaration_request.person.second_name |
birth_date | $.declaration_request.person.birth_date |
tax_id | $.declaration_request.person.tax_id |
Code Block | ||||
---|---|---|---|---|
| ||||
curl -k -L '{:host}/api/persons?first_name=Олена&last_name=Пчілка&birth_date=1991-08-19&tax_id=3126509816&phone_number=%2B380508887700' |
Determine default auth method for new MPI
Invoke Gandalf to obtain auth method according to internal rules:
Code Block | ||||
---|---|---|---|---|
| ||||
curl --user GNDF_CLIENT_ID:GNDF_CLIENT_SECRET \
--header 'X-Application: GNDF_APPLICATION_ID' \
--data '{"phone_availability": {value}, "preferable_auth_method": {value}}' \
{:host}/api/v1/tables/GNDF_TABLE_ID/decisions |
Set IL.declaration_request.authentication_method_current:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"authentication_method": GandalfResponse.$.data.final_decision,
"authentication_number": DeclarationRequest.$.declaration_request.person.authentication_methods.[0].number
} |
Determine preferable auth method for existing MPI
Set IL.declaration_request.authentication_method_current:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"authentication_method": SearchMPIResponse.$.data.authentication_method.type,
"authentication_number": SearchMPIResponse.$.data.authentication_method.number
} |
Generate printout form
Invoke MAN to render print form.
Request mapping:
Parameter | Source |
---|---|
id | DECLARATION REQUEST |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
curl --request POST \
--header 'Accept: text/html' \
--header 'Content-Type: application/json' \
{:host}/templates/{:declaration_printout_id}/actions/render |
Set IL.declaration_request.printout_content:
Code Block | ||
---|---|---|
| ||
MANResponse.$.data |
Generate upload URL
Document URL's generation logic
1. If $.declaration_request.person.tax_id not null:
- Generate URL with type person.SSN
2. For each $.declaration_request.person.documents:
- Generate URL's with type person.{$.declaration_request.person.documents.[:].type}
3. If $.declaration_request.person.confidant_person.[:].tax_id not null, for each:
- Generate URL with type confidant_person.{confidant_person.type}.SSN
4. For each $.declaration_request.person.confidant_person.[:].documents_person:
- Generate URL's with type confidant_person.{confidant_person.type}.{$.declaration_request.person.confidant_person.[:].documents_person.[:].type}
4. For each $.declaration_request.person.confidant_person.[:].documents_relationship:
- Generate URL's with type confidant_person.{confidant_person.type}.{$.declaration_request.person.confidant_person.[:].documents_relationship.[:].type}
Invoke Media Content Storage to generate upload URL for each document obtained by executing logic above
IL.declaration_request.documents structure:
Code Block | ||
---|---|---|
| ||
{
"documents":[
{
"type":"person.SSN",
"url": "https://storage.googleapis.com/..."
}
]
} |
Save documents to DB.
Generate verification code
Invoke Initialize OTP to generate one time password and send it to client number.
Phone_number: IL.declaration_request.authentication_method_current.$.authentication_number
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
curl -X POST \
http://localhost:4000/verifications \
-H 'content-type: application/json' \
-d '{
"phone_number": "+380936235985"
}' |