# 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 } } } ```