"use strict" ; import { AWSError , DynamoDB } from "aws-sdk" ; import { v4 as uuid } from "uuid" ; import { PatientParam , Status , StatusParam , Patient , } from "../lambda/definitions/types" ; export default class PatientTable { client : DynamoDB . DocumentClient ; constructor ( serviceClient ) { this . client = serviceClient ; } getPatients ( centerId ) { const params = { TableName : process . env . PATIENT_TABLE_NAME ! , } ; return new Promise ( ( resolve , reject ) => { this . client . scan ( params , ( err , data ) => { if ( err ) { console . log ( err ) ; reject ( err ) ; } else { const filtered = data . Items ! . filter ( ( item ) => item . centerId === centerId ) ; resolve ( { Count : filtered . length , Items : filtered } ) ; } } ) ; } ) ; } getPatient ( patientId ) { const params = { TableName : process . env . PATIENT_TABLE_NAME ! , Key : { patientId : patientId , } , } ; return new Promise ( ( resolve , reject ) => { this . client . get ( params , ( err , data ) => { if ( err ) { console . log ( err ) ; reject ( err ) ; } else { resolve ( data . Item ! as Patient ) ; } } ) ; } ) ; } searchPhone ( phone ) { const query = { TableName : process . env . PATIENT_TABLE_NAME ! , IndexName : "RemotePatientMonitoringPatientTableGSIPhone" , KeyConditionExpression : "phone = :phone" , ExpressionAttributeValues : { ":phone" : phone } , ProjectionExpression : "patientId" , } ; return new Promise ( ( resolve ) => { this . client . query ( query , ( err , data ) => { if ( err ) { console . log ( err ) ; resolve ( undefined ) ; } else { if ( data . Count ! > 0 ) { resolve ( data . Items ! [ 0 ] . patientId ) ; } else { resolve ( undefined ) ; } } } ) ; } ) ; } async postPatient ( patient ) { const params = { TableName : process . env . PATIENT_TABLE_NAME ! , Item : patient , } ; const ret = await this . searchPhone ( patient . phone ) ; return new Promise ( ( resolve , reject ) => { if ( ret ) { reject ( { message : "phone already exists" } ) ; } else { this . client . put ( params , ( err ) => { if ( err ) { console . log ( err ) ; reject ( err ) ; } else { resolve ( patient ) ; } } ) ; } } ) ; } putPatient ( patientId , patient ) { let updateExpression = "set phone = :phone, display = :display, centerId = :centerId" ; const expressionAttributeValues = { ":phone" : patient . phone , ":display" : patient . display , ":centerId" : patient . centerId , ":statuses" : patient . statuses , } ; if ( patient . policy_accepted !== undefined ) { updateExpression += ", policy_accepted = :policy_accepted" ; expressionAttributeValues [ ":policy_accepted" ] = patient . policy_accepted ; } if ( patient . memo !== undefined ) { updateExpression += ", memo = :memo" ; expressionAttributeValues [ ":memo" ] = patient . memo ; } if ( patient . statuses ) { updateExpression += ", statuses = :statuses" ; expressionAttributeValues [ ":statuses" ] = patient . statuses ; } const params = { TableName : process . env . PATIENT_TABLE_NAME ! , Key : { patientId : patientId , } , UpdateExpression : updateExpression , ExpressionAttributeValues : expressionAttributeValues , } ; console . log ( params ) ; return new Promise ( ( resolve , reject ) => { this . client . update ( params , ( err , data ) => { console . log ( data ) ; if ( err ) { console . log ( err ) ; reject ( err ) ; } else { resolve ( patient ) ; } } ) ; } ) ; } acceptPolicy ( patientId ) { const updateExpression = "set policy_accepted = :policy_accepted" ; const policy_accepted_time = new Date ( ) . toISOString ( ) ; const expressionAttributeValues = { ":policy_accepted" : policy_accepted_time , } ; const params = { TableName : process . env . PATIENT_TABLE_NAME ! , Key : { patientId : patientId , } , UpdateExpression : updateExpression , ExpressionAttributeValues : expressionAttributeValues , } ; return new Promise ( ( resolve , reject ) => { this . client . update ( params , ( err ) => { if ( err ) { console . log ( err ) ; reject ( err ) ; } else { resolve ( { result : "OK" , policy_accepted : policy_accepted_time } ) ; } } ) ; } ) ; } async postPatientStatus ( patientId , centerId , param ) { try { const requestBody = { patientId : patientId , statusId : uuid ( ) , centerId : centerId , created : param . created || new Date ( ) . toISOString ( ) , SpO2 : param . SpO2 , body_temperature : param . body_temperature , pulse : param . pulse , } ; if ( param . symptom ) { requestBody . symptom = { ... param . symptom , symptomId : uuid ( ) , } ; } const params = { TableName : process . env . PATIENT_TABLE_NAME ! , Key : { patientId : patientId , } , UpdateExpression : "set #statuses = list_append(:status, if_not_exists(#statuses, :emptyList))" , ExpressionAttributeNames : { "#statuses" : "statuses" , } , ExpressionAttributeValues : { ":status" : [ requestBody ] , ":emptyList" : [ ] , } , } ; await this . client . update ( params ) . promise ( ) ; return Promise . resolve ( requestBody ) ; } catch ( err ) { console . log ( err ) ; throw err ; } } async deletePatientStatus ( patientId , statusId ) { try { const ret = await this . getPatient ( patientId ) ; const patient = ret as Patient ; if ( patient . statuses ) { if ( patient . statuses . findIndex ( ( item ) => item . statusId === statusId ) === - 1 ) { throw new Error ( "no status found" ) ; } patient . statuses . splice ( patient . statuses . findIndex ( ( item ) => item . statusId === statusId ) , 1 ) ; } const ret2 = await this . putPatient ( patientId , patient ) ; return Promise . resolve ( ret2 ) ; } catch ( err ) { console . log ( err ) ; throw err ; } } }