Skip to content

Commit

Permalink
feat: add record blood sugar api
Browse files Browse the repository at this point in the history
  • Loading branch information
Salaton committed Sep 14, 2023
1 parent c5ffcf9 commit 4f246cf
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/clinical/application/common/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ const (
// MuacCIELTerminologyCode is the terminology code for mid-upper arm circumference
MuacCIELTerminologyCode = "1343"

// BloodSugarCIELTerminologyCode is the terminology code for blood sugar (Serum glucose)
BloodSugarCIELTerminologyCode = "887"

// Spoc2CIELTerminologyCode is the terminology code oxygen saturation
OxygenSaturationCIELTerminologyCode = "5092"

Expand Down
1 change: 1 addition & 0 deletions pkg/clinical/presentation/graph/clinical.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extend type Mutation {
recordViralLoad(input: ObservationInput!): Observation!
recordMUAC(input: ObservationInput!): Observation!
recordOxygenSaturation(input: ObservationInput!): Observation!
recordBloodSugar(input: ObservationInput!): Observation!

# Patient
createPatient(input: PatientInput!): Patient!
Expand Down
6 changes: 6 additions & 0 deletions pkg/clinical/presentation/graph/clinical.resolvers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 108 additions & 0 deletions pkg/clinical/presentation/graph/generated/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions pkg/clinical/usecases/clinical/observation.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ func (c *UseCasesClinicalImpl) GetPatientBMIEntries(ctx context.Context, patient
return c.GetPatientObservations(ctx, patientID, common.BMICIELTerminologyCode, pagination)
}

// RecordBloodSugar records a patient's blood sugar level (Serum glucose)
func (c *UseCasesClinicalImpl) RecordBloodSugar(ctx context.Context, input dto.ObservationInput) (*dto.Observation, error) {
bloodSugarObservation, err := c.RecordObservation(ctx, input, common.BloodSugarCIELTerminologyCode)
if err != nil {
return nil, err
}

return bloodSugarObservation, nil
}

// RecordObservation is an extracted function that takes any observation input and saves it to FHIR.
// A concept ID is also passed so that we can get the concept code of the passed observation
func (c *UseCasesClinicalImpl) RecordObservation(ctx context.Context, input dto.ObservationInput, vitalSignConceptID string) (*dto.Observation, error) {
Expand Down
156 changes: 156 additions & 0 deletions pkg/clinical/usecases/clinical/observation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3383,3 +3383,159 @@ func TestUseCasesClinicalImpl_RecordViralLoad(t *testing.T) {
})
}
}

func TestUseCasesClinicalImpl_RecordBloodSugar(t *testing.T) {
ctx := context.Background()
type args struct {
ctx context.Context
input dto.ObservationInput
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Happy Case - Successfully record blood sugar",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "12",
},
},
wantErr: false,
},
{
name: "Sad Case - Fail to record blood sugar",
args: args{
ctx: ctx,
input: dto.ObservationInput{
EncounterID: uuid.New().String(),
Value: "12",
},
},
wantErr: true,
},
{
name: "Sad Case - Fail to get encounter",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "1234",
},
},
wantErr: true,
},
{
name: "Sad Case - return a finished encounter",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "1234",
},
},
wantErr: true,
},
{
name: "Sad Case - Fail to get CIEL concept",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "1234",
},
},
wantErr: true,
},
{
name: "Sad Case - Fail to get tenant meta tags",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "1234",
},
},
wantErr: true,
},
{
name: "Sad Case - Fail to create observation",
args: args{
ctx: ctx,
input: dto.ObservationInput{
Status: dto.ObservationStatusFinal,
EncounterID: uuid.New().String(),
Value: "1234",
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fakeExt := fakeExtMock.NewFakeBaseExtensionMock()
fakeFHIR := fakeFHIRMock.NewFHIRMock()
fakeOCL := fakeOCLMock.NewFakeOCLMock()
fakePubSub := fakePubSubMock.NewPubSubServiceMock()

fakeUpload := fakeUploadMock.NewFakeUploadMock()

infra := infrastructure.NewInfrastructureInteractor(fakeExt, fakeFHIR, fakeOCL, fakeUpload, fakePubSub)
c := clinicalUsecase.NewUseCasesClinicalImpl(infra)

if tt.name == "Sad Case - Fail to get encounter" {
fakeFHIR.MockGetFHIREncounterFn = func(ctx context.Context, id string) (*domain.FHIREncounterRelayPayload, error) {
return nil, fmt.Errorf("failed to get encounter")
}
}

if tt.name == "Sad Case - return a finished encounter" {
fakeFHIR.MockGetFHIREncounterFn = func(ctx context.Context, id string) (*domain.FHIREncounterRelayPayload, error) {
return &domain.FHIREncounterRelayPayload{
Resource: &domain.FHIREncounter{
Status: domain.EncounterStatusEnumFinished,
},
}, nil
}
}

if tt.name == "Sad Case - Fail to get CIEL concept" {
fakeOCL.MockGetConceptFn = func(ctx context.Context, org, source, concept string, includeMappings, includeInverseMappings bool) (*domain.Concept, error) {
return nil, fmt.Errorf("fail to get concept")
}
}

if tt.name == "Sad Case - Fail to get tenant meta tags" {
fakeExt.MockGetTenantIdentifiersFn = func(ctx context.Context) (*dto.TenantIdentifiers, error) {
return nil, fmt.Errorf("failed to get tenant identifiers")
}
}

if tt.name == "Sad Case - Fail to create observation" {
fakeFHIR.MockCreateFHIRObservationFn = func(ctx context.Context, input domain.FHIRObservationInput) (*domain.FHIRObservation, error) {
return nil, fmt.Errorf("failed to create observation")
}
}

got, err := c.RecordBloodSugar(tt.args.ctx, tt.args.input)
if (err != nil) != tt.wantErr {
t.Errorf("UseCasesClinicalImpl.RecordBloodSugar() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
if got == nil {
t.Errorf("expected a response but got %v", got)
return
}
}
})
}
}
1 change: 1 addition & 0 deletions pkg/clinical/usecases/usecases.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type Clinical interface {
RecordViralLoad(ctx context.Context, input dto.ObservationInput) (*dto.Observation, error)
RecordMuac(ctx context.Context, input dto.ObservationInput) (*dto.Observation, error)
RecordOxygenSaturation(ctx context.Context, input dto.ObservationInput) (*dto.Observation, error)
RecordBloodSugar(ctx context.Context, input dto.ObservationInput) (*dto.Observation, error)
RecordObservation(ctx context.Context, input dto.ObservationInput, vitalSignConceptID string) (*dto.Observation, error)

GetPatientObservations(ctx context.Context, patientID string, observationCode string, pagination *dto.Pagination) (*dto.ObservationConnection, error)
Expand Down

0 comments on commit 4f246cf

Please sign in to comment.