# Hjemmelegene Chat integration - dev notes
[TOC]
### Flow overview
- Customer logs in
- gets through the IF coverage verification
- gets to some sort of next step of the wizard in which he likely fills up the nature of his desired consultation in a text field
- backend creates and fetches jwt shared secret from SEALD
- backend creates and redirects his ass in a URL (same url he'd get via SMS if he was in the referral flow)
- he gets there and is being show a spinner or sth that basically tells them to wait
- doctor starts a consultation, video and chat widgets begin to work
- they're done talking
- doctor finishes a consultation, video and chat switch off
- customer is redirected to review page
```plantuml
@startuml
actor Patient as pat
actor Doctor as doc
entity Backend as back
boundary Seald as se
== patient creates \na consultation ==
pat -> back : `GQL: createCustomerConsultation(...)`
back -> se : Call to Seald API for sharedsecret
back -> back: 2 JWTs are created, one for the patient and one for the doctor
back -> pat : returns data on Consultation, Doctor and Patient to the frontend
pat -> back : `GQL: consultation(id: 345678)` patient|doctor fetches details of consultation
note over pat, se: frontend injects those data to the Chat React component?
note over pat, se: Patient starts chat-consultation
@enduml
```
### JWT settings
```ruby=
JWT.encode(
{
iat: Time.zone.now.to_i, # current EPOCH timestamp
exp: expiry, # EPOCH, currently: 1 day for patient, 14 days for the doctor
iss: jwt_shared_secret_id, # from SEALD API
jti: SecureRandom.uuid, # just UUIDv4
scopes: [required_token_permissions], # [1]
recipients: recipient_ids, # eg. ['Consultation/4567', 'Patient/4567']
join_team: true,
owner: owner_id # will be sth like `Consultation/4567` for doctor and
# `Patient/4567` for patient side
},
jwt_shared_secret, # from SEALD API
'HS256'
)
```
### API calls
Note: I dont expect you to have to make those calls. Rather I expect Alex/Alexa to implement them,
and once they receive the response, they'd just pass some of the fields as props to the Chat React component
```graphql=
query {
consultation(id: 20) {
id
patient {
id
name
phoneNumber
}
serviceProvider {
id
fullName
}
source
state
videoRoom {
name
externalId
serviceProviderKey // only for doctor obvsly
patientKey // only for patient
}
chatRoom {
id
serviceProviderJwt // only for doctor
patientJwt // only for patient
}
serviceProviderId
enabledChannels
primaryChannel
category
code
options
}
}
```
or as curl
```curl=
curl --location --request POST 'http://localhost:5000/graphql' \
--header 'Content-Type: application/json' \
--header 'Cookie: _session_id=blahblahblah' \
--data-raw '{"query":"query {\n consultation(id: 20) {\n id\n patient {\n id\n name\n phoneNumber\n }\n serviceProvider {\n id\n fullName\n }\n source\n state\n videoRoom {\n name\n externalId\n serviceProviderKey\n }\n chatRoom {\n id\n serviceProviderJwt\n }\n serviceProviderId\n enabledChannels\n primaryChannel\n category\n code\n options\n }\n}","variables":{}}'
```
#### Payload when logged user is a doctor (note `serviceProviderJwt`)
```jsonld=
{
"data": {
"consultation": {
"id": "20",
"patient": {
"id": "1",
"name": "jerem poiraudau",
"phoneNumber": "+4791222120"
},
"serviceProvider": {
"id": "1",
"fullName": "Helen Karal Melbergtest"
},
"source": "direct",
"state": "PENDING",
"videoRoom": {
"name": "C-ufF7woVa-d74mGWRt",
"externalId": "af048d83-b663-4efa-9d1c-fa56c7531240",
"serviceProviderKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyIjoiQy11ZkY3d29WYS1kNzRtR1dSdCIsIm8iOnRydWUsInVkIjoiQ29uc3VsdGF0aW9uLzIwIiwidSI6Im1lZGlzaW5zayBhcmJlaWRlciIsImQiOiI4ZGNjY2E5Zi04YmM4LTRkMGYtODRlNC1jZGY0NmU0MzcxN2UiLCJpYXQiOjE2Njk5Njc4Mzh9.8ZXC5yJJ18X8jqmvbXkUNL85B1cDvkqW8pQqrQTSTQU"
},
"chatRoom": {
"id": "1",
"serviceProviderJwt": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Njk5Njc4MzksImV4cCI6MTY3MTE3NzQzOSwiaXNzIjpudWxsLCJqdGkiOiIzMTA0NWI1Yi1jNjQ2LTRlYmYtOTFmNC1mOWFhNTlhZjA5ZDUiLCJzY29wZXMiOlsiMSJdLCJyZWNpcGllbnRzIjpbIkNvbnN1bHRhdGlvbi8yMCIsIlBhdGllbnQvMSJdLCJqb2luX3RlYW0iOnRydWUsIm93bmVyIjoiQ29uc3VsdGF0aW9uLzIwIn0.nFCImbMCiIaRK51Ey6NQnifj187WbdVDkfoxAUfal2E"
},
"serviceProviderId": "1",
"enabledChannels": [
"PHONE",
"CHAT",
"VIDEO"
],
"primaryChannel": "VIDEO",
"category": "insurance",
"code": "ufF7woVa",
"options": null
}
}
}
```
#### Payload when logged user is a patient (note `patientJwt`)
```jsonld=
{
"data": {
"consultation": {
"id": "20",
"patient": {
"id": "22",
"name": "test guy",
"phoneNumber": "+4791222122"
},
"serviceProvider": {
"id": "1",
"fullName": "Helen Karal Melbergtest"
},
"source": "direct",
"state": "PENDING",
"videoRoom": {
"name": "C-ufF7woVa-d74mGWRt",
"externalId": "af048d83-b663-4efa-9d1c-fa56c7531240",
"patientKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyIjoiQy11ZkY3d29WYS1kNzRtR1dSdCIsIm8iOmZhbHNlLCJ1ZCI6IlBhdGllbnQvMSIsInUiOiJtZWRpc2luc2sgYXJiZWlkZXIiLCJkIjoiOGRjY2NhOWYtOGJjOC00ZDBmLTg0ZTQtY2RmNDZlNDM3MTdlIiwiaWF0IjoxNjY5OTY3ODM4fQ.WIHqeImL52XHeGI7GS4qY86NfAA1hR5zCvsm3Mpi8mc"
},
"chatRoom": {
"id": "1",
"patientJwt": "eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2Njk5Njc4MzksImV4cCI6MTY3MDA1NDIzOSwiaXNzIjpudWxsLCJqdGkiOiIzNWMzNDgwMy02OTA1LTQ5MmQtOGU4ZS05YTA3NjNmZThhZmQiLCJzY29wZXMiOlsiMSJdLCJyZWNpcGllbnRzIjpbIkNvbnN1bHRhdGlvbi8yMCIsIlBhdGllbnQvMSJdLCJqb2luX3RlYW0iOnRydWUsIm93bmVyIjoiUGF0aWVudC8xIn0.iBJl-G2nGkANl-sVxE-Ob05qf1X7jCgrADjY7aYArk8"
},
"serviceProviderId": "1",
"enabledChannels": [
"PHONE",
"CHAT",
"VIDEO"
],
"primaryChannel": "VIDEO",
"category": "insurance",
"code": "ufF7woVa",
"options": null
}
}
}
```