###### tags : `xirka` `documentation` --- title: "Dokumentasi API Respinos" --- # Pendahuluan ## 1. Daftar Isi [TOC] ## 2. Petunjuk Umum 1. Relasi Diagram bisa diakses di : https://dbdiagram.io/d/60b8509cb29a09603d17bff1 2. Base Url : `http://<ip_address>:<port>` 3. Untuk mendapatkan akses api, setiap request perlu disertakan token pada header. 4. Token diperoleh dengan mengakses api token dengan mengirimkan username & password. Server memberi respon berupa token dan refresh_token. Token valid dalam jangka waktu tertentu, jika token sudah tidak valid, gunakan refresh_token untuk mendapatkan token baru. 5. Respon Kode | No | Kode | Keterangan | Deskripsi | | :-: | :--: | :-----------: | :-------------------------------------------------------------------------------: | | 1 | 200 | Sukses | | | 2 | 201 | Sukses | | | 3 | 400 | Bad Request | Kesalahan berada di sisi klien | | 4 | 401 | Not Authorize | client tidak menyertakan token pada saat melakukan request atau token tidak valid | | 5 | 403 | Forbidden | client tidak bisa melakukan request | | 6 | 404 | Not Found | Data tidak ditemukan | | 7 | 500 | Server Error | Terjadi kesalahan di server | 6. Format Respons ``` Sample Response: { status: "success", result: [ {data1}, {data2}, ] } { status: "success", result: response.data } Error response : { error: message } ``` ## 3. Diagram Alir Request #### Request Token ```sequence Note left of Client: username & password Client->Server: request token Server->Database: query database Note right of Server: validate payload Database->Server: send user data Server->Client: send response Note left of Client: token & refresh_token ``` #### General Request ```sequence Note left of Client: payload + token Client->Server: send request Note right of Server: validate token Server->Database: query database Note right of Database: query data Database->Server: send data Server->Client: send response Note left of Client: data ``` # REST API ## 1. Auth Token Endpoint : `<base_url>/api/v1/auth` |No|Metode|Endpoint|Header|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Post|`<endpoint>/token`|-|email, password|Mendapatkan token & refresh token| |2|Post|`<endpoint>/token-refresh`|refresh_token|-|Mendapatkan token & refresh token baru| > Catatan : > Masa berlaku token adalah 1 jam sedangkan refresh token 1 hari. > Pada api token-refresh, gunakan refresh-token pada header autentikasi. > User bisa mendapatkan token jika sudah terdaftar di aplikasi dan telah melakukan verifikasi email. #### Deskripsi Body | No | Item | Tipe Data | Catatan | | :-: | :-----------: | :-------: | :-----------------------------------------------: | | 1 | email | String | - | | 2 | password | String | - | | 3 | \_id | String | Id User | | 4 | refresh_token | String | refresh token yang diperoleh pada saat post token | #### Sample Request - Using Curl ##### Get Token ``` Request : curl --location --request POST 'http://202.148.1.57:8501/api/v1/auth/token' \ --header 'Content-Type: application/json' \ --data-raw '{ "email": "aditya@mail.com", "password": "bandung123abc" }' Response: { "status": "success", "_id": "60b734b0cc2e723dc015acbc", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTUwMTAsImV4cCI6MTYyNDQ1ODYxMH0.bOaAqhYmf7Eh-tNVWX1M18vwfFk6vzLoOb4mAzgP_rk", "max_age": "1h", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTUwMTAsImV4cCI6MTYyNDQ2MjIxMH0.jjSSQP_W-EB35DD8lKT05P8rhsVrHpeg6aG623CPSSk" } ``` ##### Get Refresh Token ``` Request : curl --location --request POST 'http://127.0.0.1:8080/api/v1/auth/token-refresh' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTUwMTAsImV4cCI6MTYyNDQ2MjIxMH0.jjSSQP_W-EB35DD8lKT05P8rhsVrHpeg6aG623CPSSk' Response: { "status": "success", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJpYXQiOjE2MjU2NDMzMjcsImV4cCI6MTYyNTY0NjkyN30.W-W-aDBciWdIfzXe00WPhHF7NFhC8eXs3KQGlGD-Os0", "max_age": "1h", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJpYXQiOjE2MjU2NDMzMjcsImV4cCI6MTYyNTY1MDUyN30.mAzokjNqsjrXw_Df3OHEdS1oZYc68q9eB_cSoIJeJTQ" } ``` ## 2. User User adalah koleksi yang memuat informasi pengguna baik itu pasien, dokter, petugas medis dan superuser. Akses data sementara dibuka untuk kategori dokter. Pengguna yang ingin mengakses data respinos wajib mendaftarkan diri & melakukan verifikasi link yang dikirim ke email yang telah didaftarkan. Proses Registrasi ```sequence Note left of Client: account & user info Client->Server: account registration Note right of Server: generate verification link Server->Client: send verification link Client->Server: Go to verification link Note right of Server: validate account ``` #### Skema User | No | Field | Tipe Data | Keterangan | | :-: | :--------: | :-------: | :-------------------------------------------------------: | | 1 | \_id | string | Id User | | 2 | password | string | | | 3 | createdAt | datetime | | | 4 | lastLogin | datetime | | | 5 | role | string | Peran pengguna: patient, doctor, health worker, superuser | | 6 | profile | object | profil user: avatar, description, dsb | | 7 | isVerified | boolean | status verifikasi user | | 8 | token | string | kunci untuk: reset password/verifikasi user | > untuk menambah user, tidak diperlukan token pada saat request #### Skema User Profile | No | Field | Tipe Data | Keterangan | | :-: | :------------: | :-------: | :-----------------------------------: | | 1 | avatar | string | user avatar | | 2 | workingPlace\* | string | Instansi tempat bekerja | | 3 | strNumber\* | string | nomor registrasi petugas medis/dokter | | 4 | description | string | deskripsi user | | 5 | isMale | boolean | jenis kelamin | | 6 | weight | int | berat badan | | 7 | height | intr | tinggi badan | | 8 | dateOfBirth | date | tanggal lahir | > - health worker/doctor #### List API User Endpoint :`<base_url>/api/v1/user` |No|Metode|Endpoint|Param|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Post|`<endpoint>/`|-|name*, email*, password*, role, strNumber**, workingPlace**|Mendaftarkan user| |2|Get|`<endpoint>/:id`|fields|-|Mendapatkan Informasi User| |3|Patch|`<endpoint>/profile`|-|\_id*, name, description, isMale, dateOfBirth, weight, height, workingPlace, strNumber |Mengubah profile user| |4|Patch|`<endpoint>/password`|-|\_id*, password*, newPassword*|Mengubah password| |5|Post|`<endpoint>/verification`| - |key*|Verifikasi User -> link verifikasi via email| |6|Post|`<endpoint>/password/forget`| - |email*| Request link + key untuk lupa password | |7|Post|`<endpoint>/password/verification`| - |key*, password\*| Mengubah password (status lupa password) | #### Deskripsi Body / Parameter | No | Item | Tipe Data | Catatan | | :-: | :----------: | :-------: | :----------------------------------------------------------------------------------------------: | | 1 | id | String | User Id | | 2 | fields | String | informasi yang ingin diperoleh dari user | | 3 | role | String | peran user (doctor, health worker) | | 4 | strNumber | String | Nomor tanda register petugas medis | | 5 | workingPlace | String | instansi tempat bekerja | | 6 | key | String | kunci untuk melakukan verifikasi user / verifikasi perubahan password, kunci diberikan via email | > Catatan : > nilai fields yang valid : \_id, role, email, name, profile > contoh request dengan parameter fields http://202.148.1.57:8501/api/v1/user/60b734b0cc2e723dc015acbc?fields=_id,role,email > "\*" Wajib diisi > "\*\*" Wajib jika rolenya "doctor" atau "health worker" > Proses registrasi: post "/" -> post "/verification" > Proses lupa password : post "/password/forget" -> "/password/verification" #### Sample Request - Using Curl ##### Get User Detail ``` curl --location --request GET 'http://202.148.1.57:8501/api/v1/user/60b734b0cc2e723dc015acbc' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTUwMTAsImV4cCI6MTYyNDQ1ODYxMH0.bOaAqhYmf7Eh-tNVWX1M18vwfFk6vzLoOb4mAzgP_rk' Response: { "message": "success", "result": { "role": "doctor", "_id": "60b734b0cc2e723dc015acbc", "name": "Aditya", "email": "aditya@mail.com" } } ``` ##### Post User ``` curl --location --request POST 'http://202.148.1.57:8501/api/v1/user' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTUwMTAsImV4cCI6MTYyNDQ1ODYxMH0.bOaAqhYmf7Eh-tNVWX1M18vwfFk6vzLoOb4mAzgP_rk' \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "tes user 2", "email": "user2@mail.com", "password": "bandung123abc", "role": "doctor", "strNumber": "123abc", "workingPlace": "RS Hasan Sadikin" }' Response: { "message": "created", "result": { "name": "tes user 2", "email": "user2@mail.com" } } ``` ## 3. Patient User adalah koleksi yang memuat informasi pasien berupa tanggal registrasi, dan list dokter yang menangani pasien. Informasi deskripsi pasien, diambil dari informasi user. Data pasien hanya bisa diakses oleh dokter yang bersangkutan. Proses Registrasi ```sequence Note left of Client: patient info Client->Server: patient registration Note right of Server: create user account & patient ``` #### Skema Patient | No | Field | Tipe Data | Keterangan | | :-: | :----: | :---------: | :--------: | | 1 | \_id | string | ID pasien | | 2 | user | FK | ref: User | | 3 | doctor | Array of FK | ref: User | #### List API Patient Endpoint :`<base_url>/api/v1/patient` |No|Metode|Endpoint|Param|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Get|`<endpoint>/`|doctor*, limit, offset, orderBy, name||Mendapatkan list pasien | |2|Post|`<endpoint>/`|-|doctor*, name*, isMale*, dateOfBirth*, weight*, height\*|Mendaftarkan pasien | |3|Get|`<endpoint>/:id`|doctor|-|Mendaftarkan informasi detail pasien | |4|Get|`<endpoint>/count`|doctor|-|Mendapatkan informasi jumlah registrasi pasien berdasarkan waktu | |5|Delete|`<endpoint>`|\_id|-|Menghapus data pasien | |6|Patch|`<endpoint>`|-|\_id*, doctor*, isMale, dateOfBirth, weight, height |Mengubah data pasien | > Catatan: > Menghapus data pasien berakibat terhapusnya data lain (rekam medis, user, dsb) #### Deskripsi Body / Parameter | No | Item | Tipe Data | Catatan | | :-: | :---------: | :-------: | :---------------------------------: | | 1 | doctor | String | user ID Dokter | | 2 | limit | Integer | Jumlah data yang direquest | | 3 | offset | Integer | Banyak data yang di skip | | 4 | orderBy | String | Jenis urutan data pasien | | 5 | isMale | Boolean | Jenis Kelamin | | 6 | dateOfBirth | Date | Tanggal lahir (Format : YYYY-MM-DD) | | 7 | height | Integer | Tinggi Badan | | 8 | weight | Integer | Berat Badan | | 9 | name | String | Nama pasien | | 10 | \_id | String | Id Pasien | #### Sample Request - Using Curl ##### Get Patient ``` curl --location --request GET 'http://202.148.1.57:8501/api/v1/patient?doctor=60b734b0cc2e723dc015acbc&limit=1' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTg2NDEsImV4cCI6MTYyNDQ2MjI0MX0.4OR2e199qinCtJCv0LrbNJImzqA2ZOAoJU4cBCNQaMs' Response: { "message": "ok", "result": [ { "_id": "60bd89003f3c571ce4b0bc6c", "user": { "profile": { "isMale": true, "age": 21, "weight": 55, "height": 160 }, "name": "Julie Ramos" } } ], "count": 6 } ``` ##### Post Patient ``` curl --location --request POST 'http://202.148.1.57:8501/api/v1/patient' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTg2NDEsImV4cCI6MTYyNDQ2MjI0MX0.4OR2e199qinCtJCv0LrbNJImzqA2ZOAoJU4cBCNQaMs' \ --header 'Content-Type: application/json' \ --data-raw '{ "doctor": "60b734b0cc2e723dc015acbc", "name": "test pasien 1", "isMale": true, "dateOfBirth": "1993-08-21", "weight": 60, "height": 165 }' Response: { "message": "created" } ``` ##### Get Patient Detail ``` curl --location --request GET 'http://202.148.1.57:8501/api/v1/patient/60bd89003f3c571ce4b0bc6c?doctor=60b734b0cc2e723dc015acbc' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTg2NDEsImV4cCI6MTYyNDQ2MjI0MX0.4OR2e199qinCtJCv0LrbNJImzqA2ZOAoJU4cBCNQaMs' Response: { "message": "ok", "result": { "_id": "60bd89003f3c571ce4b0bc6c", "user": { "profile": { "isMale": true, "age": 21, "weight": 55, "height": 160 }, "name": "Julie Ramos" } } } ``` ##### Get Patient Count ``` curl --location --request GET 'http://202.148.1.57:8501/api/v1/patient/count?doctor=60b734b0cc2e723dc015acbc' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTg2NDEsImV4cCI6MTYyNDQ2MjI0MX0.4OR2e199qinCtJCv0LrbNJImzqA2ZOAoJU4cBCNQaMs' Response: { "message": "ok", "result": [ { "_id": "2021-06-23", "count": 1 }, { "_id": "2021-06-07", "count": 1 }, { "_id": "2021-06-04", "count": 3 }, { "_id": "2021-06-03", "count": 2 } ] } ``` ##### Delete Patient ``` curl --location --request DELETE 'http://127.0.0.1:8080/api/v1/patient' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjU2NDI5MjIsImV4cCI6MTYyNTY1MDEyMn0.Q4h2loFzrqSYsF0bKIlTpITxQDubuKway_HrbAQ6Rfs' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "60e6b69997478449185fa9bb" }' Response: { "message": "ok", } ``` ##### Patch Patient ``` Request: curl --location --request PATCH 'http://202.148.1.57:8501/api/v1/patient' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2Mjg3NTEzNjAsImV4cCI6MTYyODc1NDk2MH0.15F7pZklYxuiIiqmWUMD2xuJjQ7Nv142-4ciMFFqL-s' \ --header 'Content-Type: application/json' \ --data-raw '{"weight":68,"height":163,"dateOfBirth":"2021-08-02","_id":"6111b5dfa3cfd8412fedc8c2","doctor":"60d57f37b99ba932a04de252"}' Response: { "message": "ok" } ``` ## 4. Device Device adalah koleksi yang memuat informasi perangkat respinos berupa nama perangkat, kapan dibuat, enkripsi token , dsb. Untuk menambah perangkat hanya bisa dilakukan oleh superuser. Akses sementara menggunakan terminal di server. #### Skema Device | No | Field | Tipe Data | Keterangan | | :-: | :-------: | :---------: | :----------------------------------------------------: | | 1 | \_id | string | ID Perangkat | | 2 | createdAt | datetime | | | 3 | token | string | kunci untuk menghubungkan (menambahkan list) perangkat | | 4 | patient | FK | ID pasien yang sedang menggunakan perangkat | | 5 | doctor | FK | ID dokter yang sedang menggunakan perangkat | | 6 | doctors | array of FK | ID dokter yang diperbolehkan mengakses perangkat | | 7 | mode | string | Mode yang sedang berjalan | | 8 | isRun | Boolean | Status perangkat, apakah sedang digunakan atau tidak | #### List API Device Endpoint :`<base_url>/api/v1/device` |No|Metode|Endpoint|Param|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Get|`<endpoint>/`|doctor\*, limit, offset, orderBy, device|-|Mendapatkan list perangkat | |2|Get|`<endpoint>/:id`|-|-| Mendapatkan detail perangkat | |3|Post*|`<endpoint>/link`|-|\_id, token, action| Menghubungkan perangkat | |4|Post*|`<endpoint>/use`|-|\_id, action, mode, doctor, patient | Menggunakan perangkat | |5|Post*|`<endpoint>/control`|-|\_id, action | Mengendalikan perangkat | |6|Post*|`<endpoint>/reset`|-|\_id, token, secret | Mereset pengguna device | |7|Post\*|`<endpoint>/status`|-|\_id, token | Mendapatkan status device | > API untuk mendapatkan status tidak perlu menyisipkan bearer token pada header. > > \*) Deprecated API #### Deskripsi Body / Parameter | No | Item | Tipe Data | Catatan | | :-: | :-----: | :-------: | :-----------------------------------------------------------------------------: | | 1 | doctor | String | user ID Dokter | | 2 | limit | Integer | Jumlah data yang direquest | | 3 | offset | Integer | Banyak data yang di skip | | 4 | orderBy | String | Jenis urutan data pasien | | 5 | id | String | ID Perangkat | | 6 | token | String | Token Perangkat | | 7 | action | String | Aksi untuk menambahkan list/ mengapus list perangkat, nilai valid: link, unlink | | 8 | patient | String | ID pasien | | 9 | action | String | Aksi untuk menggunakan perangkat (start, stop) | | 10 | device | String | nama ID device | | 11 | secret | String | String rahasia untuk menghapus user | > Catatan : > TODO : ditambah dokter sbg parameter pada device detail > TODO : ubah nama link -> add list device? > Registrasi perangkat oleh superuser -> post "/link" -> post "/use" #### Sample Request - Using Curl ##### Get Device ``` curl --location --request GET 'http://localhost:8080/api/v1/device?doctor=60d57f37b99ba932a04de252&limit=1' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' Response: { "message": "ok", "result": [ { "isRun": false, "_id": "respinos02", "createdAt": "2021-06-28T22:50:10.025Z" } ], "count": 2 } ``` ##### Get Device Detail ``` curl --location --request GET 'http://localhost:8080/api/v1/device/respinos01' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' Response: { "message": "ok", "result": { "_id": "respinos01", "createdAt": "2021-06-28T22:46:03.888Z", "isRun": false, "doctor": { "profile": { "workingPlace": "RS Hasan Sadikin" }, "role": "doctor", "name": "dr. Yudi Aditya", "isRequestUser": true }, "patient": { "_id": "60d95395bbe7b85b3f7cc7d2", "user": { "profile": { "isMale": true, "dateOfBirth": "2021-06-22T00:00:00.000Z", "weight": 23, "height": 231 }, "name": "pasien 2" } } } } ``` ##### Post Device Link (Deprecated) ``` curl --location --request POST 'http://localhost:8080/api/v1/device/link' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos02", "action": "link", "token": "123" }' Response: { "message": "ok" } ``` ##### Post Device Unlink (Deprecated) ``` curl --location --request POST 'http://localhost:8080/api/v1/device/link' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos02", "action": "unlink" }' Response: { "message": "ok" } ``` ##### Post Device Use (Deprecated) ``` curl --location --request POST 'http://localhost:8080/api/v1/device/use' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos01", "action":"use", "mode":"basic", "doctor":"60d57f37b99ba932a04de252", "patient":"60d58a34b99ba932a04de254" }' Response: { "message": "ok" } ``` ##### Post Device Control (Deprecated) ``` curl --location --request POST 'http://127.0.0.1:8080/api/v1/device/control' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2Mjg1NzI4NDYsImV4cCI6MTYyODU3NjQ0Nn0.nGP1qORMy-BtPhyUNgLCCM73H2clVJwPjjtM4KCQc9Y' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos05", "action":"start" }' Response: { "message": "ok", "recordId": "61121542527d4b38806e1173" } ``` ##### Post Device Reset (Deprecated) ``` Request: curl --location --request POST 'http://202.148.1.57:8501/api/v1/device/reset' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos02", "token": "123", "secret": "X5l4SsKJkXFy253s3X2ISJvqeU8FFi" }' Response: { "message": "ok" } ``` ##### Post Device Status (Deprecated) ``` Request: curl --location --request POST 'http://127.0.0.1:8080/api/v1/device/status' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "respinos02", "token": "123" }' Response: { "message": "ok", "result": { "_id": "respinos02", "isRun": false } } ``` ## 5. Record Data rekam medis pasien berupa pengukuran mode basic atau spirometer disimpan dalam koleksi record. Data rekam medis hanya bisa diakses oleh dokter yang menangani pasien. #### Skema Record | No | Field | Tipe Data | Keterangan | | :-: | :--------: | :----------------------------------: | :-------------------------------------------: | | 1 | \_id | string | ID Rekam medis | | 2 | patient | FK | ref: patient | | 3 | doctors | array of Object : {doctor, viewOnly} | doctor ref: User | | 4 | createdAt | datetime | | | 5 | testNumber | int | nomor tes pengukuran | | 6 | mode | string | mode pengukuran (basic, spirometer) | | 7 | sensors | object | data pengukuran. Isi berbeda, tergantung mode | | 8 | notes | list of String | catatan dokter | | 9 | device | String | Perangkat | #### List API Record Endpoint :`<base_url>/api/v1/record` |No|Metode|Endpoint|Param|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Get|`<endpoint>/`|patient, limit, offset, orderBy, fields|-|Mendapatkan list rekam medis | |2|Delete|`<endpoint>/`||\_id|Menghapus rekam medis | |3|Patch|`<endpoint>/`|-|\_id, sensors, notes | Mengubah data rekam medis (sensor, catatan) | |4|Get|`<endpoint>/:id`|-|-| Mendapatkan detail rekam medis | |5|Get|`<endpoint>/count`|-|-| Mendapatkan jumlah rekam medis harian| |6|Get|`<endpoint>/statistic`|startDate, endDate, patient, mode |-|Mendapatkan nilai statistik rekam medis| |7|Post\*|`<endpoint>/result`|-| record, result |Menyimpan (mengganti) data hasil sensor| |8|Post|`<endpoint>`|-| patient, device, createdAt, mode, sensors |Menyimpan data hasil sensor| > catatan: > api record/result akan menimpa hasil sebelumnya > \*) Deprecated API #### Deskripsi Body / Parameter | No | Item | Tipe Data | Catatan | | :-: | :-------: | :-------------: | :----------------------------------------------------------------------------------------------------------------: | | 1 | patient | String | ID Pasien | | 2 | limit | Integer | Jumlah data yang direquest | | 3 | offset | Integer | Banyak data yang di skip | | 4 | orderBy | String | Jenis urutan data pasien | | 5 | fields | String | field yang ingin diperoleh dari database | | 5 | \_id | String | ID rekam medis | | 6 | sensor | Object | Data sensor | | 7 | notes | Array of String | Catatan Dokter | | 8 | startDate | Date | tanggal awal | | 9 | endDate | Date | tanggal akhir | | 10 | result\* | Object | basic: {"RR": array, "SPO2": array, "T": array} | | | | | spirometer: {"FVC": number, "FEV1": number, "ratio": number, "PEF": number, "FC": array, "VC": array, "VT": array} | | 11 | createdAt | Datetime | Tanggal & Waktu (format mengikuti ISO 8601) | > catatan: > Nilai valid fields: "patient", "createdAt", "testNumber", "sensors", "notes", "mode" > Sensor merupakan object yang terdiri atas pasangan key - value : {FVC: number, FEV1: number, ratio: number, PEF: number, FC: array, VC: array, VT: array} > Gunakan tanda "," untuk menghapus lebih dari 1 rekam medis pada parameter \_id #### Sample Request - Using Curl ##### Get Record ``` curl --location --request GET 'http://202.148.1.57:8501/api/v1/record?limit=1' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGI3MzRiMGNjMmU3MjNkYzAxNWFjYmMiLCJpYXQiOjE2MjQ0NTg2NDEsImV4cCI6MTYyNDQ2MjI0MX0.4OR2e199qinCtJCv0LrbNJImzqA2ZOAoJU4cBCNQaMs' Response: { "message": "ok", "result": [ { "_id": "60b8a2e2100ae315889dae6e", "patient": { "_id": "60b844faa4f6634074b5af48", "user": { "name": "Aubrey Robbins" } }, "testNumber": 2, "createdAt": "2021-06-04T09:59:15.000" } ], "count": 2 } ``` ##### Get Record Detail ``` curl --location --request GET 'http://localhost:8080/api/v1/record/60da9d6fa99d353944b490ac' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' Response: { "message": "ok", "result": { "sensors": { "RR": [], "SPO2": [], "T": [], "FC": [], "VC": [], "VT": [] }, "mode": "basic", "notes": [], "_id": "60da9d6fa99d353944b490ac", "patient": { "_id": "60d58a34b99ba932a04de254", "user": { "profile": { "avatar": "default-avatar.png", "isMale": true, "dateOfBirth": "1983-03-14T00:00:00.000Z", "weight": 65, "height": 170 }, "name": "Pasien 1" } }, "testNumber": 2, "device": "respinos02", "createdAt": "2021-06-29T04:11:27.873Z", "__v": 0 } } ``` ##### Get Record Detail ``` curl --location --request DELETE 'http://localhost:8080/api/v1/record' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjQ5Mzg3NzEsImV4cCI6MTYyNDk0MjM3MX0.U3EkNYzRL0QllxClwAm71cZtj5SWSpcJjPjgeqN_kd8' \ --header 'Content-Type: application/json' \ --data-raw '{ "_id": "60da9d6fa99d353944b490ac" }' Response : { "message": "ok", "result": { "n": 1, "ok": 1, "deletedCount": 1 } } ``` ``` Request : curl --location --request GET 'http://202.148.1.57:8501/api/v1/record/statistic?startDate=2021-07-01&endDate=2021-07-05&patient=60d95395bbe7b85b3f7cc7d2' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2MjU3MTE0MjUsImV4cCI6MTYyNTcxNTAyNX0.8bXIOIRN-oxSsj5QynMGiT-AJ-ntU2pJCEl38EnQ29U' Response : { "message": "ok", "result": [ { "_id": "60dd34554cad271a7c3a531f", "createdAt": "2021-07-01T03:19:49.043Z", "testNumber": 2, "RR": { "n": 10, "avg": 45.9, "min": 12, "max": 74, "stdv": 20.28521629167409 }, "T": { "n": 10, "avg": 37.196999999999996, "min": 33.83, "max": 41.64, "stdv": 2.5028665565706865 }, "SPO2": { "n": 10, "avg": 67.1, "min": 50, "max": 94, "stdv": 14.494481708567573 } }, { "_id": "60dd5fb9f771d30f609187a3", "createdAt": "2021-07-01T06:24:57.436Z", "testNumber": 3, "RR": { "n": 11, "avg": 48, "min": 4, "max": 77, "stdv": 21.144524328792762 }, "T": { "n": 11, "avg": 36.78, "min": 33.6, "max": 41.57, "stdv": 2.3854978516024676 }, "SPO2": { "n": 11, "avg": 81.27272727272727, "min": 64, "max": 99, "stdv": 10.74574680420888 } } ] } ``` ##### Post Record Result (Deprecated) ``` curl --location --request POST 'http://127.0.0.1:8080/api/v1/record/result' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2Mjg1NzI4NDYsImV4cCI6MTYyODU3NjQ0Nn0.nGP1qORMy-BtPhyUNgLCCM73H2clVJwPjjtM4KCQc9Y' \ --header 'Content-Type: application/json' \ --data-raw '{ "record": "61120c9ab3f3693c1c2713f5", "result": { "FVC": 1, "FEV1": 2, "ratio": 3, "PEF": 4, "FC": [1,2,3], "VC": [1,2,3], "VT": [1,2,3] } } ' Response: { "message": "ok" } ``` ##### Post Record ``` curl --location --request POST 'http://192.168.2.7:8080/api/v1/record' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFkaXR5YUBtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MGQ1N2YzN2I5OWJhOTMyYTA0ZGUyNTIiLCJpYXQiOjE2NDI0MDI4NzgsImV4cCI6MTY0MjQwNjQ3OH0.ffRVlPIdNHISpBOiLQ0TEHj83zglnZNNZWLV8lWe3xk' \ --header 'Content-Type: application/json' \ --data-raw '{ "patient": "60d58a34b99ba932a04de254", "device": "respinos03", "mode": "basic", "sensors": { "RR": [1,2,3], "SPO2": [4,5,6], "T": [7,8,9], "HR": [10,11,12] }, "createdAt": "2022-10-01T16:23:02.23" }' ' Response: { "message": "ok", "record": "61e5181c3484203124a62427" } ``` ## 6. Pulmonary Function Pulmonary Function merupakan nilai ideal paru orang Indonesia. Nilai tersebut memuat FVC, FEV1, FEV1/FVC dan PEFR. Nilai ini digenerate dengan rumus tertentu dengan input nilai : isMale, height dan age. #### Skema Pulmonary Function | No | Field | Tipe Data | Keterangan | | :-: | :------: | :-------: | :--------: | | 1 | FVC | float | - | | 2 | FEV1 | float | - | | 3 | FEV1/FVC | float | - | | 4 | PEFR | float | - | #### List API Pulmonary Function Endpoint :`<base_url>/api/v1/pulmonary-function` |No|Metode|Endpoint|Param|Body|Deskripsi| |:----:|:----:|:-----:|:-----:|:-----:|:-----:| |1|Get|`<endpoint>/:patient_id`| - | - | Mendapatkan perhitungan nilai faal paru untuk pasien tertentu | #### Sample Request - Using Curl ##### Get Pulmunary Function ``` curl --location --request GET 'http://127.0.0.1:8080/api/v1/pulmonary-function/611ba637ae8d6d585c645c3a' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Inl1ZGkuYWRpdHlhLjg5QGdtYWlsLmNvbSIsInJvbGUiOiJkb2N0b3IiLCJfaWQiOiI2MTFiOTAyMmFlOGQ2ZDU4NWM2NDVjMzYiLCJpYXQiOjE2MzU3MzAyNDYsImV4cCI6MTYzNTczMzg0Nn0.n-LNleXZ7aPwLRhp0dYWX_OyLmdzN5dvFAztLMxrvYE' Response: { "message": "ok", "result": { "fvc": 3.001, "fev1": 2.691, "fev1FvcRatio": 91.216, "pefr": 7.292 } } ``` # MQTT API ## 1. Pendahuluan 1. Selain dengan menggunakan rest API, respinos juga bisa berinteraksi dibawah protokol mqtt, endpoint yang digunakan adalah `mqtt://<ip_address>:<port>`. Jika aplikasi tidak mendukung komunikasi melalui mqtt, developer bisa menggunakan websocket sebagai gantinya dengan port yang berbeda. 2. Pada saat membuat koneksi dengan broker respinos, perlu diset username & password. Hubungi admin untuk mendapatkan username & passwordnya. ## 2. Skema Komunikasi 1. Basic Mode (Deprecated) ```sequence Note left of Client: start/stop Client->Server: send request Note right of Server: validate request Server->Broker: send command (mqtt) Broker->Device: forward command Server->Client: send response Device->Broker: send payload Broker->Client: broadcast payload ``` > Asumsi perangkat sudah terhubung dengan jaringan internet 2. Device State (Deprecated) ```sequence Note left of Client: state Client->Broker: send command (state) Broker->Device: forward command Device->Broker: send state Broker->Client: broadcast state ``` 3. Basic Mode ```sequence Client 1->Device: command (BLE) Device->Client 1: sensor data (BLE) Client 1->Broker: sensor data (MQTT) Broker -> Client 2: sensor data (MQTT) Client 1 -> Server: record data (HTTP) Note right of Server: store data ``` ## 3. Available Topic | No | Topic | Publish | Subscribe | qos | Catatan | Format Message | | :-: | :-------------------: | :-----: | :-----------------: | :-: | :-----------------------------------------------------: | :--------------------------------------------------: | | 1 | <deviceID> | device | app (Deprecated) | 0 | Mengirimkan data sensor mode basic | `{"payload": {"key_1": val_1, "key_2": val_2, ...}}` | | 2 | <deviceID>/cmd | server | device (Deprecated) | 2 | Mengirimkan perintah ke perangkat | `{cmd: <cmd>, "mode":<mode> }` | | 3 | <deviceID>/state | device | app (Deprecated) | 1 | Info status perangkat, dikirim pada saat request status | `{state: <state> }` | | 4 | notification/<userID> | server | app | 2 | Notification | `{message: <message>, createdAt: <datetime> }` | | 5 | <deviceID>/v2 | app | app | 0 | Mengirim data sensor mode basic | `{"payload": {"key_1": val_1, "key_2": val_2, ...}}` | > untuk menjalankan, menghentikan perangkat, gunakan rest api pada server, karena perlu pemutakhiran data. Command start/stop akan dihandle oleh server. #### Deskripsi Parameter | No | Item | Tipe Data | Catatan | | :-: | :------: | :-------: | :------------------------------------------------------------------: | | 1 | deviceID | String | ID Perangkat | | 2 | payload | Object | Nilai parameter yang dibaca sensor | | 3 | cmd | String | Perintah yang diassign ke perangkat, nilai valid: start, stop, state | | 4 | mode | String | Mode pengukuran: (basic, spirometer) | | 5 | state | String | Mode pengukuran: (idle, running) | > contoh payload : `{"payload": {"RR": 123, "SPO2": 123, "T": 123}}` # Respinos Device API Ada dua teknologi yang digunakan untuk berkomunikasi dengan perangkat respinos yaitu melalui Wifi dan bluetooth. Komunikasi melalui wifi digunakan untuk mengetahui status perangkat, konfigurasi wifi perangkat, kendali pengukuran dan pengiriman hasil perhitungan mode basic. Sedangkan komunikasi melalui bluetooth digunakan kendali dan pengiriman hasil pengukuran pada mode spirometer. ### Untuk menggunakan api ini, client perlu terhubung dengan perangkat respinos dengan menggunakan wifi. Untuk terhubung ke perangkat respinos, kita perlu memilih respinos sebagai access point dan memasukan token respinos sebagai password. Endpoint :`http://192.168.4.1` | No | Metode | Endpoint | Param | Body | Deskripsi | | :-: | :----: | :--------------------: | :---: | :------------: | :------------------------------------------------: | | 1 | Get | `<endpoint>` | - | - | Mendapatkan status koneksi perangkat | | 2 | Get | `<endpoint>/scan-wifi` | - | - | Mendapatkan list scanned wifi & kekuatan sinyalnya | | 3 | Post | `<endpoint>/set-wifi` | - | ssid, password | Konfigurasi ssid wifi dan password | > untuk mengubah kekuatan sinyal ke dalam persentasi diperlukan konversi. berikut adalah contoh konversi dengan menggunakan bahasa javascript. ``` const dbmToPercentage = (dBm) => { const RSSI_MAX = -50; const RSSI_MIN = -100; let quality; if (dBm <= RSSI_MIN) { quality = 0; } else if (dBm >= RSSI_MAX) { quality = 100; } else { quality = 2 * (dBm + 100); } return quality; }; ``` #### Sample Request - Using Curl ##### Get Status ``` curl --location --request GET 'http://192.168.4.1' Response: - ``` ##### Get Scanned Wifi ``` curl --location --request GET 'http://192.168.4.1/scan-wifi' Response: - ``` ##### Post Set Wifi ``` curl --location --request POST 'http://192.168.4.1/set-wifi' \ --data-raw '{ "ssid": "smart xirka", "password": "test123abc", } Response: - ```