diff --git a/pkg/clinical/domain/complex_types.go b/pkg/clinical/domain/complex_types.go index a8bbf40..f40bb9b 100644 --- a/pkg/clinical/domain/complex_types.go +++ b/pkg/clinical/domain/complex_types.go @@ -3229,3 +3229,14 @@ const ( ServiceRequestPriorityAsap ServiceRequestPriorityEnum = "asap" ServiceRequestPriorityStat ServiceRequestPriorityEnum = "stat" ) + +// SubscriptionType defines the types of methods used to execute a subscription +type SubscriptionTypeEnum string + +const ( + SubscriptionTypeRestHook SubscriptionTypeEnum = "rest-hook" + SubscriptionTypeWebSocket SubscriptionTypeEnum = "websocket" + SubscriptionTypeEmail SubscriptionTypeEnum = "email" + SubscriptionTypeSMS SubscriptionTypeEnum = "sms" + SubscriptionTypeMessage SubscriptionTypeEnum = "message" +) diff --git a/pkg/clinical/domain/subscription.go b/pkg/clinical/domain/subscription.go new file mode 100644 index 0000000..e9172b1 --- /dev/null +++ b/pkg/clinical/domain/subscription.go @@ -0,0 +1,58 @@ +package domain + +type FHIRSubscriptionInput struct { + ID *string `json:"id,omitempty"` + Meta *FHIRMetaInput `json:"meta,omitempty"` + Extension []Extension `json:"extension,omitempty"` + Status SubscriptionTypeEnum `json:"status"` + Contact []FHIRContactPointInput `json:"contact,omitempty"` + End *string `json:"end,omitempty"` + Reason string `json:"reason"` + Criteria string `json:"criteria"` + Error *string `json:"error,omitempty"` + Channel FHIRSubscriptionChannel `json:"channel"` +} + +// FHIRSubscriptionChannel the channel on which to report matches to the criteria +type FHIRSubscriptionChannelInput struct { + ID *string `json:"id,omitempty"` + Type *string `json:"type"` + Endpoint *string `json:"endpoint,omitempty"` + Payload *string `json:"payload,omitempty"` + Header []string `json:"header,omitempty"` +} + +// FHIRSubscription models a subscription output +type FHIRSubscription struct { + ID *string `json:"id,omitempty"` + Meta *FHIRMeta `json:"meta,omitempty"` + ImplicitRules *string `json:"implicitRules,omitempty"` + Language *string `json:"language,omitempty"` + Text *FHIRNarrative `json:"text,omitempty"` + Extension []*Extension `json:"extension,omitempty"` + ModifierExtension []*Extension `json:"modifierExtension,omitempty"` + Identifier []*FHIRIdentifier `json:"identifier,omitempty"` + Status SubscriptionTypeEnum `json:"status"` + Contact []FHIRContactPoint `json:"contact,omitempty"` + End *string `json:"end,omitempty"` + Reason string `json:"reason"` + Criteria string `json:"criteria"` + Error *string `json:"error,omitempty"` + Channel FHIRSubscriptionChannel `json:"channel"` +} + +// FHIRSubscriptionChannel ... +type FHIRSubscriptionChannel struct { + ID *string `json:"id,omitempty"` + Meta *FHIRMeta `json:"meta,omitempty"` + ImplicitRules *string `json:"implicitRules,omitempty"` + Language *string `json:"language,omitempty"` + Text *FHIRNarrative `json:"text,omitempty"` + Extension []*Extension `json:"extension,omitempty"` + ModifierExtension []*Extension `json:"modifierExtension,omitempty"` + Identifier []*FHIRIdentifier `json:"identifier,omitempty"` + Type *string `json:"type"` + Endpoint *string `json:"endpoint,omitempty"` + Payload *string `json:"payload,omitempty"` + Header []string `json:"header,omitempty"` +} diff --git a/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir.go b/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir.go index 69f40ff..90d3ab0 100644 --- a/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir.go +++ b/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir.go @@ -41,6 +41,7 @@ const ( questionnaireResponseResourceType = "QuestionnaireResponse" riskAssessmentResourceType = "RiskAssessment" diagnosticReportResourceType = "DiagnosticReport" + subscriptionResourceType = "Subscription" ) // Dataset ... @@ -2050,3 +2051,21 @@ func (fh StoreImpl) GetFHIRServiceRequest(_ context.Context, id string) (*domain return payload, nil } + +// CreateFHIRSubscription is responsible for creating a subscription resource in FHIR repository +func (fh StoreImpl) CreateFHIRSubscription(_ context.Context, subscription *domain.FHIRSubscriptionInput) (*domain.FHIRSubscription, error) { + payload, err := converterandformatter.StructToMap(subscription) + if err != nil { + return nil, fmt.Errorf("unable to convert subscription input into a map: %w", err) + } + + fhirSubscription := &domain.FHIRSubscription{} + + err = fh.Dataset.CreateFHIRResource(subscriptionResourceType, payload, fhirSubscription) + if err != nil { + return nil, fmt.Errorf( + "unable to create episode of care resource: %w", err) + } + + return fhirSubscription, nil +} diff --git a/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir_unit_test.go b/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir_unit_test.go index 72fd38e..c71f29e 100644 --- a/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir_unit_test.go +++ b/pkg/clinical/infrastructure/datastore/cloudhealthcare/fhir_unit_test.go @@ -5205,3 +5205,55 @@ func TestStoreImpl_GetFHIRPatientEverything(t *testing.T) { }) } } + +func TestStoreImpl_CreateFHIRSubscription(t *testing.T) { + id := gofakeit.UUID() + type args struct { + ctx context.Context + subscription *domain.FHIRSubscriptionInput + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Happy case: create subscription", + args: args{ + ctx: context.Background(), + subscription: &domain.FHIRSubscriptionInput{ + ID: &id, + }, + }, + wantErr: false, + }, + { + name: "Sad case: unable to create subscription", + args: args{ + ctx: context.Background(), + subscription: &domain.FHIRSubscriptionInput{ + ID: &id, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dataset := fakeDataset.NewFakeFHIRRepositoryMock() + fh := FHIR.NewFHIRStoreImpl(dataset) + + if tt.name == "Sad case: unable to create subscription" { + dataset.MockCreateFHIRResourceFn = func(resourceType string, payload map[string]interface{}, resource interface{}) error { + return fmt.Errorf("an error occurred") + } + } + + _, err := fh.CreateFHIRSubscription(tt.args.ctx, tt.args.subscription) + if (err != nil) != tt.wantErr { + t.Errorf("StoreImpl.CreateFHIRSubscription() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} diff --git a/pkg/clinical/infrastructure/datastore/cloudhealthcare/mock/fhir_mock.go b/pkg/clinical/infrastructure/datastore/cloudhealthcare/mock/fhir_mock.go index 199416a..9caa7e4 100644 --- a/pkg/clinical/infrastructure/datastore/cloudhealthcare/mock/fhir_mock.go +++ b/pkg/clinical/infrastructure/datastore/cloudhealthcare/mock/fhir_mock.go @@ -93,6 +93,7 @@ type FHIRMock struct { MockSearchFHIREncounterAllDataFn func(_ context.Context, params map[string]interface{}, tenant dto.TenantIdentifiers, pagination dto.Pagination) (*domain.PagedFHIRResource, error) MockGetFHIRPatientEverythingFn func(ctx context.Context, id string, params map[string]interface{}) (*domain.PagedFHIRResource, error) MockGetFHIRServiceRequestFn func(_ context.Context, id string) (*domain.FHIRServiceRequestRelayPayload, error) + MockCreateFHIRSubscriptionFn func(_ context.Context, subscription *domain.FHIRSubscriptionInput) (*domain.FHIRSubscription, error) } // NewFHIRMock initializes a new instance of FHIR mock @@ -2197,6 +2198,26 @@ func NewFHIRMock() *FHIRMock { }, }, nil }, + MockCreateFHIRSubscriptionFn: func(_ context.Context, subscription *domain.FHIRSubscriptionInput) (*domain.FHIRSubscription, error) { + resourceID := uuid.New().String() + return &domain.FHIRSubscription{ + ID: &resourceID, + Meta: &domain.FHIRMeta{}, + ImplicitRules: new(string), + Language: new(string), + Text: &domain.FHIRNarrative{}, + Extension: []*domain.Extension{}, + ModifierExtension: []*domain.Extension{}, + Identifier: []*domain.FHIRIdentifier{}, + Status: "", + Contact: []domain.FHIRContactPoint{}, + End: new(string), + Reason: "", + Criteria: "", + Error: new(string), + Channel: domain.FHIRSubscriptionChannel{}, + }, nil + }, } } @@ -2559,3 +2580,8 @@ func (fh *FHIRMock) GetFHIRPatientEverything(ctx context.Context, id string, par func (fh *FHIRMock) GetFHIRServiceRequest(ctx context.Context, id string) (*domain.FHIRServiceRequestRelayPayload, error) { return fh.MockGetFHIRServiceRequestFn(ctx, id) } + +// CreateFHIRSubscription mocks the implementation of creating a subscription +func (fh *FHIRMock) CreateFHIRSubscription(ctx context.Context, subscription *domain.FHIRSubscriptionInput) (*domain.FHIRSubscription, error) { + return fh.MockCreateFHIRSubscriptionFn(ctx, subscription) +} diff --git a/pkg/clinical/repository/repository.go b/pkg/clinical/repository/repository.go index 6b7fa63..778d963 100644 --- a/pkg/clinical/repository/repository.go +++ b/pkg/clinical/repository/repository.go @@ -27,6 +27,7 @@ type FHIR interface { FHIRQuestionnaireResponse FHIRRiskAssessment FHIRDiagnosticReport + FHIRSubscription } type FHIROrganization interface { @@ -142,3 +143,8 @@ type FHIRRiskAssessment interface { type FHIRDiagnosticReport interface { CreateFHIRDiagnosticReport(_ context.Context, input *domain.FHIRDiagnosticReportInput) (*domain.FHIRDiagnosticReport, error) } + +// FHIRSubscription contains method signatures of the FHIRSubscription interface +type FHIRSubscription interface { + CreateFHIRSubscription(_ context.Context, input *domain.FHIRSubscriptionInput) (*domain.FHIRSubscription, error) +}