Skip to content

Commit

Permalink
feat: search allergy
Browse files Browse the repository at this point in the history
- searches for allegy by the provided name

Signed-off-by: Kathurima Kimathi <kathurimakimathi415@gmail.com>
  • Loading branch information
KathurimaKimathi committed Mar 29, 2023
1 parent 34543da commit bd543e8
Show file tree
Hide file tree
Showing 16 changed files with 589 additions and 82 deletions.
7 changes: 7 additions & 0 deletions pkg/clinical/application/dto/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,10 @@ type Condition struct {
PatientID string `json:"patientID"`
EncounterID string `json:"encounterID"`
}

// Terminology models the OCL terminology output
type Terminology struct {
Code string `json:"code"`
System TerminologySource `json:"system"`
Name string `json:"name"`
}
46 changes: 22 additions & 24 deletions pkg/clinical/domain/concept.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
package domain

import "time"

// Concept models a concept type from OpenConceptLab
type Concept struct {
ConceptClass string `mapstructure:"concept_class" json:"concept_class"`
DataType string `mapstructure:"datatype" json:"datatype"`
DisplayLocale string `mapstructure:"display_locale" json:"display_locale"`
DisplayName string `mapstructure:"display_name" json:"display_name"`
ExternalID string `mapstructure:"external_id" json:"external_id"`
ID string `mapstructure:"id" json:"id"`
IsLatestVersion bool `mapstructure:"is_latest_version" json:"is_latest_version"`
Locale *string `mapstructure:"locale" json:"locale"`
Owner string `mapstructure:"owner" json:"owner"`
OwnerType string `mapstructure:"owner_type" json:"owner_type"`
OwnerURL string `mapstructure:"owner_url" json:"owner_url"`
Retired bool `mapstructure:"retired" json:"retired"`
Source string `mapstructure:"source" json:"source"`
Type string `mapstructure:"type" json:"type"`
UpdateComment string `mapstructure:"update_comment" json:"update_comment"`
URL string `mapstructure:"url" json:"url"`
UUID string `mapstructure:"uuid" json:"uuid"`
Version string `mapstructure:"version" json:"version"`
VersionCreatedBy string `mapstructure:"version_created_by" json:"version_created_by"`
VersionCreatedOn *time.Time `mapstructure:"version_created_on" json:"version_created_on"`
VersionURL string `mapstructure:"version_url" json:"version_url"`
VersionsURL string `mapstructure:"versions_url" json:"versions_url"`
ConceptClass string `mapstructure:"concept_class" json:"concept_class"`
DataType string `mapstructure:"datatype" json:"datatype"`
DisplayLocale string `mapstructure:"display_locale" json:"display_locale"`
DisplayName string `mapstructure:"display_name" json:"display_name"`
ExternalID string `mapstructure:"external_id" json:"external_id"`
ID string `mapstructure:"id" json:"id"`
IsLatestVersion bool `mapstructure:"is_latest_version" json:"is_latest_version"`
Locale *string `mapstructure:"locale" json:"locale"`
Owner string `mapstructure:"owner" json:"owner"`
OwnerType string `mapstructure:"owner_type" json:"owner_type"`
OwnerURL string `mapstructure:"owner_url" json:"owner_url"`
Retired bool `mapstructure:"retired" json:"retired"`
Source string `mapstructure:"source" json:"source"`
Type string `mapstructure:"type" json:"type"`
UpdateComment string `mapstructure:"update_comment" json:"update_comment"`
URL string `mapstructure:"url" json:"url"`
UUID string `mapstructure:"uuid" json:"uuid"`
Version string `mapstructure:"version" json:"version"`
VersionCreatedBy string `mapstructure:"version_created_by" json:"version_created_by"`
VersionCreatedOn string `mapstructure:"version_created_on" json:"version_created_on"`
VersionURL string `mapstructure:"version_url" json:"version_url"`
VersionsURL string `mapstructure:"versions_url" json:"versions_url"`
}
4 changes: 2 additions & 2 deletions pkg/clinical/infrastructure/infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ type ServiceOCL interface {
ctx context.Context, org string, source string, verbose bool, q *string,
sortAsc *string, sortDesc *string, conceptClass *string, dataType *string,
locale *string, includeRetired *bool,
includeMappings *bool, includeInverseMappings *bool) ([]map[string]interface{}, error)
includeMappings *bool, includeInverseMappings *bool) ([]*domain.Concept, error)
GetConcept(
ctx context.Context, org string, source string, concept string,
includeMappings bool, includeInverseMappings bool) (map[string]interface{}, error)
includeMappings bool, includeInverseMappings bool) (*domain.Concept, error)
}

// BaseExtension is an interface that represents some methods in base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"io"
"net/http"
"net/url"

"github.com/savannahghi/clinical/pkg/clinical/domain"
)

// FakeOCL is an mock of the Open concept lab
Expand All @@ -14,10 +16,10 @@ type FakeOCL struct {
ctx context.Context, org string, source string, verbose bool, q *string,
sortAsc *string, sortDesc *string, conceptClass *string, dataType *string,
locale *string, includeRetired *bool,
includeMappings *bool, includeInverseMappings *bool) ([]map[string]interface{}, error)
includeMappings *bool, includeInverseMappings *bool) ([]*domain.Concept, error)
MockGetConceptFn func(
ctx context.Context, org string, source string, concept string,
includeMappings bool, includeInverseMappings bool) (map[string]interface{}, error)
includeMappings bool, includeInverseMappings bool) (*domain.Concept, error)
}

// NewFakeOCLMock initializes a new instance of ocl mock
Expand All @@ -28,25 +30,24 @@ func NewFakeOCLMock() *FakeOCL {
StatusCode: 200,
}, nil
},
MockListConceptsFn: func(
ctx context.Context, org string, source string, verbose bool, q *string,
sortAsc *string, sortDesc *string, conceptClass *string, dataType *string,
locale *string, includeRetired *bool,
includeMappings *bool, includeInverseMappings *bool) ([]map[string]interface{}, error) {
m := map[string]interface{}{
"concept": "C00001",
}
return []map[string]interface{}{
m,
MockListConceptsFn: func(ctx context.Context, org, source string, verbose bool, q, sortAsc, sortDesc, conceptClass, dataType, locale *string, includeRetired, includeMappings, includeInverseMappings *bool) ([]*domain.Concept, error) {
return []*domain.Concept{
{
ConceptClass: "CIEL",
DataType: "N/A",
DisplayLocale: "en/us",
DisplayName: "test",
ExternalID: "1234",
ID: "1234",
},
}, nil
},
MockGetConceptFn: func(
ctx context.Context, org string, source string, concept string,
includeMappings bool, includeInverseMappings bool) (map[string]interface{}, error) {
m := map[string]interface{}{
"id": "C12345",
}
return m, nil
includeMappings bool, includeInverseMappings bool) (*domain.Concept, error) {
return &domain.Concept{
ID: "1234",
}, nil
},
}
}
Expand All @@ -61,13 +62,13 @@ func (o *FakeOCL) ListConcepts(
ctx context.Context, org string, source string, verbose bool, q *string,
sortAsc *string, sortDesc *string, conceptClass *string, dataType *string,
locale *string, includeRetired *bool,
includeMappings *bool, includeInverseMappings *bool) ([]map[string]interface{}, error) {
includeMappings *bool, includeInverseMappings *bool) ([]*domain.Concept, error) {
return o.MockListConceptsFn(ctx, org, source, verbose, q, sortAsc, sortDesc, conceptClass, dataType, locale, includeRetired, includeMappings, includeInverseMappings)
}

// GetConcept is a mock implementation of getting a concept
func (o *FakeOCL) GetConcept(
ctx context.Context, org string, source string, concept string,
includeMappings bool, includeInverseMappings bool) (map[string]interface{}, error) {
includeMappings bool, includeInverseMappings bool) (*domain.Concept, error) {
return o.MockGetConceptFn(ctx, org, source, concept, includeMappings, includeInverseMappings)
}
34 changes: 28 additions & 6 deletions pkg/clinical/infrastructure/services/openconceptlab/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"strconv"
"time"

"github.com/mitchellh/mapstructure"
"github.com/savannahghi/clinical/pkg/clinical/domain"
"github.com/savannahghi/serverutils"
)

Expand Down Expand Up @@ -82,7 +84,7 @@ func (s Service) MakeRequest(method string, path string, params url.Values, body
// e.g GET /orgs/WHO/sources/ICD-10-2010/concepts/A15.1/?includeInverseMappings=true
func (s Service) GetConcept(
_ context.Context, org string, source string, concept string,
includeMappings bool, includeInverseMappings bool) (map[string]interface{}, error) {
includeMappings bool, includeInverseMappings bool) (*domain.Concept, error) {
s.enforcePreconditions()

path := fmt.Sprintf("orgs/%s/sources/%s/concepts/%s", org, source, concept)
Expand Down Expand Up @@ -117,7 +119,14 @@ func (s Service) GetConcept(
return nil, fmt.Errorf("failed to get %v concept with id %v", source, concept)
}

return output, nil
var terminologyConcept *domain.Concept

err = mapstructure.Decode(output, &terminologyConcept)
if err != nil {
return nil, err
}

return terminologyConcept, nil
}

// ListConcepts searches for matching concepts on OpenConceptLab
Expand All @@ -127,7 +136,7 @@ func (s Service) ListConcepts(
_ context.Context, org string, source string, verbose bool, q *string,
sortAsc *string, sortDesc *string, conceptClass *string, dataType *string,
locale *string, includeRetired *bool,
includeMappings *bool, includeInverseMappings *bool) ([]map[string]interface{}, error) {
includeMappings *bool, includeInverseMappings *bool) ([]*domain.Concept, error) {
s.enforcePreconditions()

path := fmt.Sprintf("orgs/%s/sources/%s/concepts", org, source)
Expand Down Expand Up @@ -182,18 +191,31 @@ func (s Service) ListConcepts(

defer resp.Body.Close()

output := []map[string]interface{}{}
terminologyConcepts := []map[string]interface{}{}

data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("unable to read OCL API response body: %w", err)
}

err = json.Unmarshal(data, &output)
err = json.Unmarshal(data, &terminologyConcepts)
if err != nil {
return nil, fmt.Errorf(
"unable to marshal OCL get concept response %s to JSON: %w", string(data), err)
}

return output, nil
var concepts []*domain.Concept

for _, terminologyConcept := range terminologyConcepts {
var concept *domain.Concept

err := mapstructure.Decode(terminologyConcept, &concept)
if err != nil {
return nil, err
}

concepts = append(concepts, concept)
}

return concepts, nil
}
3 changes: 3 additions & 0 deletions pkg/clinical/presentation/graph/clinical.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ extend type Query {
getPatientPulseRateEntries(patientID: String!): [Observation!]
getPatientBMIEntries(patientID: String!): [Observation!]
getPatientWeightEntries(patientID: String!): [Observation!]

# Allergy
searchAllergyTerminology(name: String!): [Terminology]
}

extend type Mutation {
Expand Down
17 changes: 7 additions & 10 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.

Loading

0 comments on commit bd543e8

Please sign in to comment.