...

Anchor
Declaration Request JSON Schema
Declaration Request JSON Schema
Validate request

Validate request using JSON schema

Code Block
languagexml
titleJSON Schema
collapsetrue
{

  "$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

    1. Verify the validity of access token
    2. Check user scope declaration_request:create in order to perform this action

Validate doctor

Image Removed

Get employee details

Invoke Get employee details

Validate Response $.data.employee_type == DOCTOR

Calculate patient age

Calculate patient age

Code Block
languagesql
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
languagexml
titleRequest example
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
languagesql
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
languagesql
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
languagesql
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
languagexml
titleSample request
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
languagejs
themeMidnight
titleRequest example
linenumberstrue
collapsetrue
{
  "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
languagesql
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
languagesql
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
languagesql
SET   IL_DB.declaration_request.documents = :documents
WHERE IL_DB.declaration_request.id = :id

Documents structure

Code Block
languagexml
{
   "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

    1. Verify the validity of access token
    2. Check user scope declaration_request:create in order to perform this action

Validate doctor

Image Added

Get employee details

Invoke Get employee details

Validate Response $.data.employee_type == DOCTOR

Calculate patient age

Calculate patient age

Code Block
languagesql
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
languagesql
titlecURL example
curl -X GET \
  {:host}/prm/api/global_parameters


Code Block
languagejs
themeMidnight
titleResponse example
{
  "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 specialityAge
FAMILY DOCTORAll ages
THERAPISTGreater or equal to $.data.adult_age
PEDIATRICIANLess 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
languagexml
titlecURL example
curl -k -L '{:host}/verifications/+380508887700'


Code Block
languagejs
themeMidnight
titleSuccessful response example
{
    "meta": {
        "url": "http://dev.ehealth.world/verifications/+380936235985",
        "type": "object",
        "request_id": "b98ie5d0j3fn7vcbbmksa4k45ptue2ca",
        "code": 200
    },
    "data": {
        "phone_number": "+380936235985"
    }
}


Code Block
languagejs
themeMidnight
titleFailed response example
{
    "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
languagesql
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
languagesql
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 paramSource

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
languagexml
titleSample request
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
languagejs
titlecURL example
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
languagejs
themeMidnight
titleUpdate auth method
{
  "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
languagejs
themeMidnight
titleUpdate auth method
{
  "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:

ParameterSource
idDECLARATION REQUEST


Code Block
languagejs
themeMidnight
titlecURL example
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
languagesql
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
languagexml
{
   "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
languagejs
themeMidnight
titlecURL example
curl -X POST \
  http://localhost:4000/verifications \
  -H 'content-type: application/json' \
  -d '{
  "phone_number": "+380936235985"
}'