Skip to content

Commit

Permalink
feat: get all resources recorded within an encounter
Browse files Browse the repository at this point in the history
  • Loading branch information
Salaton authored and allansifuna committed Feb 20, 2024
1 parent 8cdca53 commit 60f4eb6
Show file tree
Hide file tree
Showing 16 changed files with 2,309 additions and 424 deletions.
15 changes: 15 additions & 0 deletions pkg/clinical/application/dto/consent_output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package dto

// Consent models a fhir consent resource.
type Consent struct {
ID *string `json:"id,omitempty"`
Status *ConsentStatusEnum `json:"status"`
Provision *ConsentProvision `json:"provision,omitempty"`
Patient *Reference `json:"patient,omitempty"`
}

// ConsentProvision models a consent provision
type ConsentProvision struct {
ID *string `json:"id,omitempty"`
Type *ConsentProvisionTypeEnum `json:"type,omitempty"`
}
23 changes: 17 additions & 6 deletions pkg/clinical/application/dto/encounter_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package dto

// Encounter definition: an interaction between a patient and healthcare provider(s) for the purpose of providing healthcare service(s) or assessing the health status of a patient.
type Encounter struct {
ID string `json:"id,omitempty"`
Status EncounterStatusEnum `json:"status,omitempty"`
Class EncounterClass `json:"class,omitempty"`
PatientID string `json:"patientID,omitempty"`
EpisodeOfCareID string `json:"episodeOfCareID,omitempty"`
ID *string `json:"id,omitempty" mapstructure:"id"`
Status *EncounterStatusEnum `json:"status,omitempty"`
Class *EncounterClass `json:"class,omitempty"`
PatientID *string `json:"patientID,omitempty"`
EpisodeOfCareID *string `json:"episodeOfCareID,omitempty"`
}

type EncounterClass struct {
Code *string `json:"code,omitempty"`
Display *EncounterClassEnum `json:"display,omitempty"`
}

// EncounterConnection is the encounter connection type
Expand All @@ -33,11 +38,17 @@ func CreateEncounterConnection(encounters []*Encounter, pageInfo PageInfo, total
for _, encounter := range encounters {
edge := EncounterEdge{
Node: *encounter,
Cursor: encounter.ID,
Cursor: *encounter.ID,
}

connection.Edges = append(connection.Edges, edge)
}

return connection
}

// EncounterAssociatedResources models resources associated with an encounter
type EncounterAssociatedResources struct {
RiskAssessment *RiskAssessment `json:"riskAssesment"`
Consent *Consent `json:"consent"`
}
78 changes: 76 additions & 2 deletions pkg/clinical/application/dto/enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ const (
EncounterStatusEnumCancelled EncounterStatusEnum = "CANCELLED"
)

type EncounterClass string
// EncounterClassEnum ...
type EncounterClassEnum string

const (
// Also referred to as outpatient - For now we'll start with outpatient only
EncounterClassAmbulatory EncounterClass = "AMBULATORY"
EncounterClassEnumAmbulatory EncounterClassEnum = "AMBULATORY"
)

type ResourceType string
Expand Down Expand Up @@ -400,3 +401,76 @@ func (c *VIAOutcomeEnum) UnmarshalGQL(v interface{}) error {

return nil
}

// ObservationStatusEnum is a FHIR enum
type ObservationStatusEnum string

const (
// ObservationStatusEnumRegistered ...
ObservationStatusEnumRegistered ObservationStatusEnum = "registered"
// ObservationStatusEnumPreliminary ...
ObservationStatusEnumPreliminary ObservationStatusEnum = "preliminary"
// ObservationStatusEnumFinal ...
ObservationStatusEnumFinal ObservationStatusEnum = "final"
// ObservationStatusEnumAmended ...
ObservationStatusEnumAmended ObservationStatusEnum = "amended"
// ObservationStatusEnumCorrected ...
ObservationStatusEnumCorrected ObservationStatusEnum = "corrected"
// ObservationStatusEnumCancelled ...
ObservationStatusEnumCancelled ObservationStatusEnum = "cancelled"
// ObservationStatusEnumEnteredInError ...
ObservationStatusEnumEnteredInError ObservationStatusEnum = "entered_in_error"
// ObservationStatusEnumUnknown ...
ObservationStatusEnumUnknown ObservationStatusEnum = "unknown"
)

// AllObservationStatusEnum ...
var AllObservationStatusEnum = []ObservationStatusEnum{
ObservationStatusEnumRegistered,
ObservationStatusEnumPreliminary,
ObservationStatusEnumFinal,
ObservationStatusEnumAmended,
ObservationStatusEnumCorrected,
ObservationStatusEnumCancelled,
ObservationStatusEnumEnteredInError,
ObservationStatusEnumUnknown,
}

// IsValid ...
func (e ObservationStatusEnum) IsValid() bool {
switch e {
case ObservationStatusEnumRegistered, ObservationStatusEnumPreliminary, ObservationStatusEnumFinal, ObservationStatusEnumAmended, ObservationStatusEnumCorrected, ObservationStatusEnumCancelled, ObservationStatusEnumEnteredInError, ObservationStatusEnumUnknown:
return true
}

return false
}

// String ...
func (e ObservationStatusEnum) String() string {
if e == ObservationStatusEnumEnteredInError {
return "entered-in-error"
}

return string(e)
}

// UnmarshalGQL ...
func (e *ObservationStatusEnum) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}

*e = ObservationStatusEnum(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid ObservationStatusEnum", str)
}

return nil
}

// MarshalGQL writes the observation status to the supplied writer as a quoted string
func (e ObservationStatusEnum) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}
17 changes: 17 additions & 0 deletions pkg/clinical/application/dto/risk_assessment_output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package dto

// RiskAssessment ...
type RiskAssessment struct {
ID *string `json:"id,omitempty" mapstructure:"id"`
Subject Reference `json:"subject,omitempty"`
Encounter *Reference `json:"encounter,omitempty"`
Prediction []RiskAssessmentPrediction `json:"prediction,omitempty"`
Note []Annotation `json:"note,omitempty"`
}

// RiskAssessmentPrediction describes the predicted outcome
type RiskAssessmentPrediction struct {
ID *string `json:"id,omitempty"`
Outcome *CodeableConcept `json:"outcome,omitempty"`
ProbabilityDecimal *float64 `json:"probabilityDecimal,omitempty"`
}
19 changes: 19 additions & 0 deletions pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir.go
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,25 @@ func (fh StoreImpl) SearchFHIREncounter(_ context.Context, params map[string]int
return &encounterOutput, nil
}

// SearchFHIREncounterAllData provides a search API for a FHIREncounter and all other resources that reference the encounter
func (fh StoreImpl) SearchFHIREncounterAllData(_ context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.PagedFHIRResource, error) {
resources, err := fh.Dataset.SearchFHIRResource(encounterResourceType, params, tenant, pagination)
if err != nil {
return nil, err
}

encounterAllDataOutput := domain.PagedFHIRResource{
Resources: resources.Resources,
HasNextPage: resources.HasNextPage,
NextCursor: resources.NextCursor,
HasPreviousPage: resources.HasPreviousPage,
PreviousCursor: resources.PreviousCursor,
TotalCount: resources.TotalCount,
}

return &encounterAllDataOutput, nil
}

// SearchFHIRMedicationRequest provides a search API for FHIRMedicationRequest
func (fh StoreImpl) SearchFHIRMedicationRequest(_ context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.FHIRMedicationRequestRelayConnection, error) {
output := domain.FHIRMedicationRequestRelayConnection{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,16 @@ func (fr Repository) SearchFHIRResource(resourceType string, params map[string]i
urlParams := url.Values{}

for k, v := range params {
val, ok := v.(string)
if !ok {
switch value := v.(type) {
case string:
urlParams.Add(k, value)
case []string:
for _, i := range value {
urlParams.Add(k, i)
}
default:
return nil, fmt.Errorf("the search/filter param: %s should all be sent as strings", k)
}

urlParams.Add(k, val)
}

urlParams.Add("_tag", fmt.Sprintf("http://mycarehub/tenant-identification/organisation|%s", tenant.OrganizationID))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type FHIRMock struct {
MockSearchFHIRRiskAssessmentFn func(ctx context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.FHIRRiskAssessmentRelayConnection, error)
MockGetFHIRQuestionnaireResponseFn func(ctx context.Context, id string) (*domain.FHIRQuestionnaireResponseRelayPayload, error)
MockCreateFHIRDiagnosticReportFn func(_ context.Context, input *domain.FHIRDiagnosticReportInput) (*domain.FHIRDiagnosticReport, error)
MockSearchFHIREncounterAllDataFn func(_ context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.PagedFHIRResource, error)
}

// NewFHIRMock initializes a new instance of FHIR mock
Expand Down Expand Up @@ -2060,6 +2061,9 @@ func NewFHIRMock() *FHIRMock {
PresentedForm: []*domain.FHIRAttachment{},
}, nil
},
MockSearchFHIREncounterAllDataFn: func(_ context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.PagedFHIRResource, error) {
return &domain.PagedFHIRResource{}, nil
},
}
}

Expand Down Expand Up @@ -2407,3 +2411,8 @@ func (fh *FHIRMock) GetFHIRQuestionnaireResponse(ctx context.Context, id string)
func (fh *FHIRMock) CreateFHIRDiagnosticReport(ctx context.Context, input *domain.FHIRDiagnosticReportInput) (*domain.FHIRDiagnosticReport, error) {
return fh.MockCreateFHIRDiagnosticReportFn(ctx, input)
}

// SearchFHIREncounterAllData mocks the implementation of SearchFHIREncounterAllData
func (fh *FHIRMock) SearchFHIREncounterAllData(ctx context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.PagedFHIRResource, error) {
return fh.MockSearchFHIREncounterAllDataFn(ctx, params, tenant, pagination)
}
2 changes: 2 additions & 0 deletions pkg/clinical/presentation/graph/clinical.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,6 @@ extend type Mutation {
recordMammographyResult(input: DiagnosticReportInput!): DiagnosticReport!
recordBiopsy(input: DiagnosticReportInput!): DiagnosticReport!
recordMRI(input: DiagnosticReportInput!): DiagnosticReport!

getEncounterAssociatedResources(encounterID: String!): EncounterAssociatedResources!
}
5 changes: 5 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.

2 changes: 1 addition & 1 deletion pkg/clinical/presentation/graph/enums.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ enum EncounterStatusEnum {
CANCELLED
}

enum EncounterClass {
enum EncounterClassEnum {
AMBULATORY
}

Expand Down

0 comments on commit 60f4eb6

Please sign in to comment.