From 790e2beeb627ace333182c148d649e3530214fea Mon Sep 17 00:00:00 2001 From: Salaton Date: Mon, 8 Apr 2024 14:40:46 +0300 Subject: [PATCH] chore: add fhir document reference resource model (#419) --- pkg/clinical/domain/complex_types.go | 64 ++++++++++ pkg/clinical/domain/complex_types_test.go | 144 ++++++++++++++++++++++ pkg/clinical/domain/document_reference.go | 90 ++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 pkg/clinical/domain/document_reference.go diff --git a/pkg/clinical/domain/complex_types.go b/pkg/clinical/domain/complex_types.go index f40bb9b6..f2ed2356 100644 --- a/pkg/clinical/domain/complex_types.go +++ b/pkg/clinical/domain/complex_types.go @@ -3240,3 +3240,67 @@ const ( SubscriptionTypeSMS SubscriptionTypeEnum = "sms" SubscriptionTypeMessage SubscriptionTypeEnum = "message" ) + +// DocumentReferenceStatusEnum is a FHIR enum for document reference statuses +type DocumentReferenceStatusEnum string + +const ( + DocumentReferenceStatusEnumCurrent DocumentReferenceStatusEnum = "current" + DocumentReferenceStatusEnumSuperseded DocumentReferenceStatusEnum = "superseded" + DocumentReferenceStatusEnumEnteredInError DocumentReferenceStatusEnum = "entered-in-error" +) + +// AllDocumentReferenceStatusEnum lists all document reference statuses +var AllDocumentReferenceStatusEnum = []DocumentReferenceStatusEnum{ + DocumentReferenceStatusEnumCurrent, + DocumentReferenceStatusEnumSuperseded, + DocumentReferenceStatusEnumEnteredInError, +} + +// IsValid checks if the enum value is valid +func (e DocumentReferenceStatusEnum) IsValid() bool { + switch e { + case DocumentReferenceStatusEnumCurrent, DocumentReferenceStatusEnumSuperseded, DocumentReferenceStatusEnumEnteredInError: + return true + } + + return false +} + +// String converts the enum to its string representation +func (e DocumentReferenceStatusEnum) String() string { + return string(e) +} + +// DocumentRelationshipTypeEnum is a FHIR enum for document relationship types +type DocumentRelationshipTypeEnum string + +const ( + DocumentRelationshipTypeEnumReplaces DocumentRelationshipTypeEnum = "replaces" + DocumentRelationshipTypeEnumTransforms DocumentRelationshipTypeEnum = "transforms" + DocumentRelationshipTypeEnumSigns DocumentRelationshipTypeEnum = "signs" + DocumentRelationshipTypeEnumAppends DocumentRelationshipTypeEnum = "appends" +) + +// AllDocumentRelationshipTypeEnum lists all document relationship types +var AllDocumentRelationshipTypeEnum = []DocumentRelationshipTypeEnum{ + DocumentRelationshipTypeEnumReplaces, + DocumentRelationshipTypeEnumTransforms, + DocumentRelationshipTypeEnumSigns, + DocumentRelationshipTypeEnumAppends, +} + +// IsValid checks if the enum value is valid +func (e DocumentRelationshipTypeEnum) IsValid() bool { + switch e { + case DocumentRelationshipTypeEnumReplaces, DocumentRelationshipTypeEnumTransforms, DocumentRelationshipTypeEnumSigns, DocumentRelationshipTypeEnumAppends: + return true + } + + return false +} + +// String converts the enum to its string representation +func (e DocumentRelationshipTypeEnum) String() string { + return string(e) +} diff --git a/pkg/clinical/domain/complex_types_test.go b/pkg/clinical/domain/complex_types_test.go index 389c25cf..0d5d6e50 100644 --- a/pkg/clinical/domain/complex_types_test.go +++ b/pkg/clinical/domain/complex_types_test.go @@ -4517,3 +4517,147 @@ func TestConsentState_MarshalGQL(t *testing.T) { }) } } + +func TestDocumentReferenceStatusEnum_IsValid(t *testing.T) { + tests := []struct { + name string + e DocumentReferenceStatusEnum + want bool + }{ + { + name: "valid current status", + e: DocumentReferenceStatusEnumCurrent, + want: true, + }, + { + name: "valid superseded status", + e: DocumentReferenceStatusEnumSuperseded, + want: true, + }, + { + name: "valid entered-in-error status", + e: DocumentReferenceStatusEnumEnteredInError, + want: true, + }, + { + name: "invalid status", + e: DocumentReferenceStatusEnum("unknown"), + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.e.IsValid(); got != tt.want { + t.Errorf("DocumentReferenceStatusEnum.IsValid() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDocumentReferenceStatusEnum_String(t *testing.T) { + tests := []struct { + name string + e DocumentReferenceStatusEnum + want string + }{ + { + name: "current status", + e: DocumentReferenceStatusEnumCurrent, + want: "current", + }, + { + name: "superseded status", + e: DocumentReferenceStatusEnumSuperseded, + want: "superseded", + }, + { + name: "entered-in-error status", + e: DocumentReferenceStatusEnumEnteredInError, + want: "entered-in-error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.e.String(); got != tt.want { + t.Errorf("DocumentReferenceStatusEnum.String() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDocumentRelationshipTypeEnum_IsValid(t *testing.T) { + tests := []struct { + name string + e DocumentRelationshipTypeEnum + want bool + }{ + { + name: "valid replaces relationship", + e: DocumentRelationshipTypeEnumReplaces, + want: true, + }, + { + name: "valid transforms relationship", + e: DocumentRelationshipTypeEnumTransforms, + want: true, + }, + { + name: "valid signs relationship", + e: DocumentRelationshipTypeEnumSigns, + want: true, + }, + { + name: "valid appends relationship", + e: DocumentRelationshipTypeEnumAppends, + want: true, + }, + { + name: "invalid relationship", + e: DocumentRelationshipTypeEnum("unknown"), + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.e.IsValid(); got != tt.want { + t.Errorf("DocumentRelationshipTypeEnum.IsValid() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestDocumentRelationshipTypeEnum_String(t *testing.T) { + tests := []struct { + name string + e DocumentRelationshipTypeEnum + want string + }{ + { + name: "replaces relationship", + e: DocumentRelationshipTypeEnumReplaces, + want: "replaces", + }, + { + name: "transforms relationship", + e: DocumentRelationshipTypeEnumTransforms, + want: "transforms", + }, + { + name: "signs relationship", + e: DocumentRelationshipTypeEnumSigns, + want: "signs", + }, + { + name: "appends relationship", + e: DocumentRelationshipTypeEnumAppends, + want: "appends", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.e.String(); got != tt.want { + t.Errorf("DocumentRelationshipTypeEnum.String() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/clinical/domain/document_reference.go b/pkg/clinical/domain/document_reference.go new file mode 100644 index 00000000..dea7dbb0 --- /dev/null +++ b/pkg/clinical/domain/document_reference.go @@ -0,0 +1,90 @@ +package domain + +// FHIRDocumentReference represents a reference to a document of any kind for any purpose. +// It provides metadata about the document so that the document can be discovered and managed. +// The scope of a document is any seralized object with a mime-type, so includes formal patient centric documents (CDA), cliical notes, scanned paper, and non-patient centric documents like policy text. +type FHIRDocumentReference 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 []FHIRExtension `json:"extension,omitempty"` + ModifierExtension []FHIRExtension `json:"modifierExtension,omitempty"` + MasterIdentifier *FHIRIdentifier `json:"masterIdentifier,omitempty"` + Identifier []FHIRIdentifier `json:"identifier,omitempty"` + Status DocumentReferenceStatusEnum `json:"status,omitempty"` + DocStatus *CompositionStatusEnum `json:"docStatus,omitempty"` + Type *FHIRCodeableConcept `json:"type,omitempty"` + Category []FHIRCodeableConcept `json:"category,omitempty"` + Subject *FHIRReference `json:"subject,omitempty"` + Date *string `json:"date,omitempty"` + Author []FHIRReference `json:"author,omitempty"` + Authenticator *FHIRReference `json:"authenticator,omitempty"` + Custodian *FHIRReference `json:"custodian,omitempty"` + RelatesTo []FHIRDocumentReferenceRelatesTo `json:"relatesTo,omitempty"` + Description string `json:"description,omitempty"` + SecurityLabel []FHIRCodeableConcept `json:"securityLabel,omitempty"` + Content []FHIRDocumentReferenceContent `json:"content,omitempty"` + Context *FHIRDocumentReferenceContext `json:"context,omitempty"` +} + +// FHIRDocumentReferenceRelatesTo specifies how this document reference is related to other resources, +// such as being a replacement for, transformation of, or addition to another document reference. +type FHIRDocumentReferenceRelatesTo struct { + ID string `json:"id,omitempty"` + Extension []Extension `json:"extension,omitempty"` + ModifierExtension []Extension `json:"modifierExtension,omitempty"` + Code DocumentRelationshipTypeEnum `json:"code"` + Target Reference `json:"target"` +} + +// FHIRDocumentReferenceContent describes the content of the document, including the document itself as an attachment, and potentially its format. +type FHIRDocumentReferenceContent struct { + ID string `json:"id,omitempty"` + Extension []Extension `json:"extension,omitempty"` + ModifierExtension []Extension `json:"modifierExtension,omitempty"` + Attachment FHIRAttachment `json:"attachment"` + Format *FHIRCoding `json:"format,omitempty"` +} + +// FHIRDocumentReferenceContext provides the clinical context in which the document was created, such as encounter, period, practice setting. +type FHIRDocumentReferenceContext struct { + ID string `json:"id,omitempty"` + Extension []Extension `json:"extension,omitempty"` + ModifierExtension []Extension `json:"modifierExtension,omitempty"` + Encounter []Reference `json:"encounter,omitempty"` + Event []FHIRCodeableConcept `json:"event,omitempty"` + Period *FHIRPeriod `json:"period,omitempty"` + FacilityType *FHIRCodeableConcept `json:"facilityType,omitempty"` + PracticeSetting *FHIRCodeableConcept `json:"practiceSetting,omitempty"` + SourcePatientInfo *Reference `json:"sourcePatientInfo,omitempty"` + Related []Reference `json:"related,omitempty"` +} + +// FHIRDocumentReferenceInput is the input type for FHIRDocumentReference +type FHIRDocumentReferenceInput struct { + ID string `json:"id,omitempty"` + Meta *FHIRMetaInput `json:"meta,omitempty"` + ImplicitRules *string `json:"implicitRules,omitempty"` + Language *string `json:"language,omitempty"` + Text *FHIRNarrativeInput `json:"text,omitempty"` + Extension []FHIRExtension `json:"extension,omitempty"` + ModifierExtension []FHIRExtension `json:"modifierExtension,omitempty"` + MasterIdentifier *FHIRIdentifierInput `json:"masterIdentifier,omitempty"` + Identifier []FHIRIdentifierInput `json:"identifier,omitempty"` + Status DocumentReferenceStatusEnum `json:"status,omitempty"` + DocStatus *CompositionStatusEnum `json:"docStatus,omitempty"` + Type *FHIRCodeableConceptInput `json:"type,omitempty"` + Category []FHIRCodeableConceptInput `json:"category,omitempty"` + Subject *FHIRReferenceInput `json:"subject,omitempty"` + Date *string `json:"date,omitempty"` + Author []FHIRReferenceInput `json:"author,omitempty"` + Authenticator *FHIRReferenceInput `json:"authenticator,omitempty"` + Custodian *FHIRReferenceInput `json:"custodian,omitempty"` + RelatesTo []FHIRDocumentReferenceRelatesTo `json:"relatesTo,omitempty"` + Description string `json:"description,omitempty"` + SecurityLabel []FHIRCodeableConceptInput `json:"securityLabel,omitempty"` + Content []FHIRDocumentReferenceContent `json:"content,omitempty"` + Context *FHIRDocumentReferenceContext `json:"context,omitempty"` +}