diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml
index 0d9798cd9..5cf578d12 100644
--- a/.github/workflows/docker.yaml
+++ b/.github/workflows/docker.yaml
@@ -57,6 +57,14 @@ jobs:
type=raw,value=${{ matrix.flavor }},enable=${{ github.ref_name == 'main' }}
# if this is a (non main) branch build, tag it with the flavor and branch name (eg. main-branch and sandbox-branch)
type=ref,event=branch,prefix=${{ matrix.flavor }}-,enable=${{ github.ref_name != 'main' }}
+ labels: |
+ maintainer=AnalogJ
+ org.opencontainers.image.title=Fasten Health - ${{ matrix.flavor }}
+ org.opencontainers.image.authors=Jason Kulatunga - support@fastenhealth.com
+ org.opencontainers.image.description=An open-source personal medical record that never leaves the patients hands without their consent
+ org.opencontainers.image.vendor=Fasten Health, Inc.
+ org.opencontainers.image.source=https://github.com/fastenhealth/fasten-onprem/
+ org.opencontainers.image.revision=${{ github.sha }}
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
diff --git a/backend/pkg/constants.go b/backend/pkg/constants.go
index 8062ffe07..e09ca457a 100644
--- a/backend/pkg/constants.go
+++ b/backend/pkg/constants.go
@@ -10,6 +10,9 @@ type DatabaseRepositoryType string
type InstallationVerificationStatus string
type InstallationQuotaStatus string
+type IPSSections string
+type IPSSectionGroups string
+
const (
ResourceListPageSize int = 20
@@ -50,4 +53,63 @@ const (
InstallationVerificationStatusVerified InstallationVerificationStatus = "VERIFIED" //email has been verified
InstallationQuotaStatusActive InstallationQuotaStatus = "ACTIVE"
InstallationQuotaStatusConsumed InstallationQuotaStatus = "CONSUMED"
+
+ IPSSectionsMedicationSummary IPSSections = "medication_summary"
+ IPSSectionsAllergiesIntolerances IPSSections = "allergies_intolerances"
+ IPSSectionsProblemList IPSSections = "problem_list"
+ IPSSectionsImmunizations IPSSections = "immunizations"
+ IPSSectionsHistoryOfProcedures IPSSections = "history_of_procedures"
+ IPSSectionsMedicalDevices IPSSections = "medical_devices"
+ IPSSectionsDiagnosticResults IPSSections = "diagnostic_results"
+ IPSSectionsVitalSigns IPSSections = "vital_signs"
+ IPSSectionsHistoryOfIllness IPSSections = "history_of_illness"
+ IPSSectionsPregnancy IPSSections = "pregnancy"
+ IPSSectionsSocialHistory IPSSections = "social_history"
+ IPSSectionsPlanOfCare IPSSections = "plan_of_care"
+ IPSSectionsFunctionalStatus IPSSections = "functional_status"
+ IPSSectionsAdvanceDirectives IPSSections = "advance_directives"
+
+ IPSSectionGroupsRequired IPSSectionGroups = "required"
+ IPSSectionGroupsRecommended IPSSectionGroups = "recommended"
+ IPSSectionGroupsOptional IPSSectionGroups = "optional"
)
+
+var IPSSectionsList = []IPSSections{
+ IPSSectionsMedicationSummary,
+ IPSSectionsAllergiesIntolerances,
+ IPSSectionsProblemList,
+ IPSSectionsImmunizations,
+ IPSSectionsHistoryOfProcedures,
+ IPSSectionsMedicalDevices,
+ IPSSectionsDiagnosticResults,
+ IPSSectionsVitalSigns,
+ IPSSectionsHistoryOfIllness,
+ IPSSectionsPregnancy,
+ IPSSectionsSocialHistory,
+ IPSSectionsPlanOfCare,
+ IPSSectionsFunctionalStatus,
+ IPSSectionsAdvanceDirectives,
+}
+
+var IPSSectionGroupsOrdered = map[IPSSectionGroups][]IPSSections{
+ IPSSectionGroupsRequired: []IPSSections{
+ IPSSectionsMedicationSummary,
+ IPSSectionsAllergiesIntolerances,
+ IPSSectionsProblemList,
+ },
+ IPSSectionGroupsRecommended: []IPSSections{
+ IPSSectionsImmunizations,
+ IPSSectionsHistoryOfProcedures,
+ IPSSectionsMedicalDevices,
+ IPSSectionsDiagnosticResults,
+ },
+ IPSSectionGroupsOptional: []IPSSections{
+ IPSSectionsVitalSigns,
+ IPSSectionsHistoryOfIllness,
+ IPSSectionsPregnancy,
+ IPSSectionsSocialHistory,
+ IPSSectionsPlanOfCare,
+ IPSSectionsFunctionalStatus,
+ IPSSectionsAdvanceDirectives,
+ },
+}
diff --git a/backend/pkg/database/gorm_repository_query.go b/backend/pkg/database/gorm_repository_query.go
index 66195976a..4a29090b8 100644
--- a/backend/pkg/database/gorm_repository_query.go
+++ b/backend/pkg/database/gorm_repository_query.go
@@ -41,6 +41,10 @@ const TABLE_ALIAS = "fhir"
// Can generate simple or complex queries, depending on the SearchParameter type:
//
// eg. Simple
+// SELECT fhir.*
+// FROM fhir_observation as fhir, json_each(fhir.code) as codeJson
+//
+// result = inteface{} ([]database.IFhirResource)
//
// eg. Complex
// SELECT fhir.*
@@ -54,6 +58,8 @@ const TABLE_ALIAS = "fhir"
// )
// AND (user_id = "6efcd7c5-3f29-4f0d-926d-a66ff68bbfc2")
// GROUP BY `fhir`.`id`
+//
+// results = []map[string]any{}
func (gr *GormRepository) QueryResources(ctx context.Context, query models.QueryResource) (interface{}, error) {
sqlQuery, err := gr.sqlQueryResources(ctx, query)
@@ -62,14 +68,20 @@ func (gr *GormRepository) QueryResources(ctx context.Context, query models.Query
}
if query.Aggregations != nil && (query.Aggregations.GroupBy != nil || query.Aggregations.CountBy != nil) {
- results := []map[string]interface{}{}
+ results := []map[string]any{}
clientResp := sqlQuery.Find(&results)
return results, clientResp.Error
} else {
- results := []models.ResourceBase{}
- clientResp := sqlQuery.Find(&results)
- return results, clientResp.Error
+
+ //find the associated Gorm Model for this query
+ queryModelSlice, err := databaseModel.NewFhirResourceModelSliceByType(query.From)
+ if err != nil {
+ return nil, err
+ }
+
+ clientResp := sqlQuery.Find(&queryModelSlice)
+ return queryModelSlice, clientResp.Error
}
}
@@ -230,6 +242,10 @@ func (gr *GormRepository) sqlQueryResources(ctx context.Context, query models.Qu
}
}
+ // Debugging
+ //log.Printf("whereClauses: %v", whereClauses)
+ //log.Printf("whereNamedParameters: %v", whereNamedParameters)
+
//ensure Where and From clauses are unique
whereClauses = lo.Uniq(whereClauses)
whereClauses = lo.Compact(whereClauses)
@@ -313,9 +329,10 @@ func ProcessSearchParameter(searchCodeWithModifier string, searchParamTypeLookup
searchParameter.Type = SearchParameterType(searchParamTypeStr)
}
- //if this is a token search parameter with a modifier, we need to throw an error
- if searchParameter.Type == SearchParameterTypeToken && len(searchParameter.Modifier) > 0 {
- return searchParameter, fmt.Errorf("token search parameter %s cannot have a modifier", searchParameter.Name)
+ //only a limited set of token modifiers are allowed. Otherwise we need to throw an error
+ allowedTokenModifiers := []string{"not"}
+ if searchParameter.Type == SearchParameterTypeToken && len(searchParameter.Modifier) > 0 && !lo.Contains(allowedTokenModifiers, searchParameter.Modifier) {
+ return searchParameter, fmt.Errorf("token search parameter %s does not support this modifier: %s", searchParameter.Name, searchParameter.Modifier)
}
return searchParameter, nil
@@ -332,8 +349,8 @@ func ProcessSearchParameter(searchCodeWithModifier string, searchParamTypeLookup
//
// For example, searchParamCodeValueOrValuesWithPrefix may be:
//
-// "code": "29463-7,3141-9,27113001"
-// "code": ["le29463-7", "gt3141-9", "27113001"]
+// "code": "29463-7,3141-9,27113001" = OR
+// "code": ["le29463-7", "gt3141-9", "27113001"] = AND
func ProcessSearchParameterValueIntoOperatorTree(searchParameter SearchParameter, searchParamCodeValueOrValuesWithPrefix interface{}) (SearchParameterValueOperatorTree, error) {
searchParamCodeValuesWithPrefix := []string{}
@@ -344,6 +361,11 @@ func ProcessSearchParameterValueIntoOperatorTree(searchParameter SearchParameter
case []string:
searchParamCodeValuesWithPrefix = v
break
+ case []interface{}:
+ for _, searchParamCodeValue := range v {
+ searchParamCodeValuesWithPrefix = append(searchParamCodeValuesWithPrefix, fmt.Sprintf("%v", searchParamCodeValue))
+ }
+ break
default:
return nil, fmt.Errorf("invalid search parameter value type %T, must be a string or a list of strings (%s=%v)", v, searchParameter.Name, searchParamCodeValueOrValuesWithPrefix)
}
@@ -456,8 +478,12 @@ func ProcessSearchParameterValue(searchParameter SearchParameter, searchValueWit
return searchParameterValue, nil
}
-func NamedParameterWithSuffix(parameterName string, suffix string) string {
- return fmt.Sprintf("%s_%s", parameterName, suffix)
+func NamedParameterWithSuffix(parameterName string, parameterModifier string, suffix string) string {
+ if len(parameterModifier) > 0 {
+ return fmt.Sprintf("%s_%s_%s", parameterName, parameterModifier, suffix)
+ } else {
+ return fmt.Sprintf("%s_%s", parameterName, suffix)
+ }
}
// SearchCodeToWhereClause converts a searchCode and searchCodeValue to a where clause and a map of named parameters
@@ -465,10 +491,10 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
//add named parameters to the lookup map. Basically, this is a map of all the named parameters that will be used in the where clause we're generating
searchClauseNamedParams := map[string]interface{}{
- NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix): searchParamValue.Value,
+ NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix): searchParamValue.Value,
}
for k, v := range searchParamValue.SecondaryValues {
- searchClauseNamedParams[NamedParameterWithSuffix(k, namedParameterSuffix)] = v
+ searchClauseNamedParams[NamedParameterWithSuffix(k, searchParam.Modifier, namedParameterSuffix)] = v
}
//parse the searchCode and searchCodeValue to determine the correct where clause
@@ -479,27 +505,27 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
case SearchParameterTypeNumber, SearchParameterTypeDate:
if searchParamValue.Prefix == "" || searchParamValue.Prefix == "eq" {
- return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParamValue.Prefix == "lt" || searchParamValue.Prefix == "eb" {
- return fmt.Sprintf("(%s < @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s < @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParamValue.Prefix == "le" {
- return fmt.Sprintf("(%s <= @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s <= @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParamValue.Prefix == "gt" || searchParamValue.Prefix == "sa" {
- return fmt.Sprintf("(%s > @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s > @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParamValue.Prefix == "ge" {
- return fmt.Sprintf("(%s >= @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s >= @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParamValue.Prefix == "ne" {
- return fmt.Sprintf("(%s <> @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s <> @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParam.Modifier == "ap" {
return "", nil, fmt.Errorf("search modifier 'ap' not supported for search parameter type %s (%s=%s)", searchParam.Type, searchParam.Name, searchParamValue.Value)
}
case SearchParameterTypeUri:
if searchParam.Modifier == "" {
- return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParam.Modifier == "below" {
- searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)] = searchParamValue.Value.(string) + "%" // column starts with "http://example.com"
- return fmt.Sprintf("(%s LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)] = searchParamValue.Value.(string) + "%" // column starts with "http://example.com"
+ return fmt.Sprintf("(%s LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParam.Modifier == "above" {
return "", nil, fmt.Errorf("search modifier 'above' not supported for search parameter type %s (%s=%s)", searchParam.Type, searchParam.Name, searchParamValue.Value)
}
@@ -508,14 +534,14 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
case SearchParameterTypeString:
if searchParam.Modifier == "" {
- searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)] = searchParamValue.Value.(string) + "%" // "eve" matches "Eve" and "Evelyn"
- return fmt.Sprintf("(%sJson.value LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)] = searchParamValue.Value.(string) + "%" // "eve" matches "Eve" and "Evelyn"
+ return fmt.Sprintf("(%sJson.value LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParam.Modifier == "exact" {
// "eve" matches "eve" (not "Eve" or "EVE")
- return fmt.Sprintf("(%sJson.value = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%sJson.value = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
} else if searchParam.Modifier == "contains" {
- searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)] = "%" + searchParamValue.Value.(string) + "%" // "eve" matches "Eve", "Evelyn" and "Severine"
- return fmt.Sprintf("(%sJson.value LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ searchClauseNamedParams[NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)] = "%" + searchParamValue.Value.(string) + "%" // "eve" matches "Eve", "Evelyn" and "Severine"
+ return fmt.Sprintf("(%sJson.value LIKE @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
}
case SearchParameterTypeQuantity:
@@ -523,17 +549,17 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
var clause string
if searchParamValue.Prefix == "" || searchParamValue.Prefix == "eq" {
//TODO: when no prefix is specified, we need to search using BETWEEN (+/- 0.05)
- clause = fmt.Sprintf("%sJson.value ->> '$.value' = @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' = @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "lt" || searchParamValue.Prefix == "eb" {
- clause = fmt.Sprintf("%sJson.value ->> '$.value' < @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' < @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "le" {
- clause = fmt.Sprintf("%sJson.value ->> '$.value' <= @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' <= @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "gt" || searchParamValue.Prefix == "sa" {
- clause = fmt.Sprintf("%sJson.value ->> '$.value' > @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' > @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "ge" {
- clause = fmt.Sprintf("%sJson.value ->> '$.value' >= @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' >= @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "ne" {
- clause = fmt.Sprintf("%sJson.value ->> '$.value' <> @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix))
+ clause = fmt.Sprintf("%sJson.value ->> '$.value' <> @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix))
} else if searchParamValue.Prefix == "ap" {
return "", nil, fmt.Errorf("search modifier 'ap' not supported for search parameter type %s (%s=%s)", searchParam.Type, searchParam.Name, searchParamValue.Value)
}
@@ -545,7 +571,7 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
for _, k := range allowedSecondaryKeys {
namedParameterKey := fmt.Sprintf("%s%s", searchParam.Name, strings.Title(k))
if _, ok := searchParamValue.SecondaryValues[namedParameterKey]; ok {
- clause += fmt.Sprintf(` AND %sJson.value ->> '$.%s' = @%s`, searchParam.Name, k, NamedParameterWithSuffix(namedParameterKey, namedParameterSuffix))
+ clause += fmt.Sprintf(` AND %sJson.value ->> '$.%s' = @%s`, searchParam.Name, k, NamedParameterWithSuffix(namedParameterKey, searchParam.Modifier, namedParameterSuffix))
}
}
@@ -574,7 +600,11 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
//setup the clause
clause := []string{}
if searchParamValue.Value.(string) != "" {
- clause = append(clause, fmt.Sprintf("%sJson.value ->> '$.code' = @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)))
+ if searchParam.Modifier == "" {
+ clause = append(clause, fmt.Sprintf("%sJson.value ->> '$.code' = @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)))
+ } else if searchParam.Modifier == "not" {
+ clause = append(clause, fmt.Sprintf("%sJson.value ->> '$.code' <> @%s", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)))
+ }
}
//append the code and/or system clauses (if required)
@@ -584,14 +614,14 @@ func SearchCodeToWhereClause(searchParam SearchParameter, searchParamValue Searc
for _, k := range allowedSecondaryKeys {
namedParameterKey := fmt.Sprintf("%s%s", searchParam.Name, strings.Title(k))
if _, ok := searchParamValue.SecondaryValues[namedParameterKey]; ok {
- clause = append(clause, fmt.Sprintf(`%sJson.value ->> '$.%s' = @%s`, searchParam.Name, k, NamedParameterWithSuffix(namedParameterKey, namedParameterSuffix)))
+ clause = append(clause, fmt.Sprintf(`%sJson.value ->> '$.%s' = @%s`, searchParam.Name, k, NamedParameterWithSuffix(namedParameterKey, searchParam.Modifier, namedParameterSuffix)))
}
}
return fmt.Sprintf("(%s)", strings.Join(clause, " AND ")), searchClauseNamedParams, nil
case SearchParameterTypeKeyword:
//setup the clause
- return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, namedParameterSuffix)), searchClauseNamedParams, nil
+ return fmt.Sprintf("(%s = @%s)", searchParam.Name, NamedParameterWithSuffix(searchParam.Name, searchParam.Modifier, namedParameterSuffix)), searchClauseNamedParams, nil
case SearchParameterTypeReference:
return "", nil, fmt.Errorf("search parameter type %s not supported", searchParam.Type)
}
diff --git a/backend/pkg/database/gorm_repository_query_sql_test.go b/backend/pkg/database/gorm_repository_query_sql_test.go
index c146be9c0..e40709509 100644
--- a/backend/pkg/database/gorm_repository_query_sql_test.go
+++ b/backend/pkg/database/gorm_repository_query_sql_test.go
@@ -520,3 +520,231 @@ func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenGroupByNoMo
"00000000-0000-0000-0000-000000000000",
})
}
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenWithNotModifier() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "code:not": "test_code",
+ },
+ From: "Observation",
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT fhir.*",
+ "FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
+ "WHERE ((codeJson.value ->> '$.code' <> ?)) AND (user_id = ?)",
+ "GROUP BY `fhir`.`id`",
+ "ORDER BY fhir.sort_date DESC",
+ }, " "),
+ sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "test_code", "00000000-0000-0000-0000-000000000000",
+ })
+}
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenMultipleANDValuesWithNotModifier() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "code:not": []string{"test_code", "test_code2"}, //AND condition
+ },
+ From: "Observation",
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT fhir.*",
+ "FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
+ "WHERE ((codeJson.value ->> '$.code' <> ?)) AND ((codeJson.value ->> '$.code' <> ?)) AND (user_id = ?)",
+ "GROUP BY `fhir`.`id`",
+ "ORDER BY fhir.sort_date DESC",
+ }, " "),
+ sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "test_code", "test_code2", "00000000-0000-0000-0000-000000000000",
+ })
+}
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenMultipleORValues() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "code": "test_code,test_code2", //OR condition
+ },
+ From: "Observation",
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT fhir.*",
+ "FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
+ "WHERE ((codeJson.value ->> '$.code' = ?) OR (codeJson.value ->> '$.code' = ?)) AND (user_id = ?)",
+ "GROUP BY `fhir`.`id`",
+ "ORDER BY fhir.sort_date DESC",
+ }, " "),
+ sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "test_code", "test_code2", "00000000-0000-0000-0000-000000000000",
+ })
+}
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenMultipleORANDValues() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "code": []string{"test_code,test_code2", "test_code3,test_code4"}, //OR-AND condition
+ },
+ From: "Observation",
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT fhir.*",
+ "FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
+ "WHERE ((codeJson.value ->> '$.code' = ?) OR (codeJson.value ->> '$.code' = ?)) AND ((codeJson.value ->> '$.code' = ?) OR (codeJson.value ->> '$.code' = ?)) AND (user_id = ?)",
+ "GROUP BY `fhir`.`id`",
+ "ORDER BY fhir.sort_date DESC",
+ }, " "),
+ sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "test_code", "test_code2", "test_code3", "test_code4", "00000000-0000-0000-0000-000000000000",
+ })
+}
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_WithTokenMultipleModifiersMultipleANDORValues() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "code:not": []string{"test_code", "test_code2,test_code3"}, //AND-OR condition
+ "code": "test_code4,test_code5,test_code6", //OR condition
+ },
+ From: "Observation",
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT fhir.*",
+ "FROM fhir_observation as fhir, json_each(fhir.code) as codeJson",
+ "WHERE ((codeJson.value ->> '$.code' <> ?)) AND ((codeJson.value ->> '$.code' <> ?) OR (codeJson.value ->> '$.code' <> ?)) AND ((codeJson.value ->> '$.code' = ?) OR (codeJson.value ->> '$.code' = ?) OR (codeJson.value ->> '$.code' = ?)) AND (user_id = ?)",
+ "GROUP BY `fhir`.`id`",
+ "ORDER BY fhir.sort_date DESC",
+ }, " "),
+ sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "test_code", "test_code2", "test_code3", "test_code4", "test_code5", "test_code6", "00000000-0000-0000-0000-000000000000",
+ })
+}
+
+// Section Vital Signs Codes Lookup
+
+func (suite *RepositorySqlTestSuite) TestQueryResources_SQL_SectionVitalSigns_WithTokenGroupByNoModifier() {
+ //setup
+ sqliteRepo := suite.TestRepository.(*GormRepository)
+ sqliteRepo.GormClient = sqliteRepo.GormClient.Session(&gorm.Session{DryRun: true})
+
+ //test
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ sqlQuery, err := sqliteRepo.sqlQueryResources(authContext, models.QueryResource{
+ Select: []string{},
+ Where: map[string]interface{}{
+ "category": "vital-signs",
+ },
+ From: "Observation",
+ Aggregations: &models.QueryResourceAggregations{
+ GroupBy: &models.QueryResourceAggregation{Field: "code:code"},
+ },
+ })
+ require.NoError(suite.T(), err)
+ var results []map[string]interface{}
+ statement := sqlQuery.Find(&results).Statement
+ sqlString := statement.SQL.String()
+ sqlParams := statement.Vars
+
+ //assert
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(),
+ strings.Join([]string{
+ "SELECT (codeJson.value ->> '$.code') as label, count(*) as value",
+ "FROM fhir_observation as fhir, json_each(fhir.category) as categoryJson, json_each(fhir.code) as codeJson",
+ "WHERE ((categoryJson.value ->> '$.code' = ?)) AND (user_id = ?)",
+ "GROUP BY (codeJson.value ->> '$.code')",
+ "ORDER BY count(*) DESC",
+ }, " "), sqlString)
+ require.Equal(suite.T(), sqlParams, []interface{}{
+ "vital-signs",
+ "00000000-0000-0000-0000-000000000000",
+ })
+}
diff --git a/backend/pkg/database/gorm_repository_query_test.go b/backend/pkg/database/gorm_repository_query_test.go
index 53cb50b21..69e1d8a97 100644
--- a/backend/pkg/database/gorm_repository_query_test.go
+++ b/backend/pkg/database/gorm_repository_query_test.go
@@ -38,7 +38,9 @@ func TestProcessSearchParameter(t *testing.T) {
{"url:below", map[string]string{"url": "string"}, SearchParameter{Type: "string", Name: "url", Modifier: "below"}, false},
{"url:above", map[string]string{"url": "string"}, SearchParameter{Type: "string", Name: "url", Modifier: "above"}, false},
- {"display:text", map[string]string{"display": "token"}, SearchParameter{}, true},
+ {"display", map[string]string{"display": "token"}, SearchParameter{Type: "token", Name: "display", Modifier: ""}, false},
+ {"display:not", map[string]string{"display": "token"}, SearchParameter{Type: "token", Name: "display", Modifier: "not"}, false},
+ {"display:unsupported", map[string]string{"display": "token"}, SearchParameter{}, true},
}
//test && assert
@@ -147,10 +149,10 @@ func TestSearchCodeToWhereClause(t *testing.T) {
{SearchParameter{Type: "date", Name: "issueDate", Modifier: ""}, SearchParameterValue{Value: time.Date(2013, time.January, 14, 10, 0, 0, 0, time.UTC), Prefix: "lt", SecondaryValues: map[string]interface{}{}}, "1_1", "(issueDate < @issueDate_1_1)", map[string]interface{}{"issueDate_1_1": time.Date(2013, time.January, 14, 10, 0, 0, 0, time.UTC)}, false},
{SearchParameter{Type: "string", Name: "given", Modifier: ""}, SearchParameterValue{Value: "eve", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(givenJson.value LIKE @given_0_0)", map[string]interface{}{"given_0_0": "eve%"}, false},
- {SearchParameter{Type: "string", Name: "given", Modifier: "contains"}, SearchParameterValue{Value: "eve", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(givenJson.value LIKE @given_0_0)", map[string]interface{}{"given_0_0": "%eve%"}, false},
- {SearchParameter{Type: "string", Name: "given", Modifier: "exact"}, SearchParameterValue{Value: "eve", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(givenJson.value = @given_0_0)", map[string]interface{}{"given_0_0": "eve"}, false},
+ {SearchParameter{Type: "string", Name: "given", Modifier: "contains"}, SearchParameterValue{Value: "eve", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(givenJson.value LIKE @given_contains_0_0)", map[string]interface{}{"given_contains_0_0": "%eve%"}, false},
+ {SearchParameter{Type: "string", Name: "given", Modifier: "exact"}, SearchParameterValue{Value: "eve", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(givenJson.value = @given_exact_0_0)", map[string]interface{}{"given_exact_0_0": "eve"}, false},
- {SearchParameter{Type: "uri", Name: "url", Modifier: "below"}, SearchParameterValue{Value: "http://acme.org/fhir/", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(url LIKE @url_0_0)", map[string]interface{}{"url_0_0": "http://acme.org/fhir/%"}, false},
+ {SearchParameter{Type: "uri", Name: "url", Modifier: "below"}, SearchParameterValue{Value: "http://acme.org/fhir/", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(url LIKE @url_below_0_0)", map[string]interface{}{"url_below_0_0": "http://acme.org/fhir/%"}, false},
{SearchParameter{Type: "uri", Name: "url", Modifier: "above"}, SearchParameterValue{Value: "http://acme.org/fhir/", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "", map[string]interface{}{}, true}, //above modifier not supported
{SearchParameter{Type: "quantity", Name: "valueQuantity", Modifier: ""}, SearchParameterValue{Value: float64(5.4), Prefix: "", SecondaryValues: map[string]interface{}{"valueQuantityCode": "mg"}}, "0_0", "(valueQuantityJson.value ->> '$.value' = @valueQuantity_0_0 AND valueQuantityJson.value ->> '$.code' = @valueQuantityCode_0_0)", map[string]interface{}{"valueQuantity_0_0": float64(5.4), "valueQuantityCode_0_0": "mg"}, false},
@@ -161,7 +163,9 @@ func TestSearchCodeToWhereClause(t *testing.T) {
{SearchParameter{Type: "token", Name: "code", Modifier: ""}, SearchParameterValue{Value: "ha125", Prefix: "", SecondaryValues: map[string]interface{}{"codeSystem": "http://acme.org/conditions/codes"}}, "0_0", "(codeJson.value ->> '$.code' = @code_0_0 AND codeJson.value ->> '$.system' = @codeSystem_0_0)", map[string]interface{}{"code_0_0": "ha125", "codeSystem_0_0": "http://acme.org/conditions/codes"}, false},
{SearchParameter{Type: "token", Name: "code", Modifier: ""}, SearchParameterValue{Value: "ha125", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(codeJson.value ->> '$.code' = @code_0_0)", map[string]interface{}{"code_0_0": "ha125"}, false},
- {SearchParameter{Type: "token", Name: "identifier", Modifier: "otype"}, SearchParameterValue{Value: "MR|446053", Prefix: "", SecondaryValues: map[string]interface{}{"identifierSystem": "http://terminology.hl7.org/CodeSystem/v2-0203"}}, "0_0", "(identifierJson.value ->> '$.code' = @identifier_0_0 AND identifierJson.value ->> '$.system' = @identifierSystem_0_0)", map[string]interface{}{"identifier_0_0": "MR|446053", "identifierSystem_0_0": "http://terminology.hl7.org/CodeSystem/v2-0203"}, false},
+ {SearchParameter{Type: "token", Name: "identifier", Modifier: ""}, SearchParameterValue{Value: "MR|446053", Prefix: "", SecondaryValues: map[string]interface{}{"identifierSystem": "http://terminology.hl7.org/CodeSystem/v2-0203"}}, "0_0", "(identifierJson.value ->> '$.code' = @identifier_0_0 AND identifierJson.value ->> '$.system' = @identifierSystem_0_0)", map[string]interface{}{"identifier_0_0": "MR|446053", "identifierSystem_0_0": "http://terminology.hl7.org/CodeSystem/v2-0203"}, false},
+ {SearchParameter{Type: "token", Name: "gender", Modifier: ""}, SearchParameterValue{Value: "male", Prefix: "", SecondaryValues: map[string]interface{}{"genderSystem": "http://terminology.hl7.org/CodeSystem/v2-0203"}}, "0_0", "(genderJson.value ->> '$.code' = @gender_0_0 AND genderJson.value ->> '$.system' = @genderSystem_0_0)", map[string]interface{}{"gender_0_0": "male", "genderSystem_0_0": "http://terminology.hl7.org/CodeSystem/v2-0203"}, false},
+ {SearchParameter{Type: "token", Name: "gender", Modifier: "not"}, SearchParameterValue{Value: "male", Prefix: "", SecondaryValues: map[string]interface{}{"genderSystem": "http://terminology.hl7.org/CodeSystem/v2-0203"}}, "0_0", "(genderJson.value ->> '$.code' <> @gender_not_0_0 AND genderJson.value ->> '$.system' = @genderSystem_not_0_0)", map[string]interface{}{"gender_not_0_0": "male", "genderSystem_not_0_0": "http://terminology.hl7.org/CodeSystem/v2-0203"}, false},
{SearchParameter{Type: "keyword", Name: "id", Modifier: ""}, SearchParameterValue{Value: "1234", Prefix: "", SecondaryValues: map[string]interface{}{}}, "0_0", "(id = @id_0_0)", map[string]interface{}{"id_0_0": "1234"}, false},
}
diff --git a/backend/pkg/database/gorm_repository_summary.go b/backend/pkg/database/gorm_repository_summary.go
new file mode 100644
index 000000000..7c599dce8
--- /dev/null
+++ b/backend/pkg/database/gorm_repository_summary.go
@@ -0,0 +1,818 @@
+package database
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "github.com/TwiN/deepmerge"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models/database"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips"
+ "github.com/fastenhealth/gofhir-models/fhir401"
+ "github.com/google/uuid"
+ "github.com/samber/lo"
+ "log"
+ "time"
+)
+
+// returns IPSBundle and IPSComposition
+func (gr *GormRepository) GetInternationalPatientSummaryExport(ctx context.Context) (*ips.InternationalPatientSummaryExportData, error) {
+ exportData := &ips.InternationalPatientSummaryExportData{}
+
+ summaryTime := time.Now()
+ timestamp := summaryTime.Format(time.RFC3339)
+
+ exportData.GenerationDate = summaryTime
+
+ //get a list of all Patients associated with this user (we'll be creating a pseudo Patient for referencing in this Bundle
+ patient, err := gr.GetPatientMerged(ctx)
+ if err != nil {
+ //TODO: determine if we should error out here. If only manually entered records were entered, we wont have a Patient record,
+ return exportData, err
+ }
+ exportData.Patient = patient
+
+ //get a list of all Sources associated with this user
+ sources, err := gr.GetSources(ctx)
+ if err != nil {
+ return exportData, err
+ }
+ exportData.Sources = sources
+
+ narrativeEngine, err := ips.NewNarrative()
+ if err != nil {
+ return exportData, fmt.Errorf("error creating narrative engine: %w", err)
+ }
+
+ //Algorithm to create the IPS bundle
+ // 1. Generate the IPS Section Lists (GetInternationalPatientSummarySectionResources)
+ // - Process each resource, generating a Markdown narrative in the text field for each resource
+ // - keep track of the earliest and latest date of the resources in the section
+ // 2. Create the Composition Section (generateIPSCompositionSection)
+ // - Populate it with the data from the Header
+ // - Generate a Section Narrative, written in Markdown, which summarizes the contents of the section at a high level, with dates and counts
+ // 3. Query all the Patient Resources
+ // - Merge the Patient resources together?
+ // 4. Create a Fasten Health Organization resource. This is the custodian of the IPS
+ // 5. Create the IPS Composition
+ // - Populate it with the Composition Sections and references to the Patient resource + Fasten Health Organziation resource
+ // - Generate a Composition Narrative, written in Markdown, which summarizes the contents of the IPS & Patient at a high level, with dates and counts
+ // 6. Create the IPS Bundle
+
+ //Step 1. Generate the IPS Section Lists
+ summarySectionQueryResults, err := gr.getInternationalPatientSummarySectionResources(ctx)
+ if err != nil {
+ return exportData, err
+ }
+
+ //Step 2. Create the Composition Section
+ compositionSections := []fhir401.CompositionSection{}
+
+ //loop though the various section groups in order (required, recommended, optional)
+ for ndx, _ := range pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsRequired] {
+ section := pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsRequired][ndx]
+ if sectionQueryResultsList, ok := summarySectionQueryResults[section]; ok {
+ compositionSection, err := generateIPSCompositionSection(narrativeEngine, section, sectionQueryResultsList)
+ if err != nil {
+ return exportData, err
+ }
+ compositionSections = append(compositionSections, *compositionSection)
+ }
+ }
+ for ndx, _ := range pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsRecommended] {
+ section := pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsRecommended][ndx]
+ if sectionQueryResultsList, ok := summarySectionQueryResults[section]; ok {
+ compositionSection, err := generateIPSCompositionSection(narrativeEngine, section, sectionQueryResultsList)
+ if err != nil {
+ return exportData, err
+ }
+ compositionSections = append(compositionSections, *compositionSection)
+ }
+ }
+ for ndx, _ := range pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsOptional] {
+ section := pkg.IPSSectionGroupsOrdered[pkg.IPSSectionGroupsOptional][ndx]
+ if sectionQueryResultsList, ok := summarySectionQueryResults[section]; ok {
+ compositionSection, err := generateIPSCompositionSection(narrativeEngine, section, sectionQueryResultsList)
+ if err != nil {
+ return exportData, err
+ }
+ compositionSections = append(compositionSections, *compositionSection)
+ }
+ }
+
+ //for sectionType, sectionQueryResultsList := range summarySectionQueryResults {
+ // compositionSection, err := generateIPSCompositionSection(narrativeEngine, sectionType, sectionQueryResultsList)
+ // if err != nil {
+ // return exportData, err
+ // }
+ // compositionSections = append(compositionSections, *compositionSection)
+ //}
+
+ //TODO: Step 3. Query all the Patient Resources & merge them together
+
+ //TODO: Step 4. Create a Fasten Health Organization resource.
+
+ compositionUUID := uuid.New().String()
+ patientReference := fmt.Sprintf("%s/%s", exportData.Patient.GetSourceResourceType(), exportData.Patient.GetSourceResourceID())
+
+ //Step 5. Create the IPS Composition
+ ipsComposition := &fhir401.Composition{
+ Id: stringPtr(compositionUUID),
+ Text: &fhir401.Narrative{
+ Status: fhir401.NarrativeStatusGenerated,
+ Div: "PLACEHOLDER NARRATIVE SUMMARY FOR COMPOSITION", //TODO
+ },
+ Identifier: &fhir401.Identifier{
+ System: stringPtr("https://www.fastenhealth.com"), //TODO
+ Value: &compositionUUID,
+ },
+ Status: fhir401.CompositionStatusFinal,
+ Type: fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("60591-5"),
+ Display: stringPtr("Patient Summary"),
+ },
+ },
+ },
+ Subject: &fhir401.Reference{
+ Reference: stringPtr(patientReference), //TODO
+ },
+ Date: timestamp,
+ Author: []fhir401.Reference{
+ {
+ Reference: stringPtr("Organization/fastenhealth.com"), //TODO: The type of author(s) contribute to determine the "nature"of the Patient Summary: e.g. a "human-curated" IPS Vs. an "automatically generated" IPS.
+ },
+ },
+ Title: fmt.Sprintf("Patient Summary as of %s", summaryTime.Format("January 2, 2006 15:04")),
+ Attester: []fhir401.CompositionAttester{
+ {
+ Mode: fhir401.CompositionAttestationModePersonal,
+ Time: ×tamp,
+ Party: &fhir401.Reference{
+ Reference: stringPtr(patientReference),
+ },
+ },
+ },
+ Custodian: &fhir401.Reference{
+ Reference: stringPtr("Organization/fastenhealth.com"),
+ },
+ Event: []fhir401.CompositionEvent{
+ {
+ Code: []fhir401.CodeableConcept{
+ {
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://terminology.hl7.org/CodeSystem/v3-ActClass"),
+ Code: stringPtr("PCPR"),
+ },
+ },
+ },
+ },
+ Period: &fhir401.Period{
+ Start: ×tamp, //TODO: this should be the oldest record in the summary
+ End: ×tamp,
+ },
+ },
+ },
+ }
+ ipsComposition.Section = compositionSections
+
+ // Step 6. Create the IPS Bundle
+ bundleUUID := uuid.New().String()
+ ipsBundle := &fhir401.Bundle{
+ Id: &bundleUUID,
+ Timestamp: ×tamp,
+ Language: stringPtr("en-US"),
+ Entry: []fhir401.BundleEntry{},
+ Type: fhir401.BundleTypeDocument,
+ }
+
+ // Add the Composition to the bundle
+ ipsCompositionJson, err := json.Marshal(ipsComposition)
+ if err != nil {
+ return exportData, err
+ }
+ ipsBundle.Entry = append(ipsBundle.Entry, fhir401.BundleEntry{
+ Resource: json.RawMessage(ipsCompositionJson),
+ })
+
+ // TODO: Add the Patient to the bundle
+ // TODO: Add the Fasten Health Organization to the bundle
+
+ // TODO: Add all the resources to the bundle
+ //for _, sectionResources := range summarySectionResources {
+ // for _, resource := range sectionResources {
+ // ipsBundle.Entry = append(ipsBundle.Entry, fhir401.BundleEntry{
+ // Resource: json.RawMessage(resource.GetResourceRaw()),
+ // })
+ // }
+ //}
+
+ exportData.Bundle = ipsBundle
+ exportData.Composition = ipsComposition
+
+ return exportData, nil
+}
+
+// GetInternationalPatientSummary will generate an IPS bundle, which can then be used to generate a IPS QR code, PDF or JSON bundle
+// The IPS bundle will contain a summary of all the data in the system, including a list of all sources, and the main Patient
+// See: https://github.com/fastenhealth/fasten-onprem/issues/170
+// See: https://github.com/jddamore/fhir-ips-server/blob/main/docs/Summary_Creation_Steps.md
+func (gr *GormRepository) getInternationalPatientSummarySectionResources(ctx context.Context) (map[pkg.IPSSections][]any, error) {
+
+ summarySectionResources := map[pkg.IPSSections][]any{}
+
+ // generate queries for each IPS Section
+ for ndx, _ := range pkg.IPSSectionsList {
+ sectionName := pkg.IPSSectionsList[ndx]
+
+ //initialize the section
+ summarySectionResources[sectionName] = []any{}
+
+ queries, err := gr.generateIPSSectionQueries(ctx, sectionName)
+ if err != nil {
+ return nil, err
+ }
+
+ for qndx, _ := range queries {
+ results, err := gr.QueryResources(ctx, queries[qndx])
+ if err != nil {
+ return nil, err
+ }
+
+ //resultsList := convertUnknownInterfaceToFhirSlice(results)
+
+ //TODO: generate resource narrative
+ summarySectionResources[sectionName] = append(summarySectionResources[sectionName], results)
+ }
+ }
+
+ return summarySectionResources, nil
+}
+
+func generateIPSCompositionSection(narrativeEngine *ips.Narrative, sectionType pkg.IPSSections, queryResultsList []any) (*fhir401.CompositionSection, error) {
+ sectionTitle, sectionCode, err := generateIPSSectionHeaderInfo(sectionType)
+ if err != nil {
+ return nil, err
+ }
+
+ section := &fhir401.CompositionSection{
+ Title: §ionTitle,
+ Code: §ionCode,
+ }
+
+ //database.IFhirResourceModel
+
+ resources := flattenQueryResultsToResourcesList(queryResultsList)
+
+ if len(resources) == 0 {
+ section.EmptyReason = &fhir401.CodeableConcept{
+ Text: stringPtr("No data available"),
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://terminology.hl7.org/CodeSystem/list-empty-reason"),
+ Code: stringPtr("unavailable"),
+ },
+ },
+ }
+ } else {
+ section.Entry = []fhir401.Reference{}
+ for _, resource := range resources {
+ reference := fhir401.Reference{
+ Reference: stringPtr(fmt.Sprintf("%s/%s", resource.GetSourceResourceType(), resource.GetSourceResourceID())),
+ }
+ if err != nil {
+ return nil, err
+ }
+ section.Entry = append(section.Entry, reference)
+ }
+
+ //TODO: Add the section narrative summary
+ rendered, err := narrativeEngine.RenderSection(
+ sectionType,
+ resources,
+ )
+ if err != nil {
+ return nil, fmt.Errorf("error rendering narrative for section %s: %w", sectionType, err)
+ }
+
+ section.Text = &fhir401.Narrative{
+ Status: fhir401.NarrativeStatusGenerated,
+ Div: rendered,
+ }
+
+ }
+ return section, nil
+}
+
+// https://github.com/jddamore/fhir-ips-server/blob/main/docs/Summary_Creation_Steps.md
+// Generate Resource Queries for each IPS Section
+func (gr *GormRepository) generateIPSSectionQueries(ctx context.Context, sectionType pkg.IPSSections) ([]models.QueryResource, error) {
+
+ queries := []models.QueryResource{}
+ switch sectionType {
+ case pkg.IPSSectionsAllergiesIntolerances:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "AllergyIntolerance",
+ Where: map[string]interface{}{
+ "clinicalStatus:not": []string{"inactive", "resolved"},
+ "verificationStatus:not": []string{"entered-in-error"},
+ },
+ })
+ break
+ case pkg.IPSSectionsProblemList:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Condition",
+ Where: map[string]interface{}{
+ "clinicalStatus:not": []string{"inactive", "resolved"},
+ "verificationStatus:not": []string{"entered-in-error"},
+ },
+ })
+ break
+ case pkg.IPSSectionsMedicationSummary:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "MedicationStatement",
+ Where: map[string]interface{}{
+ "status": "active,intended,unknown,on-hold",
+ },
+ })
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "MedicationRequest",
+ Where: map[string]interface{}{
+ "status": "active,unknown,on-hold",
+ },
+ })
+ break
+ case pkg.IPSSectionsDiagnosticResults:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "DiagnosticReport",
+ Where: map[string]interface{}{
+ "category": "LAB",
+ },
+ })
+
+ //TODO: group by code, sort by date, limit to the most recent 3
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Observation",
+ Where: map[string]interface{}{
+ "category": "laboratory",
+ "status:not": "preliminary",
+ },
+ })
+ break
+ case pkg.IPSSectionsVitalSigns:
+ //lets query the database for this user, getting a list of unique codes, associated with this category ('vital-signs').
+ //our goal is to retrieve the 3 most recent values for each code.
+ vitalSignsGrouped, err := gr.QueryResources(ctx, models.QueryResource{
+ Select: nil,
+ From: "Observation",
+ Where: map[string]interface{}{
+ "category": "vital-signs",
+ },
+ Aggregations: &models.QueryResourceAggregations{
+ GroupBy: &models.QueryResourceAggregation{Field: "code:code"},
+ },
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ vitalSignsGroupedByCodeList, ok := vitalSignsGrouped.([]map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("could not decode vital signs grouped by code")
+ }
+
+ //known codes related to vital signs: https://www.hl7.org/fhir/R4/valueset-observation-vitalsignresult.html#definition
+ vitalSignCodes := []string{
+ "85353-1", "9279-1", "8867-4", "2708-6", "8310-5", "8302-2", "9843-4", "29463-7", "39156-5", "85354-9", "8480-6", "8462-4", "8478-0",
+ }
+
+ for ndx, _ := range vitalSignsGroupedByCodeList {
+ //now that we have a list of codes that are tagged as vital-signs.
+ if labelValue, labelValueOk := vitalSignsGroupedByCodeList[ndx]["label"]; labelValueOk {
+ if labelValueStr, labeValueStrOk := labelValue.(*interface{}); labeValueStrOk {
+ vitalSignCodes = append(vitalSignCodes, (*labelValueStr).(string))
+ } else {
+ gr.Logger.Warnf("could not cast vital-sign codes to string")
+ }
+ } else {
+ gr.Logger.Warnf("could not retrieve vital-sign group-by clause label value")
+ }
+ }
+ vitalSignCodes = lo.Uniq(vitalSignCodes)
+
+ limit := 3
+ //group by code, sort by date, limit to the most recent 3
+ for ndx, _ := range vitalSignCodes {
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Observation",
+ Where: map[string]interface{}{
+ "code": vitalSignCodes[ndx],
+ },
+ Limit: &limit,
+ })
+ }
+ break
+ case pkg.IPSSectionsSocialHistory:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Observation",
+ Where: map[string]interface{}{
+ "category": "social-history",
+ "status:not": "preliminary",
+ },
+ })
+ break
+ case pkg.IPSSectionsPregnancy:
+ //TODO: determine the code for pregnancy from IPS specification
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Observation",
+ Where: map[string]interface{}{
+ "status:not": "preliminary",
+ },
+ })
+ break
+ case pkg.IPSSectionsImmunizations:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Immunization",
+ Where: map[string]interface{}{
+ "status:not": "entered-in-error",
+ },
+ })
+ break
+ case pkg.IPSSectionsAdvanceDirectives:
+ //queries = append(queries, models.QueryResource{
+ // Select: nil,
+ // From: "Consent",
+ // Where: map[string]interface{}{
+ // "status": "active",
+ // },
+ //})
+ log.Printf("warning: Consent FHIR resources are not supported yet. Skipping")
+ break
+ case pkg.IPSSectionsFunctionalStatus:
+ //queries = append(queries, models.QueryResource{
+ // Select: nil,
+ // From: "ClinicalImpression",
+ // Where: map[string]interface{}{
+ // "status": "in-progress,completed",
+ // },
+ //})
+ log.Printf("warning: ClinicalImpression FHIR resources are not supported yet. Skipping")
+ break
+ case pkg.IPSSectionsMedicalDevices:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Device",
+ Where: map[string]interface{}{
+ "status": "entered-in-error",
+ },
+ })
+ break
+ case pkg.IPSSectionsHistoryOfIllness:
+ //TODO: last updated date should be older than 5 years (dateTime or period.high)
+ //TODO: check if where clause with multiple modifiers for the same field works as expected
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Condition",
+ Where: map[string]interface{}{
+ "clinicalStatus:not": []string{"entered-in-error"},
+ "clinicalStatus": "inactive,remission,resolved",
+ },
+ })
+ break
+ case pkg.IPSSectionsPlanOfCare:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "CarePlan",
+ Where: map[string]interface{}{
+ "status": "active,on-hold,unknown",
+ },
+ })
+ break
+ case pkg.IPSSectionsHistoryOfProcedures:
+ queries = append(queries, models.QueryResource{
+ Select: nil,
+ From: "Procedure",
+ Where: map[string]interface{}{
+ "status:not": []string{"entered-in-error", "not-done"},
+ },
+ })
+ break
+ default:
+ return nil, fmt.Errorf("unsupported section type: %s", sectionType)
+ }
+
+ return queries, nil
+}
+
+// generate header information for Composition Sections. Title & Code for each section
+func generateIPSSectionHeaderInfo(sectionType pkg.IPSSections) (string, fhir401.CodeableConcept, error) {
+ switch sectionType {
+ case pkg.IPSSectionsMedicationSummary:
+ return "Medication Summary", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("10160-0"),
+ Display: stringPtr("Medication Summary"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsAllergiesIntolerances:
+ return "Allergies and Intolerances", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("48765-2"),
+ Display: stringPtr("Allergies and Intolerances"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsProblemList:
+ return "Problem List", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("11450-4"),
+ Display: stringPtr("Problem List"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsImmunizations:
+ return "Immunizations", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("11369-6"),
+ Display: stringPtr("Immunizations"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsHistoryOfProcedures:
+ return "History of Procedures", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("47519-4"),
+ Display: stringPtr("History of Procedures"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsMedicalDevices:
+ return "Medical Devices", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("46264-8"),
+ Display: stringPtr("Medical Devices"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsDiagnosticResults:
+ return "Diagnostic Results", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("30954-2"),
+ Display: stringPtr("Diagnostic Results"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsVitalSigns:
+ return "Vital Signs", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("8716-3"),
+ Display: stringPtr("Vital Signs"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsHistoryOfIllness:
+ return "Past History of Illness", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("11348-0"),
+ Display: stringPtr("History of Illness"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsPregnancy:
+ return "Pregnancy History", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("10162-6"),
+ Display: stringPtr("Pregnancy History"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsSocialHistory:
+ return "Social History", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("29762-2"),
+ Display: stringPtr("Social History"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsPlanOfCare:
+ return "Plan of Care", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("18776-5"),
+ Display: stringPtr("Plan of Care"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsFunctionalStatus:
+ return "Functional Status", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("47420-5"),
+ Display: stringPtr("Functional Status"),
+ },
+ },
+ }, nil
+ case pkg.IPSSectionsAdvanceDirectives:
+ return "Advance Directives", fhir401.CodeableConcept{
+ Coding: []fhir401.Coding{
+ {
+ System: stringPtr("http://loinc.org"),
+ Code: stringPtr("42348-3"),
+ Display: stringPtr("Advance Directives"),
+ },
+ },
+ }, nil
+ default:
+ return "", fhir401.CodeableConcept{}, fmt.Errorf("invalid section type: %s", sectionType)
+ }
+
+}
+
+// QueryResources returns an interface{} which is actually a slice of the appropriate FHIR resource type
+// we use this function to "cast" the results to a slice of the IFhirResourceModel interface (so we can use the same code to handle the results)
+// TODO: there has to be a better way to do this :/
+func convertUnknownInterfaceToFhirSlice(unknown interface{}) []database.IFhirResourceModel {
+ results := []database.IFhirResourceModel{}
+
+ switch fhirSlice := unknown.(type) {
+ case []database.FhirAllergyIntolerance:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirCarePlan:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirCondition:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirDevice:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirDiagnosticReport:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirEncounter:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirImmunization:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirMedicationRequest:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirMedicationStatement:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirObservation:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirPatient:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ case []database.FhirProcedure:
+ for ndx, _ := range fhirSlice {
+ results = append(results, &fhirSlice[ndx])
+ }
+ default:
+ log.Panicf("could not detect type for query results fhir resource list: %v", fhirSlice)
+ }
+
+ return results
+}
+
+// query results may be a list of database.IFhirResourceModel or a map[string][]database.IFhirResourceModel (if we're using aggregations/grouping)
+func flattenQueryResultsToResourcesList(queryResultsList []any) []database.IFhirResourceModel {
+ resources := []database.IFhirResourceModel{}
+
+ for ndx, _ := range queryResultsList {
+ queryResults := queryResultsList[ndx]
+ switch queryResultsTyped := queryResults.(type) {
+ case []map[string]any:
+ //aggregated resources
+ for andx, _ := range queryResultsTyped {
+ queryResultsGrouped := queryResultsTyped[andx]
+ resources = append(resources, convertUnknownInterfaceToFhirSlice(queryResultsGrouped)...)
+ }
+
+ case interface{}:
+ //list of resources
+ resources = append(resources, convertUnknownInterfaceToFhirSlice(queryResultsTyped)...)
+ default:
+ log.Panicf("Unknown Resource Structure: %v", queryResultsTyped)
+ }
+ }
+
+ return resources
+}
+
+// When given a list of Patient database records, we need to merge them together to a Patient record that's usable by the
+func (gr *GormRepository) GetPatientMerged(ctx context.Context) (*database.FhirPatient, error) {
+ currentUser, currentUserErr := gr.GetCurrentUser(ctx)
+ if currentUserErr != nil {
+ return nil, currentUserErr
+ }
+
+ tableName, err := database.GetTableNameByResourceType("Patient")
+ if err != nil {
+ return nil, err
+ }
+
+ var wrappedFhirPatients []database.FhirPatient
+ results := gr.GormClient.WithContext(ctx).
+ //Group("source_id"). //broken in Postgres.
+ Where(models.OriginBase{
+ UserID: currentUser.ID,
+ SourceResourceType: "Patient",
+ }).
+ Order("sort_date DESC").
+ Table(tableName).
+ Find(&wrappedFhirPatients)
+
+ if results.Error != nil {
+ return nil, results.Error
+ }
+
+ return mergePatients(wrappedFhirPatients)
+}
+
+// helper utility
+func stringPtr(s string) *string {
+ return &s
+}
+
+func mergePatients(patients []database.FhirPatient) (*database.FhirPatient, error) {
+ if len(patients) == 0 {
+ log.Printf("no patients to merge, ignoring")
+ return nil, fmt.Errorf("no patients to merge, ignoring")
+ }
+ mergedPatientResource := `{}`
+ for ndx, _ := range patients {
+ patient := patients[ndx]
+ mergedPatientResourceBytes, err := deepmerge.JSON([]byte(mergedPatientResource), []byte(patient.ResourceRaw))
+ if err != nil {
+ return nil, err
+ }
+ mergedPatientResource = string(mergedPatientResourceBytes)
+ }
+
+ mergedPatient := &database.FhirPatient{
+ ResourceBase: models.ResourceBase{
+ OriginBase: patients[len(patients)-1].OriginBase,
+ },
+ }
+ err := mergedPatient.PopulateAndExtractSearchParameters([]byte(mergedPatientResource))
+ if err != nil {
+ return nil, fmt.Errorf("error occurred while extracting fields from merged Patient")
+ }
+ return mergedPatient, nil
+}
diff --git a/backend/pkg/database/gorm_repository_summary_test.go b/backend/pkg/database/gorm_repository_summary_test.go
new file mode 100644
index 000000000..8a809b08c
--- /dev/null
+++ b/backend/pkg/database/gorm_repository_summary_test.go
@@ -0,0 +1,122 @@
+package database
+
+import (
+ "context"
+ "fmt"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg"
+ mock_config "github.com/fastenhealth/fasten-onprem/backend/pkg/config/mock"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/event_bus"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models"
+ sourceFactory "github.com/fastenhealth/fasten-sources/clients/factory"
+ sourcePkg "github.com/fastenhealth/fasten-sources/pkg"
+ "github.com/fastenhealth/gofhir-models/fhir401"
+ "github.com/golang/mock/gomock"
+ "github.com/google/uuid"
+ "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/require"
+ "github.com/stretchr/testify/suite"
+ "io/ioutil"
+ "log"
+ "os"
+ "testing"
+)
+
+// Define the suite, and absorb the built-in basic suite
+// functionality from testify - including a T() method which
+// returns the current testing context
+type RepositorySummaryTestSuite struct {
+ suite.Suite
+ MockCtrl *gomock.Controller
+ TestDatabase *os.File
+}
+
+// BeforeTest has a function to be executed right before the test starts and receives the suite and test names as input
+func (suite *RepositorySummaryTestSuite) BeforeTest(suiteName, testName string) {
+ suite.MockCtrl = gomock.NewController(suite.T())
+
+ dbFile, err := ioutil.TempFile("", fmt.Sprintf("%s.*.db", testName))
+ if err != nil {
+ log.Fatal(err)
+ }
+ suite.TestDatabase = dbFile
+
+}
+
+// AfterTest has a function to be executed right after the test finishes and receives the suite and test names as input
+func (suite *RepositorySummaryTestSuite) AfterTest(suiteName, testName string) {
+ suite.MockCtrl.Finish()
+ os.Remove(suite.TestDatabase.Name())
+ os.Remove(suite.TestDatabase.Name() + "-shm")
+ os.Remove(suite.TestDatabase.Name() + "-wal")
+}
+
+// In order for 'go test' to run this suite, we need to create
+// a normal test function and pass our suite to suite.Run
+func TestRepositorySummaryTestSuiteSuite(t *testing.T) {
+ suite.Run(t, new(RepositorySummaryTestSuite))
+}
+
+func (suite *RepositorySummaryTestSuite) TestGetInternationalPatientSummaryBundle() {
+ //setup
+ fakeConfig := mock_config.NewMockInterface(suite.MockCtrl)
+ fakeConfig.EXPECT().GetString("database.location").Return(suite.TestDatabase.Name()).AnyTimes()
+ fakeConfig.EXPECT().GetString("database.type").Return("sqlite").AnyTimes()
+ fakeConfig.EXPECT().IsSet("database.encryption.key").Return(false).AnyTimes()
+ fakeConfig.EXPECT().GetString("log.level").Return("INFO").AnyTimes()
+ dbRepo, err := NewRepository(fakeConfig, logrus.WithField("test", suite.T().Name()), event_bus.NewNoopEventBusServer())
+ require.NoError(suite.T(), err)
+
+ userModel := &models.User{
+ Username: "test_username",
+ Password: "testpassword",
+ Email: "test@test.com",
+ }
+ err = dbRepo.CreateUser(context.Background(), userModel)
+ require.NoError(suite.T(), err)
+ require.NotEmpty(suite.T(), userModel.ID)
+ require.NotEqual(suite.T(), uuid.Nil, userModel.ID)
+ authContext := context.WithValue(context.Background(), pkg.ContextKeyTypeAuthUsername, "test_username")
+
+ testSourceCredential := models.SourceCredential{
+ ModelBase: models.ModelBase{
+ ID: uuid.New(),
+ },
+ UserID: userModel.ID,
+ Patient: uuid.New().String(),
+ PlatformType: sourcePkg.PlatformTypeManual,
+ }
+ err = dbRepo.CreateSource(authContext, &testSourceCredential)
+ require.NoError(suite.T(), err)
+
+ bundleFile, err := os.Open("./testdata/Abraham100_Heller342_262b819a-5193-404a-9787-b7f599358035.json")
+ require.NoError(suite.T(), err)
+
+ testLogger := logrus.WithFields(logrus.Fields{
+ "type": "test",
+ })
+
+ manualClient, err := sourceFactory.GetSourceClient(sourcePkg.FastenLighthouseEnvSandbox, authContext, testLogger, &testSourceCredential)
+
+ summary, err := manualClient.SyncAllBundle(dbRepo, bundleFile, sourcePkg.FhirVersion401)
+ require.NoError(suite.T(), err)
+ require.Equal(suite.T(), 198, summary.TotalResources)
+ require.Equal(suite.T(), 234, len(summary.UpdatedResources))
+
+ //test
+ bundle, composition, err := dbRepo.GetInternationalPatientSummaryBundle(authContext)
+ require.NoError(suite.T(), err)
+
+ //case bundle and composition
+ fhirBundle := bundle.(*fhir401.Bundle)
+ fhirComposition := composition.(*fhir401.Composition)
+
+ require.NotNil(suite.T(), fhirBundle)
+ require.NotNil(suite.T(), fhirComposition)
+
+ require.Equal(suite.T(), 211, len(fhirBundle.Entry))
+ require.Equal(suite.T(), 14, len(fhirComposition.Section))
+
+ //require.Equal(suite.T(), "", fhirComposition.Section[0].Title)
+ //require.Equal(suite.T(), "", fhirComposition.Section[0].Text.Div)
+
+}
diff --git a/backend/pkg/database/interface.go b/backend/pkg/database/interface.go
index 65adea781..c77d96398 100644
--- a/backend/pkg/database/interface.go
+++ b/backend/pkg/database/interface.go
@@ -4,6 +4,7 @@ import (
"context"
"github.com/fastenhealth/fasten-onprem/backend/pkg"
"github.com/fastenhealth/fasten-onprem/backend/pkg/models"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips"
sourcePkg "github.com/fastenhealth/fasten-sources/clients/models"
"github.com/google/uuid"
)
@@ -19,7 +20,9 @@ type DatabaseRepository interface {
GetCurrentUser(ctx context.Context) (*models.User, error)
DeleteCurrentUser(ctx context.Context) error
+ //get a count of every resource type
GetSummary(ctx context.Context) (*models.Summary, error)
+ GetInternationalPatientSummaryExport(ctx context.Context) (*ips.InternationalPatientSummaryExportData, error)
GetResourceByResourceTypeAndId(context.Context, string, string) (*models.ResourceBase, error)
GetResourceBySourceId(context.Context, string, string) (*models.ResourceBase, error)
diff --git a/backend/pkg/models/database/fhir_account.go b/backend/pkg/models/database/fhir_account.go
index 1367e3606..e66523222 100644
--- a/backend/pkg/models/database/fhir_account.go
+++ b/backend/pkg/models/database/fhir_account.go
@@ -48,10 +48,10 @@ type FhirAccount struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // E.g. patient, expense, depreciation
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -74,8 +74,8 @@ func (s *FhirAccount) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -129,14 +129,14 @@ func (s *FhirAccount) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -167,14 +167,14 @@ func (s *FhirAccount) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting Period
periodResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Account.servicePeriod')")
if err == nil && periodResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, periodResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01-02", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006", periodResult.String()); err == nil {
s.Period = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", periodResult.String())
- if err == nil {
- s.Period = &d
- }
}
}
// extracting Status
@@ -188,9 +188,14 @@ func (s *FhirAccount) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Account.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_adverse_event.go b/backend/pkg/models/database/fhir_adverse_event.go
index c07d8e98b..d675c3565 100644
--- a/backend/pkg/models/database/fhir_adverse_event.go
+++ b/backend/pkg/models/database/fhir_adverse_event.go
@@ -66,11 +66,8 @@ type FhirAdverseEvent struct {
// https://hl7.org/fhir/r4/search.html#reference
Substance datatypes.JSON `gorm:"column:substance;type:text;serializer:json" json:"substance,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirAdverseEvent) GetSearchParameters() map[string]string {
@@ -98,8 +95,7 @@ func (s *FhirAdverseEvent) GetSearchParameters() map[string]string {
"study": "reference",
"subject": "reference",
"substance": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -153,14 +149,14 @@ func (s *FhirAdverseEvent) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AdverseEvent.date')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Event
@@ -181,14 +177,14 @@ func (s *FhirAdverseEvent) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -242,9 +238,9 @@ func (s *FhirAdverseEvent) PopulateAndExtractSearchParameters(resourceRaw json.R
s.Substance = []byte(substanceResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_allergy_intolerance.go b/backend/pkg/models/database/fhir_allergy_intolerance.go
index 6e1f922d0..10fde6c04 100644
--- a/backend/pkg/models/database/fhir_allergy_intolerance.go
+++ b/backend/pkg/models/database/fhir_allergy_intolerance.go
@@ -139,10 +139,19 @@ type FhirAllergyIntolerance struct {
// https://hl7.org/fhir/r4/search.html#token
Severity datatypes.JSON `gorm:"column:severity;type:text;serializer:json" json:"severity,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ /*
+ Multiple Resources:
+
+ * [AllergyIntolerance](allergyintolerance.html): allergy | intolerance - Underlying mechanism (if known)
+ * [Composition](composition.html): Kind of composition (LOINC if possible)
+ * [DocumentManifest](documentmanifest.html): Kind of document set
+ * [DocumentReference](documentreference.html): Kind of document (LOINC if possible)
+ * [Encounter](encounter.html): Specific type of encounter
+ * [EpisodeOfCare](episodeofcare.html): Type/class - e.g. specialist referral, disease management
+ */
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
// unconfirmed | confirmed | refuted | entered-in-error
// https://hl7.org/fhir/r4/search.html#token
@@ -175,8 +184,8 @@ func (s *FhirAllergyIntolerance) GetSearchParameters() map[string]string {
"source_resource_id": "keyword",
"source_resource_type": "keyword",
"source_uri": "keyword",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
"verificationStatus": "token",
}
return searchParameters
@@ -246,14 +255,14 @@ func (s *FhirAllergyIntolerance) PopulateAndExtractSearchParameters(resourceRaw
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -269,14 +278,14 @@ func (s *FhirAllergyIntolerance) PopulateAndExtractSearchParameters(resourceRaw
// extracting LastDate
lastDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.lastOccurrence')")
if err == nil && lastDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, lastDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, lastDateResult.String()); err == nil {
+ s.LastDate = &t
+ } else if t, err = time.Parse("2006-01-02", lastDateResult.String()); err == nil {
+ s.LastDate = &t
+ } else if t, err = time.Parse("2006-01", lastDateResult.String()); err == nil {
+ s.LastDate = &t
+ } else if t, err = time.Parse("2006", lastDateResult.String()); err == nil {
s.LastDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", lastDateResult.String())
- if err == nil {
- s.LastDate = &d
- }
}
}
// extracting Manifestation
@@ -287,14 +296,14 @@ func (s *FhirAllergyIntolerance) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -315,14 +324,14 @@ func (s *FhirAllergyIntolerance) PopulateAndExtractSearchParameters(resourceRaw
// extracting Onset
onsetResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.reaction.onset')")
if err == nil && onsetResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, onsetResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, onsetResult.String()); err == nil {
+ s.Onset = &t
+ } else if t, err = time.Parse("2006-01-02", onsetResult.String()); err == nil {
+ s.Onset = &t
+ } else if t, err = time.Parse("2006-01", onsetResult.String()); err == nil {
+ s.Onset = &t
+ } else if t, err = time.Parse("2006", onsetResult.String()); err == nil {
s.Onset = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", onsetResult.String())
- if err == nil {
- s.Onset = &d
- }
}
}
// extracting Recorder
@@ -341,9 +350,14 @@ func (s *FhirAllergyIntolerance) PopulateAndExtractSearchParameters(resourceRaw
s.Severity = []byte(severityResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.type | Composition.type | DocumentManifest.type | DocumentReference.type | Encounter.type | EpisodeOfCare.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
// extracting VerificationStatus
verificationStatusResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.verificationStatus')")
diff --git a/backend/pkg/models/database/fhir_allergy_intolerance_test.go b/backend/pkg/models/database/fhir_allergy_intolerance_test.go
new file mode 100644
index 000000000..584ba2588
--- /dev/null
+++ b/backend/pkg/models/database/fhir_allergy_intolerance_test.go
@@ -0,0 +1,221 @@
+package database
+
+import (
+ "encoding/json"
+ "github.com/stretchr/testify/require"
+ "os"
+ "testing"
+ "time"
+)
+
+func TestFhirAllergyIntolerance_ExtractSearchParameters(t *testing.T) {
+ t.Parallel()
+ //setup
+ //var observationJson map[string]interface{}
+ allergyIntoleranceBytes, err := os.ReadFile("../../../../frontend/src/lib/fixtures/r4/resources/allergyIntolerance/example1.json")
+ require.NoError(t, err)
+ //err = json.Unmarshal(allergyIntoleranceBytes, &observationJson)
+ //require.NoError(t, err)
+
+ //test
+ allergyIntoleranceModel := FhirAllergyIntolerance{}
+ err = allergyIntoleranceModel.PopulateAndExtractSearchParameters(allergyIntoleranceBytes)
+
+ //assert
+
+ var testClinicalStatus SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.ClinicalStatus), &testClinicalStatus)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "active",
+ Text: "Active",
+ System: "http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical",
+ },
+ }, testClinicalStatus)
+
+ var testVerificationStatus SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.VerificationStatus), &testVerificationStatus)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "confirmed",
+ Text: "Confirmed",
+ System: "http://terminology.hl7.org/CodeSystem/allergyintolerance-verification",
+ },
+ }, testVerificationStatus)
+
+ require.NotEmpty(t, allergyIntoleranceModel.Type)
+
+ var testType SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Type), &testType)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "allergy",
+ },
+ }, testType)
+
+ var testCategory SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Category), &testCategory)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "food",
+ },
+ }, testCategory)
+
+ var testCriticality SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Criticality), &testCriticality)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "high",
+ },
+ }, testCriticality)
+
+ var testCodeSystem SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Code), &testCodeSystem)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "227493005",
+ System: "http://snomed.info/sct",
+ Text: "Cashew nuts",
+ },
+ {
+ System: "http://www.nlm.nih.gov/research/umls/rxnorm",
+ Code: "1160593",
+ Text: "cashew nut allergenic extract Injectable Product",
+ },
+ }, testCodeSystem)
+
+ require.Equal(t, "2012-06-12T00:00:00Z", allergyIntoleranceModel.Onset.Format(time.RFC3339))
+
+ var testRecorder SearchParameterReferenceType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Recorder), &testRecorder)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterReferenceType{
+ {
+ Reference: "Practitioner/example",
+ },
+ }, testRecorder)
+
+ var testAsserter SearchParameterReferenceType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Asserter), &testAsserter)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterReferenceType{
+ {
+ Reference: "Patient/example",
+ },
+ }, testAsserter)
+
+ require.Equal(t, "2012-06", allergyIntoleranceModel.LastDate.Format("2006-01"))
+
+ var testSeverity SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Severity), &testSeverity)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "severe",
+ },
+ {
+ Code: "moderate",
+ },
+ }, testSeverity)
+
+ var testManifestation SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(allergyIntoleranceModel.Manifestation), &testManifestation)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ System: "http://snomed.info/sct",
+ Code: "39579001",
+ Text: "Anaphylactic reaction",
+ },
+ {
+ System: "http://snomed.info/sct",
+ Code: "64305001",
+ Text: "Urticaria",
+ },
+ }, testManifestation)
+}
+
+//func TestFhirAllergyIntolerance2_ExtractSearchParameters(t *testing.T) {
+// t.Parallel()
+// //setup
+// //var observationJson map[string]interface{}
+// conditionBytes, err := os.ReadFile("../../../../frontend/src/lib/fixtures/r4/resources/allergyIntolerance/example2.json")
+// require.NoError(t, err)
+// //err = json.Unmarshal(conditionBytes, &observationJson)
+// //require.NoError(t, err)
+//
+// //test
+// conditionModel := FhirCondition{}
+// err = conditionModel.PopulateAndExtractSearchParameters(conditionBytes)
+//
+// //assert
+//
+// var testClinicalStatus SearchParameterTokenType
+// require.NoError(t, err)
+// err = json.Unmarshal(json.RawMessage(conditionModel.ClinicalStatus), &testClinicalStatus)
+// require.NoError(t, err)
+// require.Equal(t, SearchParameterTokenType{
+// {
+// Code: "active",
+// System: "http://terminology.hl7.org/CodeSystem/condition-clinical",
+// },
+// }, testClinicalStatus)
+//
+// var testVerificationStatus SearchParameterTokenType
+// require.NoError(t, err)
+// err = json.Unmarshal(json.RawMessage(conditionModel.VerificationStatus), &testVerificationStatus)
+// require.NoError(t, err)
+// require.Equal(t, SearchParameterTokenType{
+// {
+// Code: "confirmed",
+// System: "http://terminology.hl7.org/CodeSystem/condition-ver-status",
+// },
+// }, testVerificationStatus)
+//
+// var testCategory SearchParameterTokenType
+// require.NoError(t, err)
+// err = json.Unmarshal(json.RawMessage(conditionModel.Category), &testCategory)
+// require.NoError(t, err)
+// require.Equal(t, SearchParameterTokenType{
+// {
+// Code: "problem-list-item",
+// System: "http://terminology.hl7.org/CodeSystem/condition-category",
+// Text: "Problem List Item",
+// },
+// }, testCategory)
+//
+// var testSeverity SearchParameterTokenType
+// require.NoError(t, err)
+// err = json.Unmarshal(json.RawMessage(conditionModel.Severity), &testSeverity)
+// require.NoError(t, err)
+// require.Equal(t, SearchParameterTokenType{
+// {
+// Code: "255604002",
+// System: "http://snomed.info/sct",
+// Text: "Mild",
+// },
+// }, testSeverity)
+//
+// var testOnsetInfo SearchParameterStringType
+// err = json.Unmarshal(json.RawMessage(conditionModel.OnsetInfo), &testOnsetInfo)
+// require.NoError(t, err)
+//
+// require.Equal(t, SearchParameterStringType{"approximately November 2012"}, testOnsetInfo)
+//
+//}
diff --git a/backend/pkg/models/database/fhir_appointment.go b/backend/pkg/models/database/fhir_appointment.go
index 43712266a..8b38a3974 100644
--- a/backend/pkg/models/database/fhir_appointment.go
+++ b/backend/pkg/models/database/fhir_appointment.go
@@ -78,11 +78,8 @@ type FhirAppointment struct {
// https://hl7.org/fhir/r4/search.html#reference
SupportingInfo datatypes.JSON `gorm:"column:supportingInfo;type:text;serializer:json" json:"supportingInfo,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirAppointment) GetSearchParameters() map[string]string {
@@ -114,8 +111,7 @@ func (s *FhirAppointment) GetSearchParameters() map[string]string {
"specialty": "token",
"status": "token",
"supportingInfo": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -174,14 +170,14 @@ func (s *FhirAppointment) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Appointment.start')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -202,14 +198,14 @@ func (s *FhirAppointment) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -278,9 +274,9 @@ func (s *FhirAppointment) PopulateAndExtractSearchParameters(resourceRaw json.Ra
s.SupportingInfo = []byte(supportingInfoResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_binary.go b/backend/pkg/models/database/fhir_binary.go
index ca8bb93b3..b1128462f 100644
--- a/backend/pkg/models/database/fhir_binary.go
+++ b/backend/pkg/models/database/fhir_binary.go
@@ -30,11 +30,8 @@ type FhirBinary struct {
// This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
MetaVersionId string `gorm:"column:metaVersionId;type:text" json:"metaVersionId,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirBinary) GetSearchParameters() map[string]string {
@@ -50,8 +47,7 @@ func (s *FhirBinary) GetSearchParameters() map[string]string {
"source_resource_id": "keyword",
"source_resource_type": "keyword",
"source_uri": "keyword",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -100,14 +96,14 @@ func (s *FhirBinary) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -126,9 +122,9 @@ func (s *FhirBinary) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
s.MetaVersionId = metaVersionIdResult.String()
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_care_plan.go b/backend/pkg/models/database/fhir_care_plan.go
index 147ae955d..a03c4ca3c 100644
--- a/backend/pkg/models/database/fhir_care_plan.go
+++ b/backend/pkg/models/database/fhir_care_plan.go
@@ -140,11 +140,8 @@ type FhirCarePlan struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirCarePlan) GetSearchParameters() map[string]string {
@@ -179,8 +176,7 @@ func (s *FhirCarePlan) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -229,14 +225,14 @@ func (s *FhirCarePlan) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting ActivityDate
activityDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'CarePlan.activity.detail.scheduledTiming | CarePlan.activity.detail.scheduledPeriod | CarePlan.activity.detail.scheduledString')")
if err == nil && activityDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, activityDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, activityDateResult.String()); err == nil {
+ s.ActivityDate = &t
+ } else if t, err = time.Parse("2006-01-02", activityDateResult.String()); err == nil {
+ s.ActivityDate = &t
+ } else if t, err = time.Parse("2006-01", activityDateResult.String()); err == nil {
+ s.ActivityDate = &t
+ } else if t, err = time.Parse("2006", activityDateResult.String()); err == nil {
s.ActivityDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", activityDateResult.String())
- if err == nil {
- s.ActivityDate = &d
- }
}
}
// extracting ActivityReference
@@ -267,14 +263,14 @@ func (s *FhirCarePlan) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -315,14 +311,14 @@ func (s *FhirCarePlan) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -366,9 +362,9 @@ func (s *FhirCarePlan) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_care_plan_test.go b/backend/pkg/models/database/fhir_care_plan_test.go
new file mode 100644
index 000000000..a9ad23321
--- /dev/null
+++ b/backend/pkg/models/database/fhir_care_plan_test.go
@@ -0,0 +1,80 @@
+package database
+
+import (
+ "encoding/json"
+ "github.com/stretchr/testify/require"
+ "os"
+ "testing"
+ "time"
+)
+
+func TestFhirCarePlan_ExtractSearchParameters(t *testing.T) {
+ t.Parallel()
+ //setup
+ carePlanBytes, err := os.ReadFile("../../../../frontend/src/lib/fixtures/r4/resources/carePlan/heartOperationPlan.json")
+ require.NoError(t, err)
+ //test
+ carePlanModel := FhirCarePlan{}
+ err = carePlanModel.PopulateAndExtractSearchParameters(carePlanBytes)
+
+ //assert
+
+ var testActivityCode SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(carePlanModel.ActivityCode), &testActivityCode)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ System: "http://snomed.info/sct",
+ Code: "64915003",
+ Text: "Operation on heart",
+ },
+ }, testActivityCode)
+
+ require.Equal(t, "2011-06-27T09:30:10+01:00", carePlanModel.ActivityDate.Format(time.RFC3339))
+
+ var testCareTeam SearchParameterReferenceType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(carePlanModel.CareTeam), &testCareTeam)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterReferenceType{
+ {
+ Reference: "#careteam",
+ },
+ }, testCareTeam)
+
+ require.Nil(t, carePlanModel.Category)
+
+ var testCondition SearchParameterReferenceType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(carePlanModel.Condition), &testCondition)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterReferenceType{
+ {
+ Reference: "Condition/f201",
+ Display: "?????",
+ },
+ }, testCondition)
+
+ require.Equal(t, "2011-06-26T00:00:00Z", carePlanModel.Date.Format(time.RFC3339)) //TODO date periods are not handled correctly
+
+ var testGoal SearchParameterReferenceType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(carePlanModel.Goal), &testGoal)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterReferenceType{
+ {
+ Reference: "#goal",
+ },
+ }, testGoal)
+
+ var testIntent SearchParameterTokenType
+ require.NoError(t, err)
+ err = json.Unmarshal(json.RawMessage(carePlanModel.Intent), &testIntent)
+ require.NoError(t, err)
+ require.Equal(t, SearchParameterTokenType{
+ {
+ Code: "plan",
+ },
+ }, testIntent)
+}
diff --git a/backend/pkg/models/database/fhir_care_team.go b/backend/pkg/models/database/fhir_care_team.go
index 621f7ab06..c0e2e63cd 100644
--- a/backend/pkg/models/database/fhir_care_team.go
+++ b/backend/pkg/models/database/fhir_care_team.go
@@ -104,11 +104,8 @@ type FhirCareTeam struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirCareTeam) GetSearchParameters() map[string]string {
@@ -131,8 +128,7 @@ func (s *FhirCareTeam) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -181,14 +177,14 @@ func (s *FhirCareTeam) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -209,14 +205,14 @@ func (s *FhirCareTeam) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -250,9 +246,9 @@ func (s *FhirCareTeam) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_claim.go b/backend/pkg/models/database/fhir_claim.go
index 5db75b896..e04c25062 100644
--- a/backend/pkg/models/database/fhir_claim.go
+++ b/backend/pkg/models/database/fhir_claim.go
@@ -75,11 +75,8 @@ type FhirClaim struct {
// https://hl7.org/fhir/r4/search.html#reference
SubdetailUdi datatypes.JSON `gorm:"column:subdetailUdi;type:text;serializer:json" json:"subdetailUdi,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// The kind of financial resource
// https://hl7.org/fhir/r4/search.html#token
Use datatypes.JSON `gorm:"column:use;type:text;serializer:json" json:"use,omitempty"`
@@ -113,8 +110,7 @@ func (s *FhirClaim) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subdetailUdi": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"use": "token",
}
return searchParameters
@@ -164,14 +160,14 @@ func (s *FhirClaim) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Claim.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting DetailUdi
@@ -217,14 +213,14 @@ func (s *FhirClaim) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -273,9 +269,9 @@ func (s *FhirClaim) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
s.SubdetailUdi = []byte(subdetailUdiResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting Use
useResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Claim.use')")
diff --git a/backend/pkg/models/database/fhir_claim_response.go b/backend/pkg/models/database/fhir_claim_response.go
index ae5cfae3d..0d5f096d5 100644
--- a/backend/pkg/models/database/fhir_claim_response.go
+++ b/backend/pkg/models/database/fhir_claim_response.go
@@ -57,11 +57,8 @@ type FhirClaimResponse struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// The type of claim
// https://hl7.org/fhir/r4/search.html#token
Use datatypes.JSON `gorm:"column:use;type:text;serializer:json" json:"use,omitempty"`
@@ -89,8 +86,7 @@ func (s *FhirClaimResponse) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"use": "token",
}
return searchParameters
@@ -135,14 +131,14 @@ func (s *FhirClaimResponse) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ClaimResponse.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting Disposition
@@ -168,14 +164,14 @@ func (s *FhirClaimResponse) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -201,14 +197,14 @@ func (s *FhirClaimResponse) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting PaymentDate
paymentDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ClaimResponse.payment.date')")
if err == nil && paymentDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, paymentDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, paymentDateResult.String()); err == nil {
+ s.PaymentDate = &t
+ } else if t, err = time.Parse("2006-01-02", paymentDateResult.String()); err == nil {
+ s.PaymentDate = &t
+ } else if t, err = time.Parse("2006-01", paymentDateResult.String()); err == nil {
+ s.PaymentDate = &t
+ } else if t, err = time.Parse("2006", paymentDateResult.String()); err == nil {
s.PaymentDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", paymentDateResult.String())
- if err == nil {
- s.PaymentDate = &d
- }
}
}
// extracting Request
@@ -227,9 +223,9 @@ func (s *FhirClaimResponse) PopulateAndExtractSearchParameters(resourceRaw json.
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting Use
useResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'ClaimResponse.use')")
diff --git a/backend/pkg/models/database/fhir_composition.go b/backend/pkg/models/database/fhir_composition.go
index 983294142..482175d73 100644
--- a/backend/pkg/models/database/fhir_composition.go
+++ b/backend/pkg/models/database/fhir_composition.go
@@ -143,13 +143,22 @@ type FhirComposition struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// Human Readable name/title
// https://hl7.org/fhir/r4/search.html#string
Title datatypes.JSON `gorm:"column:title;type:text;serializer:json" json:"title,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ /*
+ Multiple Resources:
+
+ * [AllergyIntolerance](allergyintolerance.html): allergy | intolerance - Underlying mechanism (if known)
+ * [Composition](composition.html): Kind of composition (LOINC if possible)
+ * [DocumentManifest](documentmanifest.html): Kind of document set
+ * [DocumentReference](documentreference.html): Kind of document (LOINC if possible)
+ * [Encounter](encounter.html): Specific type of encounter
+ * [EpisodeOfCare](episodeofcare.html): Type/class - e.g. specialist referral, disease management
+ */
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -181,9 +190,9 @@ func (s *FhirComposition) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
+ "text": "string",
"title": "string",
- "type": "special",
+ "type": "token",
}
return searchParameters
}
@@ -252,14 +261,14 @@ func (s *FhirComposition) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -285,14 +294,14 @@ func (s *FhirComposition) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -313,14 +322,14 @@ func (s *FhirComposition) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting Period
periodResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Composition.event.period')")
if err == nil && periodResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, periodResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01-02", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006", periodResult.String()); err == nil {
s.Period = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", periodResult.String())
- if err == nil {
- s.Period = &d
- }
}
}
// extracting RelatedId
@@ -349,15 +358,20 @@ func (s *FhirComposition) PopulateAndExtractSearchParameters(resourceRaw json.Ra
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting Title
titleResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'Composition.title')")
if err == nil && titleResult.String() != "undefined" {
s.Title = []byte(titleResult.String())
}
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.type | Composition.type | DocumentManifest.type | DocumentReference.type | Encounter.type | EpisodeOfCare.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
+ }
return nil
}
diff --git a/backend/pkg/models/database/fhir_condition.go b/backend/pkg/models/database/fhir_condition.go
index 12a01068a..30285808b 100644
--- a/backend/pkg/models/database/fhir_condition.go
+++ b/backend/pkg/models/database/fhir_condition.go
@@ -137,11 +137,8 @@ type FhirCondition struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// unconfirmed | provisional | differential | confirmed | refuted | entered-in-error
// https://hl7.org/fhir/r4/search.html#token
VerificationStatus datatypes.JSON `gorm:"column:verificationStatus;type:text;serializer:json" json:"verificationStatus,omitempty"`
@@ -179,8 +176,7 @@ func (s *FhirCondition) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"stage": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"verificationStatus": "token",
}
return searchParameters
@@ -230,14 +226,14 @@ func (s *FhirCondition) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting AbatementDate
abatementDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Condition.abatementDateTime | Condition.abatementPeriod')")
if err == nil && abatementDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, abatementDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, abatementDateResult.String()); err == nil {
+ s.AbatementDate = &t
+ } else if t, err = time.Parse("2006-01-02", abatementDateResult.String()); err == nil {
+ s.AbatementDate = &t
+ } else if t, err = time.Parse("2006-01", abatementDateResult.String()); err == nil {
+ s.AbatementDate = &t
+ } else if t, err = time.Parse("2006", abatementDateResult.String()); err == nil {
s.AbatementDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", abatementDateResult.String())
- if err == nil {
- s.AbatementDate = &d
- }
}
}
// extracting AbatementString
@@ -298,14 +294,14 @@ func (s *FhirCondition) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -331,14 +327,14 @@ func (s *FhirCondition) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting OnsetDate
onsetDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Condition.onsetDateTime | Condition.onsetPeriod')")
if err == nil && onsetDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, onsetDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, onsetDateResult.String()); err == nil {
+ s.OnsetDate = &t
+ } else if t, err = time.Parse("2006-01-02", onsetDateResult.String()); err == nil {
+ s.OnsetDate = &t
+ } else if t, err = time.Parse("2006-01", onsetDateResult.String()); err == nil {
+ s.OnsetDate = &t
+ } else if t, err = time.Parse("2006", onsetDateResult.String()); err == nil {
s.OnsetDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", onsetDateResult.String())
- if err == nil {
- s.OnsetDate = &d
- }
}
}
// extracting OnsetInfo
@@ -349,14 +345,14 @@ func (s *FhirCondition) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting RecordedDate
recordedDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Condition.recordedDate')")
if err == nil && recordedDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, recordedDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, recordedDateResult.String()); err == nil {
+ s.RecordedDate = &t
+ } else if t, err = time.Parse("2006-01-02", recordedDateResult.String()); err == nil {
+ s.RecordedDate = &t
+ } else if t, err = time.Parse("2006-01", recordedDateResult.String()); err == nil {
+ s.RecordedDate = &t
+ } else if t, err = time.Parse("2006", recordedDateResult.String()); err == nil {
s.RecordedDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", recordedDateResult.String())
- if err == nil {
- s.RecordedDate = &d
- }
}
}
// extracting Severity
@@ -375,9 +371,9 @@ func (s *FhirCondition) PopulateAndExtractSearchParameters(resourceRaw json.RawM
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting VerificationStatus
verificationStatusResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Condition.verificationStatus')")
diff --git a/backend/pkg/models/database/fhir_consent.go b/backend/pkg/models/database/fhir_consent.go
index 9136b58c4..d85668c6b 100644
--- a/backend/pkg/models/database/fhir_consent.go
+++ b/backend/pkg/models/database/fhir_consent.go
@@ -125,11 +125,8 @@ type FhirConsent struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirConsent) GetSearchParameters() map[string]string {
@@ -159,8 +156,7 @@ func (s *FhirConsent) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -229,14 +225,14 @@ func (s *FhirConsent) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -252,14 +248,14 @@ func (s *FhirConsent) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -285,14 +281,14 @@ func (s *FhirConsent) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting Period
periodResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Consent.provision.period')")
if err == nil && periodResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, periodResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01-02", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006", periodResult.String()); err == nil {
s.Period = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", periodResult.String())
- if err == nil {
- s.Period = &d
- }
}
}
// extracting Purpose
@@ -321,9 +317,9 @@ func (s *FhirConsent) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_coverage.go b/backend/pkg/models/database/fhir_coverage.go
index 2cf3d493d..d34c3ed9e 100644
--- a/backend/pkg/models/database/fhir_coverage.go
+++ b/backend/pkg/models/database/fhir_coverage.go
@@ -57,10 +57,10 @@ type FhirCoverage struct {
// https://hl7.org/fhir/r4/search.html#reference
Subscriber datatypes.JSON `gorm:"column:subscriber;type:text;serializer:json" json:"subscriber,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // The kind of coverage (health plan, auto, Workers Compensation)
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -86,8 +86,8 @@ func (s *FhirCoverage) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subscriber": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -161,14 +161,14 @@ func (s *FhirCoverage) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -207,9 +207,14 @@ func (s *FhirCoverage) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Subscriber = []byte(subscriberResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Coverage.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_coverage_eligibility_request.go b/backend/pkg/models/database/fhir_coverage_eligibility_request.go
index 2e52f7025..fdec2eb5e 100644
--- a/backend/pkg/models/database/fhir_coverage_eligibility_request.go
+++ b/backend/pkg/models/database/fhir_coverage_eligibility_request.go
@@ -48,11 +48,8 @@ type FhirCoverageEligibilityRequest struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirCoverageEligibilityRequest) GetSearchParameters() map[string]string {
@@ -74,8 +71,7 @@ func (s *FhirCoverageEligibilityRequest) GetSearchParameters() map[string]string
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -119,14 +115,14 @@ func (s *FhirCoverageEligibilityRequest) PopulateAndExtractSearchParameters(reso
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'CoverageEligibilityRequest.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting Enterer
@@ -152,14 +148,14 @@ func (s *FhirCoverageEligibilityRequest) PopulateAndExtractSearchParameters(reso
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -188,9 +184,9 @@ func (s *FhirCoverageEligibilityRequest) PopulateAndExtractSearchParameters(reso
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_coverage_eligibility_response.go b/backend/pkg/models/database/fhir_coverage_eligibility_response.go
index afb6dcbec..139e708fd 100644
--- a/backend/pkg/models/database/fhir_coverage_eligibility_response.go
+++ b/backend/pkg/models/database/fhir_coverage_eligibility_response.go
@@ -54,11 +54,8 @@ type FhirCoverageEligibilityResponse struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirCoverageEligibilityResponse) GetSearchParameters() map[string]string {
@@ -82,8 +79,7 @@ func (s *FhirCoverageEligibilityResponse) GetSearchParameters() map[string]strin
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -127,14 +123,14 @@ func (s *FhirCoverageEligibilityResponse) PopulateAndExtractSearchParameters(res
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'CoverageEligibilityResponse.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting Disposition
@@ -160,14 +156,14 @@ func (s *FhirCoverageEligibilityResponse) PopulateAndExtractSearchParameters(res
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -206,9 +202,9 @@ func (s *FhirCoverageEligibilityResponse) PopulateAndExtractSearchParameters(res
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_device.go b/backend/pkg/models/database/fhir_device.go
index f765bb05e..c07443642 100644
--- a/backend/pkg/models/database/fhir_device.go
+++ b/backend/pkg/models/database/fhir_device.go
@@ -51,10 +51,10 @@ type FhirDevice struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // The type of the device
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
// UDI Barcode (RFID or other technology) string in *HRF* format.
// https://hl7.org/fhir/r4/search.html#string
@@ -87,8 +87,8 @@ func (s *FhirDevice) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
"udiCarrier": "string",
"udiDi": "string",
"url": "uri",
@@ -160,14 +160,14 @@ func (s *FhirDevice) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -201,9 +201,14 @@ func (s *FhirDevice) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Device.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
// extracting UdiCarrier
udiCarrierResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'Device.udiCarrier.carrierHRF')")
diff --git a/backend/pkg/models/database/fhir_device_request.go b/backend/pkg/models/database/fhir_device_request.go
index 0633c5cf7..c4ae5eef4 100644
--- a/backend/pkg/models/database/fhir_device_request.go
+++ b/backend/pkg/models/database/fhir_device_request.go
@@ -146,11 +146,8 @@ type FhirDeviceRequest struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirDeviceRequest) GetSearchParameters() map[string]string {
@@ -183,8 +180,7 @@ func (s *FhirDeviceRequest) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -228,14 +224,14 @@ func (s *FhirDeviceRequest) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting AuthoredOn
authoredOnResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'DeviceRequest.authoredOn')")
if err == nil && authoredOnResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, authoredOnResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, authoredOnResult.String()); err == nil {
+ s.AuthoredOn = &t
+ } else if t, err = time.Parse("2006-01-02", authoredOnResult.String()); err == nil {
+ s.AuthoredOn = &t
+ } else if t, err = time.Parse("2006-01", authoredOnResult.String()); err == nil {
+ s.AuthoredOn = &t
+ } else if t, err = time.Parse("2006", authoredOnResult.String()); err == nil {
s.AuthoredOn = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", authoredOnResult.String())
- if err == nil {
- s.AuthoredOn = &d
- }
}
}
// extracting BasedOn
@@ -261,14 +257,14 @@ func (s *FhirDeviceRequest) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting EventDate
eventDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(DeviceRequest.occurrenceDateTime) | (DeviceRequest.occurrencePeriod)')")
if err == nil && eventDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, eventDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, eventDateResult.String()); err == nil {
+ s.EventDate = &t
+ } else if t, err = time.Parse("2006-01-02", eventDateResult.String()); err == nil {
+ s.EventDate = &t
+ } else if t, err = time.Parse("2006-01", eventDateResult.String()); err == nil {
+ s.EventDate = &t
+ } else if t, err = time.Parse("2006", eventDateResult.String()); err == nil {
s.EventDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", eventDateResult.String())
- if err == nil {
- s.EventDate = &d
- }
}
}
// extracting GroupIdentifier
@@ -309,14 +305,14 @@ func (s *FhirDeviceRequest) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -360,9 +356,9 @@ func (s *FhirDeviceRequest) PopulateAndExtractSearchParameters(resourceRaw json.
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_diagnostic_report.go b/backend/pkg/models/database/fhir_diagnostic_report.go
index 36fee3576..f9a4e34bf 100644
--- a/backend/pkg/models/database/fhir_diagnostic_report.go
+++ b/backend/pkg/models/database/fhir_diagnostic_report.go
@@ -160,11 +160,8 @@ type FhirDiagnosticReport struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirDiagnosticReport) GetSearchParameters() map[string]string {
@@ -195,8 +192,7 @@ func (s *FhirDiagnosticReport) GetSearchParameters() map[string]string {
"specimen": "reference",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -260,14 +256,14 @@ func (s *FhirDiagnosticReport) PopulateAndExtractSearchParameters(resourceRaw js
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -283,14 +279,14 @@ func (s *FhirDiagnosticReport) PopulateAndExtractSearchParameters(resourceRaw js
// extracting Issued
issuedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'DiagnosticReport.issued')")
if err == nil && issuedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, issuedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, issuedResult.String()); err == nil {
+ s.Issued = &t
+ } else if t, err = time.Parse("2006-01-02", issuedResult.String()); err == nil {
+ s.Issued = &t
+ } else if t, err = time.Parse("2006-01", issuedResult.String()); err == nil {
+ s.Issued = &t
+ } else if t, err = time.Parse("2006", issuedResult.String()); err == nil {
s.Issued = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", issuedResult.String())
- if err == nil {
- s.Issued = &d
- }
}
}
// extracting Language
@@ -306,14 +302,14 @@ func (s *FhirDiagnosticReport) PopulateAndExtractSearchParameters(resourceRaw js
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -362,9 +358,9 @@ func (s *FhirDiagnosticReport) PopulateAndExtractSearchParameters(resourceRaw js
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_document_manifest.go b/backend/pkg/models/database/fhir_document_manifest.go
index 92ae48fa4..0d3612522 100644
--- a/backend/pkg/models/database/fhir_document_manifest.go
+++ b/backend/pkg/models/database/fhir_document_manifest.go
@@ -96,10 +96,19 @@ type FhirDocumentManifest struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ /*
+ Multiple Resources:
+
+ * [AllergyIntolerance](allergyintolerance.html): allergy | intolerance - Underlying mechanism (if known)
+ * [Composition](composition.html): Kind of composition (LOINC if possible)
+ * [DocumentManifest](documentmanifest.html): Kind of document set
+ * [DocumentReference](documentreference.html): Kind of document (LOINC if possible)
+ * [Encounter](encounter.html): Specific type of encounter
+ * [EpisodeOfCare](episodeofcare.html): Type/class - e.g. specialist referral, disease management
+ */
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -127,8 +136,8 @@ func (s *FhirDocumentManifest) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -177,14 +186,14 @@ func (s *FhirDocumentManifest) PopulateAndExtractSearchParameters(resourceRaw js
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'DocumentManifest.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting Description
@@ -210,14 +219,14 @@ func (s *FhirDocumentManifest) PopulateAndExtractSearchParameters(resourceRaw js
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -266,9 +275,14 @@ func (s *FhirDocumentManifest) PopulateAndExtractSearchParameters(resourceRaw js
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.type | Composition.type | DocumentManifest.type | DocumentReference.type | Encounter.type | EpisodeOfCare.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_document_reference.go b/backend/pkg/models/database/fhir_document_reference.go
index a9f9e42fb..4fe59ef0f 100644
--- a/backend/pkg/models/database/fhir_document_reference.go
+++ b/backend/pkg/models/database/fhir_document_reference.go
@@ -141,10 +141,19 @@ type FhirDocumentReference struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ /*
+ Multiple Resources:
+
+ * [AllergyIntolerance](allergyintolerance.html): allergy | intolerance - Underlying mechanism (if known)
+ * [Composition](composition.html): Kind of composition (LOINC if possible)
+ * [DocumentManifest](documentmanifest.html): Kind of document set
+ * [DocumentReference](documentreference.html): Kind of document (LOINC if possible)
+ * [Encounter](encounter.html): Specific type of encounter
+ * [EpisodeOfCare](episodeofcare.html): Type/class - e.g. specialist referral, disease management
+ */
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -182,8 +191,8 @@ func (s *FhirDocumentReference) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -252,14 +261,14 @@ func (s *FhirDocumentReference) PopulateAndExtractSearchParameters(resourceRaw j
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'DocumentReference.date')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Description
@@ -305,14 +314,14 @@ func (s *FhirDocumentReference) PopulateAndExtractSearchParameters(resourceRaw j
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -333,14 +342,14 @@ func (s *FhirDocumentReference) PopulateAndExtractSearchParameters(resourceRaw j
// extracting Period
periodResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'DocumentReference.context.period')")
if err == nil && periodResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, periodResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01-02", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006-01", periodResult.String()); err == nil {
+ s.Period = &t
+ } else if t, err = time.Parse("2006", periodResult.String()); err == nil {
s.Period = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", periodResult.String())
- if err == nil {
- s.Period = &d
- }
}
}
// extracting Related
@@ -379,9 +388,14 @@ func (s *FhirDocumentReference) PopulateAndExtractSearchParameters(resourceRaw j
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.type | Composition.type | DocumentManifest.type | DocumentReference.type | Encounter.type | EpisodeOfCare.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_encounter.go b/backend/pkg/models/database/fhir_encounter.go
index 430202af9..0ebdc0429 100644
--- a/backend/pkg/models/database/fhir_encounter.go
+++ b/backend/pkg/models/database/fhir_encounter.go
@@ -146,10 +146,19 @@ type FhirEncounter struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ /*
+ Multiple Resources:
+
+ * [AllergyIntolerance](allergyintolerance.html): allergy | intolerance - Underlying mechanism (if known)
+ * [Composition](composition.html): Kind of composition (LOINC if possible)
+ * [DocumentManifest](documentmanifest.html): Kind of document set
+ * [DocumentReference](documentreference.html): Kind of document (LOINC if possible)
+ * [Encounter](encounter.html): Specific type of encounter
+ * [EpisodeOfCare](episodeofcare.html): Type/class - e.g. specialist referral, disease management
+ */
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -187,8 +196,8 @@ func (s *FhirEncounter) GetSearchParameters() map[string]string {
"specialArrangement": "token",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -252,14 +261,14 @@ func (s *FhirEncounter) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Diagnosis
@@ -295,27 +304,27 @@ func (s *FhirEncounter) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting LocationPeriod
locationPeriodResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Encounter.location.period')")
if err == nil && locationPeriodResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, locationPeriodResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, locationPeriodResult.String()); err == nil {
+ s.LocationPeriod = &t
+ } else if t, err = time.Parse("2006-01-02", locationPeriodResult.String()); err == nil {
+ s.LocationPeriod = &t
+ } else if t, err = time.Parse("2006-01", locationPeriodResult.String()); err == nil {
+ s.LocationPeriod = &t
+ } else if t, err = time.Parse("2006", locationPeriodResult.String()); err == nil {
s.LocationPeriod = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", locationPeriodResult.String())
- if err == nil {
- s.LocationPeriod = &d
- }
}
}
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -384,9 +393,14 @@ func (s *FhirEncounter) PopulateAndExtractSearchParameters(resourceRaw json.RawM
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'AllergyIntolerance.type | Composition.type | DocumentManifest.type | DocumentReference.type | Encounter.type | EpisodeOfCare.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_endpoint.go b/backend/pkg/models/database/fhir_endpoint.go
index 372951146..fcd1f3fc5 100644
--- a/backend/pkg/models/database/fhir_endpoint.go
+++ b/backend/pkg/models/database/fhir_endpoint.go
@@ -48,11 +48,8 @@ type FhirEndpoint struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirEndpoint) GetSearchParameters() map[string]string {
@@ -74,8 +71,7 @@ func (s *FhirEndpoint) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -134,14 +130,14 @@ func (s *FhirEndpoint) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -180,9 +176,9 @@ func (s *FhirEndpoint) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_enrollment_request.go b/backend/pkg/models/database/fhir_enrollment_request.go
index 36aa152be..e8bae5209 100644
--- a/backend/pkg/models/database/fhir_enrollment_request.go
+++ b/backend/pkg/models/database/fhir_enrollment_request.go
@@ -39,11 +39,8 @@ type FhirEnrollmentRequest struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirEnrollmentRequest) GetSearchParameters() map[string]string {
@@ -62,8 +59,7 @@ func (s *FhirEnrollmentRequest) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -117,14 +113,14 @@ func (s *FhirEnrollmentRequest) PopulateAndExtractSearchParameters(resourceRaw j
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -153,9 +149,9 @@ func (s *FhirEnrollmentRequest) PopulateAndExtractSearchParameters(resourceRaw j
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_enrollment_response.go b/backend/pkg/models/database/fhir_enrollment_response.go
index 1aae1f250..411b19584 100644
--- a/backend/pkg/models/database/fhir_enrollment_response.go
+++ b/backend/pkg/models/database/fhir_enrollment_response.go
@@ -39,11 +39,8 @@ type FhirEnrollmentResponse struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirEnrollmentResponse) GetSearchParameters() map[string]string {
@@ -62,8 +59,7 @@ func (s *FhirEnrollmentResponse) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -117,14 +113,14 @@ func (s *FhirEnrollmentResponse) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -153,9 +149,9 @@ func (s *FhirEnrollmentResponse) PopulateAndExtractSearchParameters(resourceRaw
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_explanation_of_benefit.go b/backend/pkg/models/database/fhir_explanation_of_benefit.go
index a4a0c23d8..4beee3eb9 100644
--- a/backend/pkg/models/database/fhir_explanation_of_benefit.go
+++ b/backend/pkg/models/database/fhir_explanation_of_benefit.go
@@ -78,11 +78,8 @@ type FhirExplanationOfBenefit struct {
// https://hl7.org/fhir/r4/search.html#reference
SubdetailUdi datatypes.JSON `gorm:"column:subdetailUdi;type:text;serializer:json" json:"subdetailUdi,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirExplanationOfBenefit) GetSearchParameters() map[string]string {
@@ -114,8 +111,7 @@ func (s *FhirExplanationOfBenefit) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subdetailUdi": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -174,14 +170,14 @@ func (s *FhirExplanationOfBenefit) PopulateAndExtractSearchParameters(resourceRa
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ExplanationOfBenefit.created')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting DetailUdi
@@ -227,14 +223,14 @@ func (s *FhirExplanationOfBenefit) PopulateAndExtractSearchParameters(resourceRa
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -278,9 +274,9 @@ func (s *FhirExplanationOfBenefit) PopulateAndExtractSearchParameters(resourceRa
s.SubdetailUdi = []byte(subdetailUdiResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_family_member_history.go b/backend/pkg/models/database/fhir_family_member_history.go
index fe2a17bff..b165f9ef3 100644
--- a/backend/pkg/models/database/fhir_family_member_history.go
+++ b/backend/pkg/models/database/fhir_family_member_history.go
@@ -124,11 +124,8 @@ type FhirFamilyMemberHistory struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirFamilyMemberHistory) GetSearchParameters() map[string]string {
@@ -152,8 +149,7 @@ func (s *FhirFamilyMemberHistory) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -202,14 +198,14 @@ func (s *FhirFamilyMemberHistory) PopulateAndExtractSearchParameters(resourceRaw
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -235,14 +231,14 @@ func (s *FhirFamilyMemberHistory) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -276,9 +272,9 @@ func (s *FhirFamilyMemberHistory) PopulateAndExtractSearchParameters(resourceRaw
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_goal.go b/backend/pkg/models/database/fhir_goal.go
index e01165f6d..1a33e70f4 100644
--- a/backend/pkg/models/database/fhir_goal.go
+++ b/backend/pkg/models/database/fhir_goal.go
@@ -84,11 +84,8 @@ type FhirGoal struct {
// https://hl7.org/fhir/r4/search.html#date
TargetDate *time.Time `gorm:"column:targetDate;type:datetime" json:"targetDate,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirGoal) GetSearchParameters() map[string]string {
@@ -111,8 +108,7 @@ func (s *FhirGoal) GetSearchParameters() map[string]string {
"startDate": "date",
"subject": "reference",
"targetDate": "date",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -181,14 +177,14 @@ func (s *FhirGoal) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -209,14 +205,14 @@ func (s *FhirGoal) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
// extracting StartDate
startDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(Goal.startDate)')")
if err == nil && startDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, startDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, startDateResult.String()); err == nil {
+ s.StartDate = &t
+ } else if t, err = time.Parse("2006-01-02", startDateResult.String()); err == nil {
+ s.StartDate = &t
+ } else if t, err = time.Parse("2006-01", startDateResult.String()); err == nil {
+ s.StartDate = &t
+ } else if t, err = time.Parse("2006", startDateResult.String()); err == nil {
s.StartDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", startDateResult.String())
- if err == nil {
- s.StartDate = &d
- }
}
}
// extracting Subject
@@ -227,20 +223,20 @@ func (s *FhirGoal) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
// extracting TargetDate
targetDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(Goal.target.dueDate)')")
if err == nil && targetDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, targetDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, targetDateResult.String()); err == nil {
+ s.TargetDate = &t
+ } else if t, err = time.Parse("2006-01-02", targetDateResult.String()); err == nil {
+ s.TargetDate = &t
+ } else if t, err = time.Parse("2006-01", targetDateResult.String()); err == nil {
+ s.TargetDate = &t
+ } else if t, err = time.Parse("2006", targetDateResult.String()); err == nil {
s.TargetDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", targetDateResult.String())
- if err == nil {
- s.TargetDate = &d
- }
}
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_imaging_study.go b/backend/pkg/models/database/fhir_imaging_study.go
index b2127e354..fd7de4b20 100644
--- a/backend/pkg/models/database/fhir_imaging_study.go
+++ b/backend/pkg/models/database/fhir_imaging_study.go
@@ -111,11 +111,8 @@ type FhirImagingStudy struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirImagingStudy) GetSearchParameters() map[string]string {
@@ -147,8 +144,7 @@ func (s *FhirImagingStudy) GetSearchParameters() map[string]string {
"started": "date",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -237,14 +233,14 @@ func (s *FhirImagingStudy) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -290,14 +286,14 @@ func (s *FhirImagingStudy) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting Started
startedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ImagingStudy.started')")
if err == nil && startedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, startedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, startedResult.String()); err == nil {
+ s.Started = &t
+ } else if t, err = time.Parse("2006-01-02", startedResult.String()); err == nil {
+ s.Started = &t
+ } else if t, err = time.Parse("2006-01", startedResult.String()); err == nil {
+ s.Started = &t
+ } else if t, err = time.Parse("2006", startedResult.String()); err == nil {
s.Started = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", startedResult.String())
- if err == nil {
- s.Started = &d
- }
}
}
// extracting Status
@@ -311,9 +307,9 @@ func (s *FhirImagingStudy) PopulateAndExtractSearchParameters(resourceRaw json.R
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_immunization.go b/backend/pkg/models/database/fhir_immunization.go
index 3e4494992..bda82559c 100644
--- a/backend/pkg/models/database/fhir_immunization.go
+++ b/backend/pkg/models/database/fhir_immunization.go
@@ -125,11 +125,8 @@ type FhirImmunization struct {
// https://hl7.org/fhir/r4/search.html#token
TargetDisease datatypes.JSON `gorm:"column:targetDisease;type:text;serializer:json" json:"targetDisease,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// Vaccine Product Administered
// https://hl7.org/fhir/r4/search.html#token
VaccineCode datatypes.JSON `gorm:"column:vaccineCode;type:text;serializer:json" json:"vaccineCode,omitempty"`
@@ -162,8 +159,7 @@ func (s *FhirImmunization) GetSearchParameters() map[string]string {
"status": "token",
"statusReason": "token",
"targetDisease": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"vaccineCode": "token",
}
return searchParameters
@@ -208,14 +204,14 @@ func (s *FhirImmunization) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -246,14 +242,14 @@ func (s *FhirImmunization) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -284,14 +280,14 @@ func (s *FhirImmunization) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting ReactionDate
reactionDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Immunization.reaction.date')")
if err == nil && reactionDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, reactionDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, reactionDateResult.String()); err == nil {
+ s.ReactionDate = &t
+ } else if t, err = time.Parse("2006-01-02", reactionDateResult.String()); err == nil {
+ s.ReactionDate = &t
+ } else if t, err = time.Parse("2006-01", reactionDateResult.String()); err == nil {
+ s.ReactionDate = &t
+ } else if t, err = time.Parse("2006", reactionDateResult.String()); err == nil {
s.ReactionDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", reactionDateResult.String())
- if err == nil {
- s.ReactionDate = &d
- }
}
}
// extracting ReasonCode
@@ -325,9 +321,9 @@ func (s *FhirImmunization) PopulateAndExtractSearchParameters(resourceRaw json.R
s.TargetDisease = []byte(targetDiseaseResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting VaccineCode
vaccineCodeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Immunization.vaccineCode')")
diff --git a/backend/pkg/models/database/fhir_insurance_plan.go b/backend/pkg/models/database/fhir_insurance_plan.go
index ad21de1a1..4ad00b815 100644
--- a/backend/pkg/models/database/fhir_insurance_plan.go
+++ b/backend/pkg/models/database/fhir_insurance_plan.go
@@ -69,10 +69,10 @@ type FhirInsurancePlan struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // A code for the type of organization
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -102,8 +102,8 @@ func (s *FhirInsurancePlan) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -197,14 +197,14 @@ func (s *FhirInsurancePlan) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -243,9 +243,14 @@ func (s *FhirInsurancePlan) PopulateAndExtractSearchParameters(resourceRaw json.
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'InsurancePlan.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_location.go b/backend/pkg/models/database/fhir_location.go
index b3d78a223..a812c99d2 100644
--- a/backend/pkg/models/database/fhir_location.go
+++ b/backend/pkg/models/database/fhir_location.go
@@ -69,10 +69,10 @@ type FhirLocation struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // A code for the type of location
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -102,8 +102,8 @@ func (s *FhirLocation) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -192,14 +192,14 @@ func (s *FhirLocation) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -243,9 +243,14 @@ func (s *FhirLocation) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Location.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_media.go b/backend/pkg/models/database/fhir_media.go
index 378d32a53..0bb44964b 100644
--- a/backend/pkg/models/database/fhir_media.go
+++ b/backend/pkg/models/database/fhir_media.go
@@ -60,10 +60,10 @@ type FhirMedia struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // Classification of media as image, video, or audio
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
// Imaging view, e.g. Lateral or Antero-posterior
// https://hl7.org/fhir/r4/search.html#token
@@ -93,8 +93,8 @@ func (s *FhirMedia) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
"view": "token",
}
return searchParameters
@@ -144,14 +144,14 @@ func (s *FhirMedia) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
// extracting Created
createdResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Media.createdDateTime | Media.createdPeriod')")
if err == nil && createdResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, createdResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01-02", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006-01", createdResult.String()); err == nil {
+ s.Created = &t
+ } else if t, err = time.Parse("2006", createdResult.String()); err == nil {
s.Created = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", createdResult.String())
- if err == nil {
- s.Created = &d
- }
}
}
// extracting Device
@@ -177,14 +177,14 @@ func (s *FhirMedia) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -228,9 +228,14 @@ func (s *FhirMedia) PopulateAndExtractSearchParameters(resourceRaw json.RawMessa
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Media.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
// extracting View
viewResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Media.view')")
diff --git a/backend/pkg/models/database/fhir_medication.go b/backend/pkg/models/database/fhir_medication.go
index 78d8914f5..ced57a7c9 100644
--- a/backend/pkg/models/database/fhir_medication.go
+++ b/backend/pkg/models/database/fhir_medication.go
@@ -74,11 +74,8 @@ type FhirMedication struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirMedication) GetSearchParameters() map[string]string {
@@ -103,8 +100,7 @@ func (s *FhirMedication) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -153,14 +149,14 @@ func (s *FhirMedication) PopulateAndExtractSearchParameters(resourceRaw json.Raw
// extracting ExpirationDate
expirationDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Medication.batch.expirationDate')")
if err == nil && expirationDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, expirationDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, expirationDateResult.String()); err == nil {
+ s.ExpirationDate = &t
+ } else if t, err = time.Parse("2006-01-02", expirationDateResult.String()); err == nil {
+ s.ExpirationDate = &t
+ } else if t, err = time.Parse("2006-01", expirationDateResult.String()); err == nil {
+ s.ExpirationDate = &t
+ } else if t, err = time.Parse("2006", expirationDateResult.String()); err == nil {
s.ExpirationDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", expirationDateResult.String())
- if err == nil {
- s.ExpirationDate = &d
- }
}
}
// extracting Form
@@ -201,14 +197,14 @@ func (s *FhirMedication) PopulateAndExtractSearchParameters(resourceRaw json.Raw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -232,9 +228,9 @@ func (s *FhirMedication) PopulateAndExtractSearchParameters(resourceRaw json.Raw
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_medication_administration.go b/backend/pkg/models/database/fhir_medication_administration.go
index d9534b8c7..c79460db2 100644
--- a/backend/pkg/models/database/fhir_medication_administration.go
+++ b/backend/pkg/models/database/fhir_medication_administration.go
@@ -130,11 +130,8 @@ type FhirMedicationAdministration struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirMedicationAdministration) GetSearchParameters() map[string]string {
@@ -162,8 +159,7 @@ func (s *FhirMedicationAdministration) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -222,14 +218,14 @@ func (s *FhirMedicationAdministration) PopulateAndExtractSearchParameters(resour
// extracting EffectiveTime
effectiveTimeResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationAdministration.effectiveDateTime | MedicationAdministration.effectivePeriod')")
if err == nil && effectiveTimeResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, effectiveTimeResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, effectiveTimeResult.String()); err == nil {
+ s.EffectiveTime = &t
+ } else if t, err = time.Parse("2006-01-02", effectiveTimeResult.String()); err == nil {
+ s.EffectiveTime = &t
+ } else if t, err = time.Parse("2006-01", effectiveTimeResult.String()); err == nil {
+ s.EffectiveTime = &t
+ } else if t, err = time.Parse("2006", effectiveTimeResult.String()); err == nil {
s.EffectiveTime = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", effectiveTimeResult.String())
- if err == nil {
- s.EffectiveTime = &d
- }
}
}
// extracting Identifier
@@ -250,14 +246,14 @@ func (s *FhirMedicationAdministration) PopulateAndExtractSearchParameters(resour
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -306,9 +302,9 @@ func (s *FhirMedicationAdministration) PopulateAndExtractSearchParameters(resour
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_medication_dispense.go b/backend/pkg/models/database/fhir_medication_dispense.go
index 7cf72bf38..368c4ea69 100644
--- a/backend/pkg/models/database/fhir_medication_dispense.go
+++ b/backend/pkg/models/database/fhir_medication_dispense.go
@@ -131,10 +131,10 @@ type FhirMedicationDispense struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // Returns dispenses of a specific type
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
// Returns dispenses handed over on this date
// https://hl7.org/fhir/r4/search.html#date
@@ -168,8 +168,8 @@ func (s *FhirMedicationDispense) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
"whenhandedover": "date",
"whenprepared": "date",
}
@@ -245,14 +245,14 @@ func (s *FhirMedicationDispense) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -301,34 +301,39 @@ func (s *FhirMedicationDispense) PopulateAndExtractSearchParameters(resourceRaw
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'MedicationDispense.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
// extracting Whenhandedover
whenhandedoverResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationDispense.whenHandedOver')")
if err == nil && whenhandedoverResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, whenhandedoverResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, whenhandedoverResult.String()); err == nil {
+ s.Whenhandedover = &t
+ } else if t, err = time.Parse("2006-01-02", whenhandedoverResult.String()); err == nil {
+ s.Whenhandedover = &t
+ } else if t, err = time.Parse("2006-01", whenhandedoverResult.String()); err == nil {
+ s.Whenhandedover = &t
+ } else if t, err = time.Parse("2006", whenhandedoverResult.String()); err == nil {
s.Whenhandedover = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", whenhandedoverResult.String())
- if err == nil {
- s.Whenhandedover = &d
- }
}
}
// extracting Whenprepared
whenpreparedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationDispense.whenPrepared')")
if err == nil && whenpreparedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, whenpreparedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, whenpreparedResult.String()); err == nil {
+ s.Whenprepared = &t
+ } else if t, err = time.Parse("2006-01-02", whenpreparedResult.String()); err == nil {
+ s.Whenprepared = &t
+ } else if t, err = time.Parse("2006-01", whenpreparedResult.String()); err == nil {
+ s.Whenprepared = &t
+ } else if t, err = time.Parse("2006", whenpreparedResult.String()); err == nil {
s.Whenprepared = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", whenpreparedResult.String())
- if err == nil {
- s.Whenprepared = &d
- }
}
}
return nil
diff --git a/backend/pkg/models/database/fhir_medication_request.go b/backend/pkg/models/database/fhir_medication_request.go
index 9be6515a8..d0dca3f67 100644
--- a/backend/pkg/models/database/fhir_medication_request.go
+++ b/backend/pkg/models/database/fhir_medication_request.go
@@ -147,11 +147,8 @@ type FhirMedicationRequest struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirMedicationRequest) GetSearchParameters() map[string]string {
@@ -182,8 +179,7 @@ func (s *FhirMedicationRequest) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -227,14 +223,14 @@ func (s *FhirMedicationRequest) PopulateAndExtractSearchParameters(resourceRaw j
// extracting Authoredon
authoredonResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationRequest.authoredOn')")
if err == nil && authoredonResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, authoredonResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, authoredonResult.String()); err == nil {
+ s.Authoredon = &t
+ } else if t, err = time.Parse("2006-01-02", authoredonResult.String()); err == nil {
+ s.Authoredon = &t
+ } else if t, err = time.Parse("2006-01", authoredonResult.String()); err == nil {
+ s.Authoredon = &t
+ } else if t, err = time.Parse("2006", authoredonResult.String()); err == nil {
s.Authoredon = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", authoredonResult.String())
- if err == nil {
- s.Authoredon = &d
- }
}
}
// extracting Category
@@ -250,14 +246,14 @@ func (s *FhirMedicationRequest) PopulateAndExtractSearchParameters(resourceRaw j
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationRequest.dosageInstruction.timing.event')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -303,14 +299,14 @@ func (s *FhirMedicationRequest) PopulateAndExtractSearchParameters(resourceRaw j
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -349,9 +345,9 @@ func (s *FhirMedicationRequest) PopulateAndExtractSearchParameters(resourceRaw j
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_medication_statement.go b/backend/pkg/models/database/fhir_medication_statement.go
index 54dc931c7..80627aca0 100644
--- a/backend/pkg/models/database/fhir_medication_statement.go
+++ b/backend/pkg/models/database/fhir_medication_statement.go
@@ -124,11 +124,8 @@ type FhirMedicationStatement struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirMedicationStatement) GetSearchParameters() map[string]string {
@@ -154,8 +151,7 @@ func (s *FhirMedicationStatement) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -214,14 +210,14 @@ func (s *FhirMedicationStatement) PopulateAndExtractSearchParameters(resourceRaw
// extracting Effective
effectiveResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'MedicationStatement.effectiveDateTime | MedicationStatement.effectivePeriod')")
if err == nil && effectiveResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, effectiveResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006-01-02", effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006-01", effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006", effectiveResult.String()); err == nil {
s.Effective = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", effectiveResult.String())
- if err == nil {
- s.Effective = &d
- }
}
}
// extracting Identifier
@@ -242,14 +238,14 @@ func (s *FhirMedicationStatement) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -288,9 +284,9 @@ func (s *FhirMedicationStatement) PopulateAndExtractSearchParameters(resourceRaw
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_nutrition_order.go b/backend/pkg/models/database/fhir_nutrition_order.go
index 20cd82fa4..98583e532 100644
--- a/backend/pkg/models/database/fhir_nutrition_order.go
+++ b/backend/pkg/models/database/fhir_nutrition_order.go
@@ -111,11 +111,8 @@ type FhirNutritionOrder struct {
// https://hl7.org/fhir/r4/search.html#token
Supplement datatypes.JSON `gorm:"column:supplement;type:text;serializer:json" json:"supplement,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirNutritionOrder) GetSearchParameters() map[string]string {
@@ -142,8 +139,7 @@ func (s *FhirNutritionOrder) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"supplement": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -192,14 +188,14 @@ func (s *FhirNutritionOrder) PopulateAndExtractSearchParameters(resourceRaw json
// extracting Datetime
datetimeResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'NutritionOrder.dateTime')")
if err == nil && datetimeResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, datetimeResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, datetimeResult.String()); err == nil {
+ s.Datetime = &t
+ } else if t, err = time.Parse("2006-01-02", datetimeResult.String()); err == nil {
+ s.Datetime = &t
+ } else if t, err = time.Parse("2006-01", datetimeResult.String()); err == nil {
+ s.Datetime = &t
+ } else if t, err = time.Parse("2006", datetimeResult.String()); err == nil {
s.Datetime = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", datetimeResult.String())
- if err == nil {
- s.Datetime = &d
- }
}
}
// extracting Encounter
@@ -235,14 +231,14 @@ func (s *FhirNutritionOrder) PopulateAndExtractSearchParameters(resourceRaw json
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -281,9 +277,9 @@ func (s *FhirNutritionOrder) PopulateAndExtractSearchParameters(resourceRaw json
s.Supplement = []byte(supplementResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_observation.go b/backend/pkg/models/database/fhir_observation.go
index 61afb41ed..3dc75e3ff 100644
--- a/backend/pkg/models/database/fhir_observation.go
+++ b/backend/pkg/models/database/fhir_observation.go
@@ -190,11 +190,8 @@ type FhirObservation struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// The value of the observation, if the value is a CodeableConcept
// https://hl7.org/fhir/r4/search.html#token
ValueConcept datatypes.JSON `gorm:"column:valueConcept;type:text;serializer:json" json:"valueConcept,omitempty"`
@@ -247,8 +244,7 @@ func (s *FhirObservation) GetSearchParameters() map[string]string {
"specimen": "reference",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"valueConcept": "token",
"valueDate": "date",
"valueQuantity": "quantity",
@@ -356,14 +352,14 @@ func (s *FhirObservation) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting DerivedFrom
@@ -404,14 +400,14 @@ func (s *FhirObservation) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -460,9 +456,9 @@ func (s *FhirObservation) PopulateAndExtractSearchParameters(resourceRaw json.Ra
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting ValueConcept
valueConceptResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, '(Observation.valueCodeableConcept)')")
@@ -472,14 +468,14 @@ func (s *FhirObservation) PopulateAndExtractSearchParameters(resourceRaw json.Ra
// extracting ValueDate
valueDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(Observation.valueDateTime) | (Observation.valuePeriod)')")
if err == nil && valueDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, valueDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, valueDateResult.String()); err == nil {
+ s.ValueDate = &t
+ } else if t, err = time.Parse("2006-01-02", valueDateResult.String()); err == nil {
+ s.ValueDate = &t
+ } else if t, err = time.Parse("2006-01", valueDateResult.String()); err == nil {
+ s.ValueDate = &t
+ } else if t, err = time.Parse("2006", valueDateResult.String()); err == nil {
s.ValueDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", valueDateResult.String())
- if err == nil {
- s.ValueDate = &d
- }
}
}
// extracting ValueQuantity
diff --git a/backend/pkg/models/database/fhir_organization.go b/backend/pkg/models/database/fhir_organization.go
index 990dde240..772e0ea95 100644
--- a/backend/pkg/models/database/fhir_organization.go
+++ b/backend/pkg/models/database/fhir_organization.go
@@ -66,10 +66,10 @@ type FhirOrganization struct {
// https://hl7.org/fhir/r4/search.html#string
Phonetic datatypes.JSON `gorm:"column:phonetic;type:text;serializer:json" json:"phonetic,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // A code for the type of organization
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -98,8 +98,8 @@ func (s *FhirOrganization) GetSearchParameters() map[string]string {
"source_resource_id": "keyword",
"source_resource_type": "keyword",
"source_uri": "keyword",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -193,14 +193,14 @@ func (s *FhirOrganization) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -234,9 +234,14 @@ func (s *FhirOrganization) PopulateAndExtractSearchParameters(resourceRaw json.R
s.Phonetic = []byte(phoneticResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Organization.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_organization_affiliation.go b/backend/pkg/models/database/fhir_organization_affiliation.go
index 095dfcf36..f3c0d5973 100644
--- a/backend/pkg/models/database/fhir_organization_affiliation.go
+++ b/backend/pkg/models/database/fhir_organization_affiliation.go
@@ -72,11 +72,8 @@ type FhirOrganizationAffiliation struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirOrganizationAffiliation) GetSearchParameters() map[string]string {
@@ -106,8 +103,7 @@ func (s *FhirOrganizationAffiliation) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"specialty": "token",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -156,14 +152,14 @@ func (s *FhirOrganizationAffiliation) PopulateAndExtractSearchParameters(resourc
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'OrganizationAffiliation.period')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Email
@@ -194,14 +190,14 @@ func (s *FhirOrganizationAffiliation) PopulateAndExtractSearchParameters(resourc
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -260,9 +256,9 @@ func (s *FhirOrganizationAffiliation) PopulateAndExtractSearchParameters(resourc
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_patient.go b/backend/pkg/models/database/fhir_patient.go
index 71ceb6b5b..3742e9f74 100644
--- a/backend/pkg/models/database/fhir_patient.go
+++ b/backend/pkg/models/database/fhir_patient.go
@@ -192,11 +192,8 @@ type FhirPatient struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirPatient) GetSearchParameters() map[string]string {
@@ -234,8 +231,7 @@ func (s *FhirPatient) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -314,27 +310,27 @@ func (s *FhirPatient) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting Birthdate
birthdateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Patient.birthDate | Person.birthDate | RelatedPerson.birthDate')")
if err == nil && birthdateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, birthdateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01-02", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006", birthdateResult.String()); err == nil {
s.Birthdate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", birthdateResult.String())
- if err == nil {
- s.Birthdate = &d
- }
}
}
// extracting DeathDate
deathDateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(Patient.deceasedDateTime)')")
if err == nil && deathDateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, deathDateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, deathDateResult.String()); err == nil {
+ s.DeathDate = &t
+ } else if t, err = time.Parse("2006-01-02", deathDateResult.String()); err == nil {
+ s.DeathDate = &t
+ } else if t, err = time.Parse("2006-01", deathDateResult.String()); err == nil {
+ s.DeathDate = &t
+ } else if t, err = time.Parse("2006", deathDateResult.String()); err == nil {
s.DeathDate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", deathDateResult.String())
- if err == nil {
- s.DeathDate = &d
- }
}
}
// extracting Deceased
@@ -385,14 +381,14 @@ func (s *FhirPatient) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -436,9 +432,9 @@ func (s *FhirPatient) PopulateAndExtractSearchParameters(resourceRaw json.RawMes
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_person.go b/backend/pkg/models/database/fhir_person.go
index f41d335f4..19568c802 100644
--- a/backend/pkg/models/database/fhir_person.go
+++ b/backend/pkg/models/database/fhir_person.go
@@ -170,11 +170,8 @@ type FhirPerson struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirPerson) GetSearchParameters() map[string]string {
@@ -208,8 +205,7 @@ func (s *FhirPerson) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -283,14 +279,14 @@ func (s *FhirPerson) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
// extracting Birthdate
birthdateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Patient.birthDate | Person.birthDate | RelatedPerson.birthDate')")
if err == nil && birthdateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, birthdateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01-02", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006", birthdateResult.String()); err == nil {
s.Birthdate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", birthdateResult.String())
- if err == nil {
- s.Birthdate = &d
- }
}
}
// extracting Email
@@ -321,14 +317,14 @@ func (s *FhirPerson) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -382,9 +378,9 @@ func (s *FhirPerson) PopulateAndExtractSearchParameters(resourceRaw json.RawMess
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_practitioner.go b/backend/pkg/models/database/fhir_practitioner.go
index 46540dbfc..21c33aa8a 100644
--- a/backend/pkg/models/database/fhir_practitioner.go
+++ b/backend/pkg/models/database/fhir_practitioner.go
@@ -171,11 +171,8 @@ type FhirPractitioner struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirPractitioner) GetSearchParameters() map[string]string {
@@ -208,8 +205,7 @@ func (s *FhirPractitioner) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -323,14 +319,14 @@ func (s *FhirPractitioner) PopulateAndExtractSearchParameters(resourceRaw json.R
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -369,9 +365,9 @@ func (s *FhirPractitioner) PopulateAndExtractSearchParameters(resourceRaw json.R
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_practitioner_role.go b/backend/pkg/models/database/fhir_practitioner_role.go
index 703a43fb8..0d4c06da2 100644
--- a/backend/pkg/models/database/fhir_practitioner_role.go
+++ b/backend/pkg/models/database/fhir_practitioner_role.go
@@ -93,11 +93,8 @@ type FhirPractitionerRole struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirPractitionerRole) GetSearchParameters() map[string]string {
@@ -126,8 +123,7 @@ func (s *FhirPractitionerRole) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"specialty": "token",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -176,14 +172,14 @@ func (s *FhirPractitionerRole) PopulateAndExtractSearchParameters(resourceRaw js
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'PractitionerRole.period')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Email
@@ -214,14 +210,14 @@ func (s *FhirPractitionerRole) PopulateAndExtractSearchParameters(resourceRaw js
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -275,9 +271,9 @@ func (s *FhirPractitionerRole) PopulateAndExtractSearchParameters(resourceRaw js
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_procedure.go b/backend/pkg/models/database/fhir_procedure.go
index 09774e846..9e6382637 100644
--- a/backend/pkg/models/database/fhir_procedure.go
+++ b/backend/pkg/models/database/fhir_procedure.go
@@ -160,11 +160,8 @@ type FhirProcedure struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirProcedure) GetSearchParameters() map[string]string {
@@ -195,8 +192,7 @@ func (s *FhirProcedure) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -255,14 +251,14 @@ func (s *FhirProcedure) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'AllergyIntolerance.recordedDate | CarePlan.period | CareTeam.period | ClinicalImpression.date | Composition.date | Consent.dateTime | DiagnosticReport.effectiveDateTime | DiagnosticReport.effectivePeriod | Encounter.period | EpisodeOfCare.period | FamilyMemberHistory.date | Flag.period | (Immunization.occurrenceDateTime) | List.date | Observation.effectiveDateTime | Observation.effectivePeriod | Observation.effectiveTiming | Observation.effectiveInstant | Procedure.performedDateTime | Procedure.performedPeriod | Procedure.performedString | Procedure.performedAge | Procedure.performedRange | (RiskAssessment.occurrenceDateTime) | SupplyRequest.authoredOn')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Encounter
@@ -298,14 +294,14 @@ func (s *FhirProcedure) PopulateAndExtractSearchParameters(resourceRaw json.RawM
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -354,9 +350,9 @@ func (s *FhirProcedure) PopulateAndExtractSearchParameters(resourceRaw json.RawM
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_provenance.go b/backend/pkg/models/database/fhir_provenance.go
index ea9a3a6c8..d98b824d3 100644
--- a/backend/pkg/models/database/fhir_provenance.go
+++ b/backend/pkg/models/database/fhir_provenance.go
@@ -54,11 +54,8 @@ type FhirProvenance struct {
// https://hl7.org/fhir/r4/search.html#reference
Target datatypes.JSON `gorm:"column:target;type:text;serializer:json" json:"target,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// When the activity occurred
// https://hl7.org/fhir/r4/search.html#date
When *time.Time `gorm:"column:when;type:datetime" json:"when,omitempty"`
@@ -85,8 +82,7 @@ func (s *FhirProvenance) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"target": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
"when": "date",
}
return searchParameters
@@ -161,14 +157,14 @@ func (s *FhirProvenance) PopulateAndExtractSearchParameters(resourceRaw json.Raw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -189,14 +185,14 @@ func (s *FhirProvenance) PopulateAndExtractSearchParameters(resourceRaw json.Raw
// extracting Recorded
recordedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Provenance.recorded')")
if err == nil && recordedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, recordedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, recordedResult.String()); err == nil {
+ s.Recorded = &t
+ } else if t, err = time.Parse("2006-01-02", recordedResult.String()); err == nil {
+ s.Recorded = &t
+ } else if t, err = time.Parse("2006-01", recordedResult.String()); err == nil {
+ s.Recorded = &t
+ } else if t, err = time.Parse("2006", recordedResult.String()); err == nil {
s.Recorded = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", recordedResult.String())
- if err == nil {
- s.Recorded = &d
- }
}
}
// extracting SignatureType
@@ -210,21 +206,21 @@ func (s *FhirProvenance) PopulateAndExtractSearchParameters(resourceRaw json.Raw
s.Target = []byte(targetResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting When
whenResult, err := vm.RunString("extractDateSearchParameters(fhirResource, '(Provenance.occurredDateTime)')")
if err == nil && whenResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, whenResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, whenResult.String()); err == nil {
+ s.When = &t
+ } else if t, err = time.Parse("2006-01-02", whenResult.String()); err == nil {
+ s.When = &t
+ } else if t, err = time.Parse("2006-01", whenResult.String()); err == nil {
+ s.When = &t
+ } else if t, err = time.Parse("2006", whenResult.String()); err == nil {
s.When = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", whenResult.String())
- if err == nil {
- s.When = &d
- }
}
}
return nil
diff --git a/backend/pkg/models/database/fhir_questionnaire.go b/backend/pkg/models/database/fhir_questionnaire.go
index 0cb652fe3..b436b76fd 100644
--- a/backend/pkg/models/database/fhir_questionnaire.go
+++ b/backend/pkg/models/database/fhir_questionnaire.go
@@ -72,14 +72,11 @@ type FhirQuestionnaire struct {
// https://hl7.org/fhir/r4/search.html#token
SubjectType datatypes.JSON `gorm:"column:subjectType;type:text;serializer:json" json:"subjectType,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
// The human-friendly name of the questionnaire
// https://hl7.org/fhir/r4/search.html#string
Title datatypes.JSON `gorm:"column:title;type:text;serializer:json" json:"title,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
// The uri that identifies the questionnaire
// https://hl7.org/fhir/r4/search.html#uri
Url string `gorm:"column:url;type:text" json:"url,omitempty"`
@@ -115,9 +112,8 @@ func (s *FhirQuestionnaire) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subjectType": "token",
- "text": "keyword",
+ "text": "string",
"title": "string",
- "type": "special",
"url": "uri",
"version": "token",
}
@@ -183,14 +179,14 @@ func (s *FhirQuestionnaire) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Questionnaire.date')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Definition
@@ -206,14 +202,14 @@ func (s *FhirQuestionnaire) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting Effective
effectiveResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Questionnaire.effectivePeriod')")
if err == nil && effectiveResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, effectiveResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006-01-02", effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006-01", effectiveResult.String()); err == nil {
+ s.Effective = &t
+ } else if t, err = time.Parse("2006", effectiveResult.String()); err == nil {
s.Effective = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", effectiveResult.String())
- if err == nil {
- s.Effective = &d
- }
}
}
// extracting Identifier
@@ -234,14 +230,14 @@ func (s *FhirQuestionnaire) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -280,9 +276,9 @@ func (s *FhirQuestionnaire) PopulateAndExtractSearchParameters(resourceRaw json.
s.SubjectType = []byte(subjectTypeResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
// extracting Title
titleResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'Questionnaire.title')")
diff --git a/backend/pkg/models/database/fhir_questionnaire_response.go b/backend/pkg/models/database/fhir_questionnaire_response.go
index 9b3fa91c2..6a50a2d0b 100644
--- a/backend/pkg/models/database/fhir_questionnaire_response.go
+++ b/backend/pkg/models/database/fhir_questionnaire_response.go
@@ -60,11 +60,8 @@ type FhirQuestionnaireResponse struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirQuestionnaireResponse) GetSearchParameters() map[string]string {
@@ -90,8 +87,7 @@ func (s *FhirQuestionnaireResponse) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -140,14 +136,14 @@ func (s *FhirQuestionnaireResponse) PopulateAndExtractSearchParameters(resourceR
// extracting Authored
authoredResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'QuestionnaireResponse.authored')")
if err == nil && authoredResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, authoredResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006-01-02", authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006-01", authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006", authoredResult.String()); err == nil {
s.Authored = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", authoredResult.String())
- if err == nil {
- s.Authored = &d
- }
}
}
// extracting BasedOn
@@ -173,14 +169,14 @@ func (s *FhirQuestionnaireResponse) PopulateAndExtractSearchParameters(resourceR
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -224,9 +220,9 @@ func (s *FhirQuestionnaireResponse) PopulateAndExtractSearchParameters(resourceR
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_related_person.go b/backend/pkg/models/database/fhir_related_person.go
index ade88f29a..256f52dd5 100644
--- a/backend/pkg/models/database/fhir_related_person.go
+++ b/backend/pkg/models/database/fhir_related_person.go
@@ -164,11 +164,8 @@ type FhirRelatedPerson struct {
// https://hl7.org/fhir/r4/search.html#token
Telecom datatypes.JSON `gorm:"column:telecom;type:text;serializer:json" json:"telecom,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirRelatedPerson) GetSearchParameters() map[string]string {
@@ -200,8 +197,7 @@ func (s *FhirRelatedPerson) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"telecom": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -280,14 +276,14 @@ func (s *FhirRelatedPerson) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting Birthdate
birthdateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Patient.birthDate | Person.birthDate | RelatedPerson.birthDate')")
if err == nil && birthdateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, birthdateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01-02", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006-01", birthdateResult.String()); err == nil {
+ s.Birthdate = &t
+ } else if t, err = time.Parse("2006", birthdateResult.String()); err == nil {
s.Birthdate = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", birthdateResult.String())
- if err == nil {
- s.Birthdate = &d
- }
}
}
// extracting Email
@@ -313,14 +309,14 @@ func (s *FhirRelatedPerson) PopulateAndExtractSearchParameters(resourceRaw json.
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -364,9 +360,9 @@ func (s *FhirRelatedPerson) PopulateAndExtractSearchParameters(resourceRaw json.
s.Telecom = []byte(telecomResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_schedule.go b/backend/pkg/models/database/fhir_schedule.go
index fd7b45603..6c109521a 100644
--- a/backend/pkg/models/database/fhir_schedule.go
+++ b/backend/pkg/models/database/fhir_schedule.go
@@ -51,11 +51,8 @@ type FhirSchedule struct {
// https://hl7.org/fhir/r4/search.html#token
Specialty datatypes.JSON `gorm:"column:specialty;type:text;serializer:json" json:"specialty,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirSchedule) GetSearchParameters() map[string]string {
@@ -78,8 +75,7 @@ func (s *FhirSchedule) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"specialty": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -133,14 +129,14 @@ func (s *FhirSchedule) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting Date
dateResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Schedule.planningHorizon')")
if err == nil && dateResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, dateResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01-02", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006-01", dateResult.String()); err == nil {
+ s.Date = &t
+ } else if t, err = time.Parse("2006", dateResult.String()); err == nil {
s.Date = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", dateResult.String())
- if err == nil {
- s.Date = &d
- }
}
}
// extracting Identifier
@@ -156,14 +152,14 @@ func (s *FhirSchedule) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -197,9 +193,9 @@ func (s *FhirSchedule) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Specialty = []byte(specialtyResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_service_request.go b/backend/pkg/models/database/fhir_service_request.go
index 535d4628c..f77683c01 100644
--- a/backend/pkg/models/database/fhir_service_request.go
+++ b/backend/pkg/models/database/fhir_service_request.go
@@ -155,11 +155,8 @@ type FhirServiceRequest struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirServiceRequest) GetSearchParameters() map[string]string {
@@ -195,8 +192,7 @@ func (s *FhirServiceRequest) GetSearchParameters() map[string]string {
"specimen": "reference",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -240,14 +236,14 @@ func (s *FhirServiceRequest) PopulateAndExtractSearchParameters(resourceRaw json
// extracting Authored
authoredResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ServiceRequest.authoredOn')")
if err == nil && authoredResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, authoredResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006-01-02", authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006-01", authoredResult.String()); err == nil {
+ s.Authored = &t
+ } else if t, err = time.Parse("2006", authoredResult.String()); err == nil {
s.Authored = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", authoredResult.String())
- if err == nil {
- s.Authored = &d
- }
}
}
// extracting BasedOn
@@ -303,14 +299,14 @@ func (s *FhirServiceRequest) PopulateAndExtractSearchParameters(resourceRaw json
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -331,14 +327,14 @@ func (s *FhirServiceRequest) PopulateAndExtractSearchParameters(resourceRaw json
// extracting Occurrence
occurrenceResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'ServiceRequest.occurrenceDateTime | ServiceRequest.occurrencePeriod | ServiceRequest.occurrenceTiming')")
if err == nil && occurrenceResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, occurrenceResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, occurrenceResult.String()); err == nil {
+ s.Occurrence = &t
+ } else if t, err = time.Parse("2006-01-02", occurrenceResult.String()); err == nil {
+ s.Occurrence = &t
+ } else if t, err = time.Parse("2006-01", occurrenceResult.String()); err == nil {
+ s.Occurrence = &t
+ } else if t, err = time.Parse("2006", occurrenceResult.String()); err == nil {
s.Occurrence = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", occurrenceResult.String())
- if err == nil {
- s.Occurrence = &d
- }
}
}
// extracting Performer
@@ -387,9 +383,9 @@ func (s *FhirServiceRequest) PopulateAndExtractSearchParameters(resourceRaw json
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_slot.go b/backend/pkg/models/database/fhir_slot.go
index 4d5701b6a..b77d47bbc 100644
--- a/backend/pkg/models/database/fhir_slot.go
+++ b/backend/pkg/models/database/fhir_slot.go
@@ -54,11 +54,8 @@ type FhirSlot struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirSlot) GetSearchParameters() map[string]string {
@@ -82,8 +79,7 @@ func (s *FhirSlot) GetSearchParameters() map[string]string {
"specialty": "token",
"start": "date",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -142,14 +138,14 @@ func (s *FhirSlot) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -190,14 +186,14 @@ func (s *FhirSlot) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
// extracting Start
startResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Slot.start')")
if err == nil && startResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, startResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, startResult.String()); err == nil {
+ s.Start = &t
+ } else if t, err = time.Parse("2006-01-02", startResult.String()); err == nil {
+ s.Start = &t
+ } else if t, err = time.Parse("2006-01", startResult.String()); err == nil {
+ s.Start = &t
+ } else if t, err = time.Parse("2006", startResult.String()); err == nil {
s.Start = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", startResult.String())
- if err == nil {
- s.Start = &d
- }
}
}
// extracting Status
@@ -206,9 +202,9 @@ func (s *FhirSlot) PopulateAndExtractSearchParameters(resourceRaw json.RawMessag
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_specimen.go b/backend/pkg/models/database/fhir_specimen.go
index 992aca68b..e8e500534 100644
--- a/backend/pkg/models/database/fhir_specimen.go
+++ b/backend/pkg/models/database/fhir_specimen.go
@@ -60,10 +60,10 @@ type FhirSpecimen struct {
// https://hl7.org/fhir/r4/search.html#reference
Subject datatypes.JSON `gorm:"column:subject;type:text;serializer:json" json:"subject,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
+ // The specimen type
+ // https://hl7.org/fhir/r4/search.html#token
Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
}
@@ -90,8 +90,8 @@ func (s *FhirSpecimen) GetSearchParameters() map[string]string {
"source_uri": "keyword",
"status": "token",
"subject": "reference",
- "text": "keyword",
- "type": "special",
+ "text": "string",
+ "type": "token",
}
return searchParameters
}
@@ -145,14 +145,14 @@ func (s *FhirSpecimen) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting Collected
collectedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'Specimen.collection.collectedDateTime | Specimen.collection.collectedPeriod')")
if err == nil && collectedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, collectedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, collectedResult.String()); err == nil {
+ s.Collected = &t
+ } else if t, err = time.Parse("2006-01-02", collectedResult.String()); err == nil {
+ s.Collected = &t
+ } else if t, err = time.Parse("2006-01", collectedResult.String()); err == nil {
+ s.Collected = &t
+ } else if t, err = time.Parse("2006", collectedResult.String()); err == nil {
s.Collected = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", collectedResult.String())
- if err == nil {
- s.Collected = &d
- }
}
}
// extracting Collector
@@ -183,14 +183,14 @@ func (s *FhirSpecimen) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -224,9 +224,14 @@ func (s *FhirSpecimen) PopulateAndExtractSearchParameters(resourceRaw json.RawMe
s.Subject = []byte(subjectResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
+ }
+ // extracting Type
+ typeResult, err := vm.RunString("extractTokenSearchParameters(fhirResource, 'Specimen.type')")
+ if err == nil && typeResult.String() != "undefined" {
+ s.Type = []byte(typeResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/fhir_vision_prescription.go b/backend/pkg/models/database/fhir_vision_prescription.go
index 902578eb6..fa4b115df 100644
--- a/backend/pkg/models/database/fhir_vision_prescription.go
+++ b/backend/pkg/models/database/fhir_vision_prescription.go
@@ -93,11 +93,8 @@ type FhirVisionPrescription struct {
// https://hl7.org/fhir/r4/search.html#token
Status datatypes.JSON `gorm:"column:status;type:text;serializer:json" json:"status,omitempty"`
// Text search against the narrative
- // This is a primitive string literal (`keyword` type). It is not a recognized SearchParameter type from https://hl7.org/fhir/r4/search.html, it's Fasten Health-specific
- Text string `gorm:"column:text;type:text" json:"text,omitempty"`
- // A resource type filter
- // https://hl7.org/fhir/r4/search.html#special
- Type datatypes.JSON `gorm:"column:type;type:text;serializer:json" json:"type,omitempty"`
+ // https://hl7.org/fhir/r4/search.html#string
+ Text datatypes.JSON `gorm:"column:text;type:text;serializer:json" json:"text,omitempty"`
}
func (s *FhirVisionPrescription) GetSearchParameters() map[string]string {
@@ -118,8 +115,7 @@ func (s *FhirVisionPrescription) GetSearchParameters() map[string]string {
"source_resource_type": "keyword",
"source_uri": "keyword",
"status": "token",
- "text": "keyword",
- "type": "special",
+ "text": "string",
}
return searchParameters
}
@@ -163,14 +159,14 @@ func (s *FhirVisionPrescription) PopulateAndExtractSearchParameters(resourceRaw
// extracting Datewritten
datewrittenResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'VisionPrescription.dateWritten')")
if err == nil && datewrittenResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, datewrittenResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, datewrittenResult.String()); err == nil {
+ s.Datewritten = &t
+ } else if t, err = time.Parse("2006-01-02", datewrittenResult.String()); err == nil {
+ s.Datewritten = &t
+ } else if t, err = time.Parse("2006-01", datewrittenResult.String()); err == nil {
+ s.Datewritten = &t
+ } else if t, err = time.Parse("2006", datewrittenResult.String()); err == nil {
s.Datewritten = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", datewrittenResult.String())
- if err == nil {
- s.Datewritten = &d
- }
}
}
// extracting Encounter
@@ -191,14 +187,14 @@ func (s *FhirVisionPrescription) PopulateAndExtractSearchParameters(resourceRaw
// extracting MetaLastUpdated
metaLastUpdatedResult, err := vm.RunString("extractDateSearchParameters(fhirResource, 'meta.lastUpdated')")
if err == nil && metaLastUpdatedResult.String() != "undefined" {
- t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String())
- if err == nil {
+ if t, err := time.Parse(time.RFC3339, metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01-02", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006-01", metaLastUpdatedResult.String()); err == nil {
+ s.MetaLastUpdated = &t
+ } else if t, err = time.Parse("2006", metaLastUpdatedResult.String()); err == nil {
s.MetaLastUpdated = &t
- } else if err != nil {
- d, err := time.Parse("2006-01-02", metaLastUpdatedResult.String())
- if err == nil {
- s.MetaLastUpdated = &d
- }
}
}
// extracting MetaProfile
@@ -227,9 +223,9 @@ func (s *FhirVisionPrescription) PopulateAndExtractSearchParameters(resourceRaw
s.Status = []byte(statusResult.String())
}
// extracting Text
- textResult, err := vm.RunString("extractSimpleSearchParameters(fhirResource, 'text')")
+ textResult, err := vm.RunString("extractStringSearchParameters(fhirResource, 'text')")
if err == nil && textResult.String() != "undefined" {
- s.Text = textResult.String()
+ s.Text = []byte(textResult.String())
}
return nil
}
diff --git a/backend/pkg/models/database/generate.go b/backend/pkg/models/database/generate.go
index 20e41d7b1..9b686a3e2 100644
--- a/backend/pkg/models/database/generate.go
+++ b/backend/pkg/models/database/generate.go
@@ -166,14 +166,10 @@ func main() {
FHIRPathExpression: "Resource.meta.tag",
}
fieldMap["Text"] = DBField{
- FieldType: "keyword",
+ FieldType: "string",
Description: "Text search against the narrative",
FHIRPathExpression: "text",
}
- fieldMap["Type"] = DBField{
- FieldType: "special",
- Description: "A resource type filter",
- }
resourceFieldMap[resourceName] = fieldMap
}
@@ -409,15 +405,27 @@ func main() {
break
case "date":
//parse RFC3339 date
- i.List(jen.Id("t"), jen.Id("err")).Op(":=").Qual("time", "Parse").Call(jen.Qual("time", "RFC3339"), jen.Id(fieldNameVar).Dot("String").Call())
- i.If(jen.Err().Op("==").Nil()).BlockFunc(func(e *jen.Group) {
+
+ i.If(
+ jen.List(jen.Id("t"), jen.Err()).Op(":=").Qual("time", "Parse").Call(jen.Qual("time", "RFC3339"), jen.Id(fieldNameVar).Dot("String").Call()),
+ jen.Err().Op("==").Nil(),
+ ).BlockFunc(func(e *jen.Group) {
+ e.Id("s").Dot(fieldName).Op("=").Op("&").Id("t")
+ }).Else().If(
+ jen.List(jen.Id("t"), jen.Err()).Op("=").Qual("time", "Parse").Call(jen.Lit("2006-01-02"), jen.Id(fieldNameVar).Dot("String").Call()),
+ jen.Err().Op("==").Nil(),
+ ).BlockFunc(func(e *jen.Group) {
+ e.Id("s").Dot(fieldName).Op("=").Op("&").Id("t")
+ }).Else().If(
+ jen.List(jen.Id("t"), jen.Err()).Op("=").Qual("time", "Parse").Call(jen.Lit("2006-01"), jen.Id(fieldNameVar).Dot("String").Call()),
+ jen.Err().Op("==").Nil(),
+ ).BlockFunc(func(e *jen.Group) {
+ e.Id("s").Dot(fieldName).Op("=").Op("&").Id("t")
+ }).Else().If(
+ jen.List(jen.Id("t"), jen.Err()).Op("=").Qual("time", "Parse").Call(jen.Lit("2006"), jen.Id(fieldNameVar).Dot("String").Call()),
+ jen.Err().Op("==").Nil(),
+ ).BlockFunc(func(e *jen.Group) {
e.Id("s").Dot(fieldName).Op("=").Op("&").Id("t")
- }).Else().If(jen.Err().Op("!=").Nil()).BlockFunc(func(e *jen.Group) {
- //parse date only
- e.List(jen.Id("d"), jen.Id("err")).Op(":=").Qual("time", "Parse").Call(jen.Lit("2006-01-02"), jen.Id(fieldNameVar).Dot("String").Call())
- e.If(jen.Err().Op("==").Nil()).BlockFunc(func(f *jen.Group) {
- f.Id("s").Dot(fieldName).Op("=").Op("&").Id("d")
- })
})
case "uri":
i.Id("s").Dot(fieldName).Op("=").Id(fieldNameVar).Dot("String").Call()
@@ -507,6 +515,22 @@ func main() {
})
})
+ //Similar to NewFhirResourceModelByType, this is a function which returns a slice corresponding FhirResource when provided the FhirResource type string
+ //uses a switch statement to return the correct type
+ utilsFile.Comment("Returns a map of all the resource names to their corresponding go struct")
+ utilsFile.Func().Id("NewFhirResourceModelSliceByType").Params(jen.Id("resourceType").String()).Params(jen.Interface(), jen.Error()).BlockFunc(func(g *jen.Group) {
+ g.Switch(jen.Id("resourceType")).BlockFunc(func(s *jen.Group) {
+ for _, resourceName := range AllowedResources {
+ s.Case(jen.Lit(resourceName)).BlockFunc(func(c *jen.Group) {
+ c.Return(jen.Index().Id("Fhir"+resourceName).Values(), jen.Nil())
+ })
+ }
+ s.Default().BlockFunc(func(d *jen.Group) {
+ d.Return(jen.Nil(), jen.Qual("fmt", "Errorf").Call(jen.Lit("Invalid resource type for model: %s"), jen.Id("resourceType")))
+ })
+ })
+ })
+
//A function which returns the GORM table name for a FHIRResource when provided the FhirResource type string
//uses a switch statement to return the correct type
utilsFile.Comment("Returns the GORM table name for a FHIRResource when provided the FhirResource type string")
diff --git a/backend/pkg/models/database/interface.go b/backend/pkg/models/database/interface.go
index 66be7f75f..d513c6df4 100644
--- a/backend/pkg/models/database/interface.go
+++ b/backend/pkg/models/database/interface.go
@@ -11,6 +11,7 @@ type IFhirResourceModel interface {
models.OriginBaser
SetOriginBase(originBase models.OriginBase)
SetResourceRaw(resourceRaw datatypes.JSON)
+ GetResourceRaw() datatypes.JSON
SetSortTitle(sortTitle *string)
SetSortDate(sortDate *time.Time)
SetSourceUri(sourceUri *string)
@@ -26,6 +27,11 @@ type SearchParameterTokenType []struct {
Text string `json:"text"`
}
+type SearchParameterReferenceType []struct {
+ Reference string `json:"reference"`
+ Display string `json:"display"`
+}
+
type SearchParameterStringType []string
type SearchParameterDateType []struct {
diff --git a/backend/pkg/models/database/searchParameterExtractor.js b/backend/pkg/models/database/searchParameterExtractor.js
index d15fa8e5f..1f399e06c 100644
--- a/backend/pkg/models/database/searchParameterExtractor.js
+++ b/backend/pkg/models/database/searchParameterExtractor.js
@@ -49,6 +49,9 @@ function extractStringSearchParameters(fhirResource, expression){
addressParts.push(currentValue.country)
}
accumulator.push(addressParts.join(" "))
+ } else if (currentValue.status && currentValue.div) {
+ // Text (Narrative - http://hl7.org/fhir/R4/narrative.html#Narrative)
+ accumulator.push(currentValue.div)
} else {
//string, boolean
accumulator.push(currentValue)
diff --git a/backend/pkg/models/database/utils.go b/backend/pkg/models/database/utils.go
index 38e9c844f..39c9d2b28 100644
--- a/backend/pkg/models/database/utils.go
+++ b/backend/pkg/models/database/utils.go
@@ -139,6 +139,124 @@ func NewFhirResourceModelByType(resourceType string) (IFhirResourceModel, error)
}
}
+// Returns a map of all the resource names to their corresponding go struct
+func NewFhirResourceModelSliceByType(resourceType string) (interface{}, error) {
+ switch resourceType {
+ case "Account":
+ return []FhirAccount{}, nil
+ case "AdverseEvent":
+ return []FhirAdverseEvent{}, nil
+ case "AllergyIntolerance":
+ return []FhirAllergyIntolerance{}, nil
+ case "Appointment":
+ return []FhirAppointment{}, nil
+ case "Binary":
+ return []FhirBinary{}, nil
+ case "CarePlan":
+ return []FhirCarePlan{}, nil
+ case "CareTeam":
+ return []FhirCareTeam{}, nil
+ case "Claim":
+ return []FhirClaim{}, nil
+ case "ClaimResponse":
+ return []FhirClaimResponse{}, nil
+ case "Composition":
+ return []FhirComposition{}, nil
+ case "Condition":
+ return []FhirCondition{}, nil
+ case "Consent":
+ return []FhirConsent{}, nil
+ case "Coverage":
+ return []FhirCoverage{}, nil
+ case "CoverageEligibilityRequest":
+ return []FhirCoverageEligibilityRequest{}, nil
+ case "CoverageEligibilityResponse":
+ return []FhirCoverageEligibilityResponse{}, nil
+ case "Device":
+ return []FhirDevice{}, nil
+ case "DeviceRequest":
+ return []FhirDeviceRequest{}, nil
+ case "DiagnosticReport":
+ return []FhirDiagnosticReport{}, nil
+ case "DocumentManifest":
+ return []FhirDocumentManifest{}, nil
+ case "DocumentReference":
+ return []FhirDocumentReference{}, nil
+ case "Encounter":
+ return []FhirEncounter{}, nil
+ case "Endpoint":
+ return []FhirEndpoint{}, nil
+ case "EnrollmentRequest":
+ return []FhirEnrollmentRequest{}, nil
+ case "EnrollmentResponse":
+ return []FhirEnrollmentResponse{}, nil
+ case "ExplanationOfBenefit":
+ return []FhirExplanationOfBenefit{}, nil
+ case "FamilyMemberHistory":
+ return []FhirFamilyMemberHistory{}, nil
+ case "Goal":
+ return []FhirGoal{}, nil
+ case "ImagingStudy":
+ return []FhirImagingStudy{}, nil
+ case "Immunization":
+ return []FhirImmunization{}, nil
+ case "InsurancePlan":
+ return []FhirInsurancePlan{}, nil
+ case "Location":
+ return []FhirLocation{}, nil
+ case "Media":
+ return []FhirMedia{}, nil
+ case "Medication":
+ return []FhirMedication{}, nil
+ case "MedicationAdministration":
+ return []FhirMedicationAdministration{}, nil
+ case "MedicationDispense":
+ return []FhirMedicationDispense{}, nil
+ case "MedicationRequest":
+ return []FhirMedicationRequest{}, nil
+ case "MedicationStatement":
+ return []FhirMedicationStatement{}, nil
+ case "NutritionOrder":
+ return []FhirNutritionOrder{}, nil
+ case "Observation":
+ return []FhirObservation{}, nil
+ case "Organization":
+ return []FhirOrganization{}, nil
+ case "OrganizationAffiliation":
+ return []FhirOrganizationAffiliation{}, nil
+ case "Patient":
+ return []FhirPatient{}, nil
+ case "Person":
+ return []FhirPerson{}, nil
+ case "Practitioner":
+ return []FhirPractitioner{}, nil
+ case "PractitionerRole":
+ return []FhirPractitionerRole{}, nil
+ case "Procedure":
+ return []FhirProcedure{}, nil
+ case "Provenance":
+ return []FhirProvenance{}, nil
+ case "Questionnaire":
+ return []FhirQuestionnaire{}, nil
+ case "QuestionnaireResponse":
+ return []FhirQuestionnaireResponse{}, nil
+ case "RelatedPerson":
+ return []FhirRelatedPerson{}, nil
+ case "Schedule":
+ return []FhirSchedule{}, nil
+ case "ServiceRequest":
+ return []FhirServiceRequest{}, nil
+ case "Slot":
+ return []FhirSlot{}, nil
+ case "Specimen":
+ return []FhirSpecimen{}, nil
+ case "VisionPrescription":
+ return []FhirVisionPrescription{}, nil
+ default:
+ return nil, fmt.Errorf("Invalid resource type for model: %s", resourceType)
+ }
+}
+
// Returns the GORM table name for a FHIRResource when provided the FhirResource type string
func GetTableNameByResourceType(resourceType string) (string, error) {
switch resourceType {
diff --git a/backend/pkg/models/query_resource.go b/backend/pkg/models/query_resource.go
index 88c3f5848..bf099c10b 100644
--- a/backend/pkg/models/query_resource.go
+++ b/backend/pkg/models/query_resource.go
@@ -27,7 +27,7 @@ type QueryResourceAggregations struct {
type QueryResourceAggregation struct {
Field string `json:"field"`
- Function string `json:"fn"`
+ Function string `json:"fn"` //built-in SQL aggregation functions (eg. Count, min, max, etc).
}
func (q *QueryResource) Validate() error {
diff --git a/backend/pkg/models/resource_base.go b/backend/pkg/models/resource_base.go
index a0f3c75a3..7195a9cb4 100644
--- a/backend/pkg/models/resource_base.go
+++ b/backend/pkg/models/resource_base.go
@@ -33,6 +33,9 @@ func (s *ResourceBase) SetSortDate(sortDate *time.Time) {
func (s *ResourceBase) SetResourceRaw(resourceRaw datatypes.JSON) {
s.ResourceRaw = resourceRaw
}
+func (s *ResourceBase) GetResourceRaw() datatypes.JSON {
+ return s.ResourceRaw
+}
func (s *ResourceBase) SetSourceUri(sourceUri *string) {
s.SourceUri = sourceUri
diff --git a/backend/pkg/utils/ips/ips_export_data.go b/backend/pkg/utils/ips/ips_export_data.go
new file mode 100644
index 000000000..de492dd02
--- /dev/null
+++ b/backend/pkg/utils/ips/ips_export_data.go
@@ -0,0 +1,17 @@
+package ips
+
+import (
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models/database"
+ "github.com/fastenhealth/gofhir-models/fhir401"
+ "time"
+)
+
+type InternationalPatientSummaryExportData struct {
+ GenerationDate time.Time
+ Bundle *fhir401.Bundle
+ Composition *fhir401.Composition
+
+ Patient *database.FhirPatient
+ Sources []models.SourceCredential
+}
diff --git a/backend/pkg/utils/ips/render.go b/backend/pkg/utils/ips/render.go
new file mode 100644
index 000000000..4092ab78c
--- /dev/null
+++ b/backend/pkg/utils/ips/render.go
@@ -0,0 +1,174 @@
+package ips
+
+import (
+ "bytes"
+ "embed"
+ "encoding/json"
+ "fmt"
+ sprig "github.com/Masterminds/sprig/v3"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models/database"
+ "github.com/fastenhealth/gofhir-models/fhir401"
+ "gorm.io/datatypes"
+ "html/template"
+ "math"
+)
+
+//go:embed templates
+var ipsTemplates embed.FS
+
+type Narrative struct {
+ Templates *template.Template
+}
+
+// Ideally we'd do this with generics, however IntelliJ `gotype` type hints in Templates don't support generics correctly so we have this ugliness...
+type NarrativeTemplateData struct {
+ Bundle *fhir401.Bundle
+ Composition *fhir401.Composition
+
+ Consent []database.FhirConsent
+ AllergyIntolerance []database.FhirAllergyIntolerance
+ DiagnosticReport []database.FhirDiagnosticReport
+ //ClinicalImpression *database.FhirClinicalImpression
+ Procedure []database.FhirProcedure
+ Immunization []database.FhirImmunization
+ Device []database.FhirDevice
+ MedicationRequest []database.FhirMedicationRequest
+ MedicationStatement []database.FhirMedicationStatement
+ Condition []database.FhirCondition
+ CarePlan []database.FhirCarePlan
+ Observation []database.FhirObservation
+ Encounter []database.FhirEncounter
+ Patient database.FhirPatient
+}
+
+func NewNarrative() (*Narrative, error) {
+ narrative := &Narrative{}
+
+ //parse templates
+ // https://stackoverflow.com/questions/50283370/include-template-from-another-directory
+ // https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-go
+ tmpl, err := template.New("ips").Funcs(template.FuncMap{
+ "safeHTMLPtr": func(s *string) template.HTML {
+ if s == nil {
+ return template.HTML("")
+ }
+ return template.HTML(*s)
+ },
+ "safeHTML": func(s string) template.HTML {
+ return template.HTML(s)
+ },
+ "parseStringList": func(data datatypes.JSON) []string {
+ var parsed []string
+ _ = json.Unmarshal(data, &parsed)
+ return parsed
+ },
+ "parseMapList": func(data datatypes.JSON) []map[string]interface{} {
+ var parsed []map[string]interface{}
+ _ = json.Unmarshal(data, &parsed)
+ return parsed
+ },
+ "pluckList": func(key string, data []map[string]interface{}) []interface{} {
+ values := []interface{}{}
+ for _, item := range data {
+ values = append(values, item[key])
+ }
+ return values
+ },
+ "roundList": func(precision uint, listVals []interface{}) []interface{} {
+ results := []interface{}{}
+ for ndx, _ := range listVals {
+ switch listVal := listVals[ndx].(type) {
+ case float64:
+ ratio := math.Pow(10, float64(precision))
+ results = append(results, math.Round(listVal*ratio)/ratio)
+ default:
+ results = append(results, listVal)
+ }
+ }
+ return results
+ },
+ }).Funcs(sprig.FuncMap()).ParseFS(ipsTemplates, "templates/*.gohtml", "templates/includes/*.gohtml")
+
+ if err != nil {
+ return nil, err
+ }
+ narrative.Templates = tmpl
+ return narrative, nil
+}
+
+func (r *Narrative) GetTemplates() *template.Template {
+ return r.Templates
+}
+
+func (r *Narrative) RenderTemplate(templateName string, data NarrativeTemplateData) (string, error) {
+ var b bytes.Buffer
+ err := r.Templates.ExecuteTemplate(&b, templateName, data)
+ if err != nil {
+ return "", err
+ }
+ return b.String(), nil
+}
+
+func (r *Narrative) RenderSection(sectionType pkg.IPSSections, resources []database.IFhirResourceModel) (string, error) {
+ templateName := fmt.Sprintf("%s.gohtml", sectionType)
+ templateData := NarrativeTemplateData{
+ Bundle: &fhir401.Bundle{},
+ Composition: &fhir401.Composition{},
+
+ AllergyIntolerance: []database.FhirAllergyIntolerance{},
+ CarePlan: []database.FhirCarePlan{},
+ Condition: []database.FhirCondition{},
+ Consent: []database.FhirConsent{},
+ Device: []database.FhirDevice{},
+ DiagnosticReport: []database.FhirDiagnosticReport{},
+ Encounter: []database.FhirEncounter{},
+ Immunization: []database.FhirImmunization{},
+ MedicationRequest: []database.FhirMedicationRequest{},
+ MedicationStatement: []database.FhirMedicationStatement{},
+ Observation: []database.FhirObservation{},
+ Procedure: []database.FhirProcedure{},
+
+ Patient: database.FhirPatient{},
+ }
+
+ //loop though the resources, cast them to the correct type, and then store them in the correct array
+ //this is a bit of a hack, but it's the best way to do it without generics
+
+ for ndx, _ := range resources {
+ resource := resources[ndx]
+ switch resource.GetSourceResourceType() {
+ case "AllergyIntolerance":
+ templateData.AllergyIntolerance = append(templateData.AllergyIntolerance, *resource.(*database.FhirAllergyIntolerance))
+ case "CarePlan":
+ templateData.CarePlan = append(templateData.CarePlan, *resource.(*database.FhirCarePlan))
+ case "Condition":
+ templateData.Condition = append(templateData.Condition, *resource.(*database.FhirCondition))
+ case "Consent":
+ templateData.Consent = append(templateData.Consent, *resource.(*database.FhirConsent))
+ case "Device":
+ templateData.Device = append(templateData.Device, *resource.(*database.FhirDevice))
+ case "DiagnosticReport":
+ templateData.DiagnosticReport = append(templateData.DiagnosticReport, *resource.(*database.FhirDiagnosticReport))
+ case "Encounter":
+ templateData.Encounter = append(templateData.Encounter, *resource.(*database.FhirEncounter))
+ case "Immunization":
+ templateData.Immunization = append(templateData.Immunization, *resource.(*database.FhirImmunization))
+ case "MedicationRequest":
+ templateData.MedicationRequest = append(templateData.MedicationRequest, *resource.(*database.FhirMedicationRequest))
+ case "MedicationStatement":
+ templateData.MedicationStatement = append(templateData.MedicationStatement, *resource.(*database.FhirMedicationStatement))
+ case "Observation":
+ templateData.Observation = append(templateData.Observation, *resource.(*database.FhirObservation))
+ case "Procedure":
+ templateData.Procedure = append(templateData.Procedure, *resource.(*database.FhirProcedure))
+ }
+ }
+
+ var b bytes.Buffer
+ err := r.Templates.ExecuteTemplate(&b, templateName, templateData)
+ if err != nil {
+ return "", err
+ }
+ return b.String(), nil
+}
diff --git a/backend/pkg/utils/ips/render_test.go b/backend/pkg/utils/ips/render_test.go
new file mode 100644
index 000000000..60acff028
--- /dev/null
+++ b/backend/pkg/utils/ips/render_test.go
@@ -0,0 +1,54 @@
+package ips
+
+import (
+ "github.com/fastenhealth/fasten-onprem/backend/pkg"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/models/database"
+ "github.com/stretchr/testify/require"
+ "testing"
+)
+
+func TestNarrative_RenderSection(t *testing.T) {
+ tests := []struct {
+ name string
+ sectionType pkg.IPSSections
+ resources []database.IFhirResourceModel
+
+ want string
+ wantErr bool
+ }{
+ {
+ name: "Test Narrative_RenderSection",
+ sectionType: pkg.IPSSectionsAllergiesIntolerances,
+ resources: []database.IFhirResourceModel{
+ &database.FhirAllergyIntolerance{
+ ResourceBase: models.ResourceBase{
+ OriginBase: models.OriginBase{
+ SourceResourceType: "AllergyIntolerance",
+ SourceResourceID: "1",
+ },
+ },
+ Code: []byte(`[
+ {"code":"891830","system":"http://www.nlm.nih.gov/research/umls/rxnorm","text":"banana (May be Banana (Diagnostic))"},
+ {"code":"93174","system":"urn:oid:2.16.840.1.113883.13.80","text":"banana (May be Banana (Diagnostic))"}
+ ]`),
+ ClinicalStatus: []byte(`[{"code":"active","system":"http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical","text":"Active"}]`),
+ Category: []byte(`[{"code":"environment"}]`),
+ },
+ },
+ want: "",
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ n, err := NewNarrative()
+ require.NoError(t, err)
+ got, err := n.RenderSection(tt.sectionType, tt.resources)
+ require.NoError(t, err, "RenderSection() error = %v, wantErr %v", err, tt.wantErr)
+ if got != tt.want {
+ t.Errorf("RenderSection() got = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/backend/pkg/utils/ips/templates/advance_directives.gohtml b/backend/pkg/utils/ips/templates/advance_directives.gohtml
new file mode 100644
index 000000000..1855612b6
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/advance_directives.gohtml
@@ -0,0 +1,36 @@
+
+
+
+
Advance Directives
+
+
+
+ Scope |
+ Status |
+ Action Controlled |
+ Date |
+
+
+
+
+
+
+
+ Scope |
+ Status |
+ Action Controlled |
+ Date |
+
+
+
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/allergies_intolerances.gohtml b/backend/pkg/utils/ips/templates/allergies_intolerances.gohtml
new file mode 100644
index 000000000..1c2625eee
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/allergies_intolerances.gohtml
@@ -0,0 +1,42 @@
+
+
+
+
Allergies And Intolerances
+
+
+
+ Allergen |
+ Status |
+ Category |
+ Reaction |
+ Severity |
+ Comments |
+ Onset |
+
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .AllergyIntolerance }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Allergen */}}
+ {{pluckList "code" ($entry.ClinicalStatus | parseMapList) | uniq | join "," }} | {{/* Status */}}
+ {{pluckList "code" ($entry.Category | parseMapList) | uniq | join "," }} | {{/* Category */}}
+ {{pluckList "text" ($entry.Manifestation | parseMapList) | uniq | join "," }} | {{/* Reaction */}}
+ {{pluckList "code" ($entry.Criticality | parseMapList) | uniq | join ","}} | {{/* Severity */}}
+ Comments | {{/* Comments - TODO: use FHIRPath */}}
+ {{default "unknown" $entry.Onset }} | {{/* Onset */}}
+
+ {{end}}
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/composition.gohtml b/backend/pkg/utils/ips/templates/composition.gohtml
new file mode 100644
index 000000000..65547445b
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/composition.gohtml
@@ -0,0 +1,19 @@
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData */ -}}
+ {{range $index, $section := .Composition.Section }}
+
+ {{$section.Title}}
+
+ {{if eq $section.Text nil }}
+ {{$section.EmptyReason.Text}}
+ {{else }}
+ {{$section.Text.Div | safeHTMLPtr}}
+ {{end}}
+
+
+ {{end}}
+
diff --git a/backend/pkg/utils/ips/templates/diagnostic_results.gohtml b/backend/pkg/utils/ips/templates/diagnostic_results.gohtml
new file mode 100644
index 000000000..560007cd5
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/diagnostic_results.gohtml
@@ -0,0 +1,88 @@
+
+
+
+
+ Diagnostic Results: Observations
+
+
+
+ Code |
+ Result |
+ Unit |
+ Interpretation |
+ Reference Range |
+ Comments |
+ Date |
+
+
+
+
+
+
+
+
+ Code
+ |
+ Result |
+ Unit |
+
+ Interpretation
+ |
+
+ Reference
+ Range
+ |
+ Comments |
+ Date |
+
+
+
+
+
+
+
+
+
+
+ Diagnostic Results: Diagnostic Reports
+
+
+
+ Code |
+ Date |
+
+
+
+
+
+
+
+
+ Device
+ |
+ Date |
+
+
+
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/functional_status.gohtml b/backend/pkg/utils/ips/templates/functional_status.gohtml
new file mode 100644
index 000000000..a569efadf
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/functional_status.gohtml
@@ -0,0 +1,37 @@
+
+
+
+
Functional Status
+
+
+
+ Assessment |
+ Status |
+ Finding |
+ Comments |
+ Date |
+
+
+
+
+
+
+
+ Assessment |
+ Status |
+ Finding |
+ Comments |
+ Date |
+
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/history_of_illness.gohtml b/backend/pkg/utils/ips/templates/history_of_illness.gohtml
new file mode 100644
index 000000000..4e83b4650
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/history_of_illness.gohtml
@@ -0,0 +1,31 @@
+
+
+
+
Past History of Illnesses
+
+
+
+ Medical Problems |
+ Status |
+ Comments |
+ Date |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Condition }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Medical Problem */}}
+ {{pluckList "code" ($entry.ClinicalStatus | parseMapList) | uniq | join "," }} | {{/* Status */}}
+ Comments | {{/* Comments - TODO: use FHIRPath */}}
+ {{$entry.OnsetDate | date "2006-01-02"}} | {{/* Onset */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/history_of_procedures.gohtml b/backend/pkg/utils/ips/templates/history_of_procedures.gohtml
new file mode 100644
index 000000000..e985b792c
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/history_of_procedures.gohtml
@@ -0,0 +1,30 @@
+
+
+
+
History Of Procedures
+
+
+
+ Procedure |
+ Comments |
+ Date |
+
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Procedure }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Procedure */}}
+ Comments | {{/* Comments - TODO: use FHIRPath */}}
+ {{$entry.Date | date "2006-01-02"}} | {{/* Performed Date */}}
+
+ {{end}}
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/immunizations.gohtml b/backend/pkg/utils/ips/templates/immunizations.gohtml
new file mode 100644
index 000000000..e782ce87d
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/immunizations.gohtml
@@ -0,0 +1,42 @@
+
+
+
+
Immunizations
+
+
+
+ Immunization |
+ Status |
+ Dose Number |
+ Manufacturer |
+ Lot Number |
+ Comments |
+ Date |
+
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Immunization }}
+
+ {{pluckList "text" ($entry.VaccineCode | parseMapList) | uniq | join "," }} | {{/* Immunization */}}
+ {{pluckList "code" ($entry.Status | parseMapList) | uniq | join "," }} | {{/* Status */}}
+ Dose Number | {{/* Comments - TODO: use FHIRPath */}}
+ {{pluckList "display" ($entry.Manufacturer | parseMapList) | uniq | join "," }} | {{/* Manufacturer */}}
+ {{$entry.LotNumber}} | {{/* Lot Number */}}
+ Comments |
+ {{$entry.Date | date "2006-01-02"}} | {{/* Performed Date */}}
+
+ {{end}}
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/includes/footer.gohtml b/backend/pkg/utils/ips/templates/includes/footer.gohtml
new file mode 100644
index 000000000..06bc0176f
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/footer.gohtml
@@ -0,0 +1 @@
+ footer hello world
diff --git a/backend/pkg/utils/ips/templates/includes/header.gohtml b/backend/pkg/utils/ips/templates/includes/header.gohtml
new file mode 100644
index 000000000..cd58842d8
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/header.gohtml
@@ -0,0 +1,101 @@
+{{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+
+
+
+
{{.Patient.Name | parseStringList | uniq | first}}
+
Patient Health Summary; Generated: {{.Composition.Date | date "2006-01-02"}}
+
+ ID: {{.Composition.Identifier.Value}}
+
+
+
+
+
Author: {{.Composition.Identifier.System}}
+
+
+
+
+
+
+
+
+
+ Born |
+ Language |
+ Race/Ethnicity |
+ Address |
+ Phone |
+
+
+
+
+
+ {{default "Unknown" (.Patient.Birthdate | date "2006-01-02")}}
+ |
+
+ {{default "Unknown" (.Patient.Language | parseMapList | pluckList "text" | join ",")}}
+ |
+
+ Unknown / Unknown
+ |
+
+ {{default "Unknown" (.Patient.Address | parseStringList | uniq | join " " | safeHTML)}}
+ |
+
+ {{default "Unknown" (.Patient.Phone | parseStringList | uniq | join ", ")}}
+ |
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/includes/observation-unit.gohtml b/backend/pkg/utils/ips/templates/includes/observation-unit.gohtml
new file mode 100644
index 000000000..b40409039
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/observation-unit.gohtml
@@ -0,0 +1,11 @@
+{{if not (empty (.ValueString | parseMapList)) }}
+ {{.ValueString}}
+{{else if not (empty (.ValueQuantity | parseMapList)) }}
+ {{.ValueQuantity | parseMapList | pluckList "unit" | join "," }}
+{{else if not (empty .ValueDate) }}
+ {{.ValueDate | date "2006-01-02" }}
+{{else if not (empty (.ValueConcept | parseMapList)) }}
+ {{.ValueConcept}}
+{{else if not (empty (.ComponentValueQuantity | parseMapList)) }}
+ {{.ComponentValueQuantity | parseMapList | pluckList "unit" | join "," }}
+{{end}}
diff --git a/backend/pkg/utils/ips/templates/includes/observation-value.gohtml b/backend/pkg/utils/ips/templates/includes/observation-value.gohtml
new file mode 100644
index 000000000..cdfc74632
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/observation-value.gohtml
@@ -0,0 +1,32 @@
+{{if not (empty (.entry.ValueString | parseMapList)) }}
+ {{.entry.ValueString | parseStringList | join ","}}
+{{else if not (empty (.entry.ValueQuantity | parseMapList)) }}
+ {{.entry.ValueQuantity | parseMapList | pluckList "value" | roundList 2 | join "," }}
+ {{if (get . "include_unit")}}
+ {{.entry.ValueQuantity | parseMapList | pluckList "unit" | join "," }}
+ {{end}}
+{{else if not (empty .entry.ValueDate) }}
+ {{.entry.ValueDate | date "2006-01-02" }}
+{{else if not (empty (.entry.ValueConcept | parseMapList)) }}
+ {{.entry.ValueConcept}}
+{{else if not (empty (.entry.ComponentValueQuantity | parseMapList)) }}
+ {{$componentCodeText := .entry.ComponentCode | parseMapList | pluckList "text" }}
+ {{$componentValueQuantity := .entry.ComponentValueQuantity | parseMapList | pluckList "value" | roundList 2 }}
+ {{$componentValueQuantityUnit := .entry.ComponentValueQuantity | parseMapList | pluckList "unit" }}
+
+
+ {{range $index, $text := $componentCodeText }}
+ {{$text}}
+ {{if lt $index (len $componentValueQuantity)}}
+ - {{index $componentValueQuantity $index}}
+ {{end}}
+ {{if (get $ "include_unit")}}
+ {{if lt $index (len $componentValueQuantityUnit)}}
+ {{index $componentValueQuantityUnit $index}}
+ {{end}}
+ {{end}}
+
+ {{end}}
+
+
+{{end}}
diff --git a/backend/pkg/utils/ips/templates/includes/styles.gohtml b/backend/pkg/utils/ips/templates/includes/styles.gohtml
new file mode 100644
index 000000000..6a0b38900
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/styles.gohtml
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/includes/toc.gohtml b/backend/pkg/utils/ips/templates/includes/toc.gohtml
new file mode 100644
index 000000000..e7fc41243
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/toc.gohtml
@@ -0,0 +1 @@
+table of contents
diff --git a/backend/pkg/utils/ips/templates/includes/utility-fragments.gohtml b/backend/pkg/utils/ips/templates/includes/utility-fragments.gohtml
new file mode 100644
index 000000000..3dea18d43
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/includes/utility-fragments.gohtml
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+ Device
+
+
+
+
+
+
+
+
+
+ Org Name
+
+
+
+
+
+
+
+
+
+ Medication
+
+
+ Medication
+
+
+
+
+
+
+
+
+ Medication
+
+
+
+
+
+
+ Medication
+
+
+
+
+
+
+
+
+ Dose Number
+ Dose Number
+
+
+
+
+
+
+
+
+
+ Result
+ Result
+
+ Result
+
+ Result
+
+
+
+
+
+
+
+ Unit
+
+
+
+
+
+
+
+
+
+ Date
+ Date
+
+
+
+
+
+
+
+ Date
+
+ Date
+
+ Date
+ Date
+
+ Date
+
+
+
+
+
+
+
+ Date
+
+ Date
+
+ Date
+ Date
+
+ Date
+
+
+
+
+
+
+
+ Date
+ Date
+
+
+
+
+
+
+
+ Date Recorded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Interpretation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reaction
+
+ Reaction
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dose Number
+
+
+
+
+
+
+ Reference Range
+
+ Reference Range
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/index.gohtml b/backend/pkg/utils/ips/templates/index.gohtml
new file mode 100644
index 000000000..b3f149fb6
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/index.gohtml
@@ -0,0 +1,25 @@
+{{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+
+
+
+
+ title
+
+
+ {{template "styles.gohtml" .}}
+
+
+
+{{template "header.gohtml" .}}
+{{template "toc.gohtml" .}}
+
+
+ {{template "composition.gohtml" .}}
+
+
+{{template "footer.gohtml" .}}
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/medical_devices.gohtml b/backend/pkg/utils/ips/templates/medical_devices.gohtml
new file mode 100644
index 000000000..86421f7e5
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/medical_devices.gohtml
@@ -0,0 +1,31 @@
+
+
+
+
Medical Devices
+
+
+
+ Device |
+ Status |
+ Comments |
+ Date Recorded |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Device }}
+
+ {{pluckList "text" ($entry.Type | parseMapList) | uniq | join "," }} | {{/* Device */}}
+ {{pluckList "code" ($entry.Status | parseMapList) | uniq | join "," }} | {{/* Status */}}
+ Comments |
+ | {{/* Date Recorded */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/medication_summary.gohtml b/backend/pkg/utils/ips/templates/medication_summary.gohtml
new file mode 100644
index 000000000..ed4a8f128
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/medication_summary.gohtml
@@ -0,0 +1,93 @@
+
+
+
+
+
+ Medication Summary: Medication Requests
+
+
+
+ Medication |
+ Status |
+ Route |
+ Sig |
+ Comments |
+ Authored Date |
+
+
+
+
+
+
+
+
+
+ Medication
+ |
+ Status |
+
+ Route
+ |
+
+ Sig
+ |
+ Comments |
+ Authored Date |
+
+
+
+
+
+
+
+
+
+
+ Medication Summary: Medication Statements
+
+
+
+ Medication |
+ Status |
+ Route |
+ Sig |
+ Date |
+
+
+
+
+
+
+
+
+ Medication
+ |
+ Status |
+ Route |
+ Sig |
+ Date |
+
+
+
+
+
+
+
+
diff --git a/backend/pkg/utils/ips/templates/plan_of_care.gohtml b/backend/pkg/utils/ips/templates/plan_of_care.gohtml
new file mode 100644
index 000000000..a88e45d34
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/plan_of_care.gohtml
@@ -0,0 +1,34 @@
+
+
+
+
Plan of Care
+
+
+
+ Activity |
+ Intent |
+ Comments |
+ Planned Start |
+ Planned End |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .CarePlan }}
+
+ Activity |
+ {{pluckList "code" ($entry.Intent | parseMapList) | uniq | join "," }} | {{/* Intent */}}
+ Comments |
+ {{$entry.Date}} | {{/* Planned Start */}}
+ Planned End |
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/pregnancy.gohtml b/backend/pkg/utils/ips/templates/pregnancy.gohtml
new file mode 100644
index 000000000..01cc7fd6f
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/pregnancy.gohtml
@@ -0,0 +1,31 @@
+
+
+
+
Pregnancy
+
+
+
+ Code |
+ Result |
+ Comments |
+ Date |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Observation }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Code */}}
+ {{template "observation-value.gohtml" (dict "entry" $entry "include_unit" true)}} | {{/* Result */}}
+ Comments |
+ {{$entry.Date | date "2006-01-02"}} | {{/* Date */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/problem_list.gohtml b/backend/pkg/utils/ips/templates/problem_list.gohtml
new file mode 100644
index 000000000..42f5055ee
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/problem_list.gohtml
@@ -0,0 +1,31 @@
+
+
+
+
Problem List
+
+
+
+ Medical Problems |
+ Status |
+ Comments |
+ Onset Date |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Condition }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Medical Problems */}}
+ {{pluckList "code" ($entry.ClinicalStatus | parseMapList) | uniq | join "," }} | {{/* Status */}}
+ Comments |
+ {{$entry.OnsetDate | date "2006-01-02"}} | {{/* Onset */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/social_history.gohtml b/backend/pkg/utils/ips/templates/social_history.gohtml
new file mode 100644
index 000000000..a7c482c75
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/social_history.gohtml
@@ -0,0 +1,34 @@
+
+
+
+
Social History
+
+
+
+ Code |
+ Result |
+ Unit |
+ Comments |
+ Date |
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Observation }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Code */}}
+ {{template "observation-value.gohtml" (dict "entry" $entry "include_unit" false)}} | {{/* Result */}}
+ Unit |
+ Comments |
+ {{$entry.Date | date "2006-01-02"}} | {{/* Date */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/utils/ips/templates/vital_signs.gohtml b/backend/pkg/utils/ips/templates/vital_signs.gohtml
new file mode 100644
index 000000000..7870aca8f
--- /dev/null
+++ b/backend/pkg/utils/ips/templates/vital_signs.gohtml
@@ -0,0 +1,38 @@
+
+
+
+
Vital Signs
+
+
+
+ Code |
+ Result |
+ Unit |
+ Interpretation |
+ Comments |
+ Date |
+
+
+
+
+ {{- /*gotype: github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips.NarrativeTemplateData*/ -}}
+ {{range $index, $entry := .Observation }}
+
+ {{pluckList "text" ($entry.Code | parseMapList) | uniq | join "," }} | {{/* Code */}}
+ {{template "observation-value.gohtml" (dict "entry" $entry "include_unit" false)}} | {{/* Result */}}
+ {{template "observation-unit.gohtml" $entry}} |
+ Interpretation |
+ Comments |
+ {{$entry.Date | date "2006-01-02"}} | {{/* Date */}}
+
+ {{end}}
+
+
+
diff --git a/backend/pkg/web/handler/summary.go b/backend/pkg/web/handler/summary.go
index 068238bfd..e17770743 100644
--- a/backend/pkg/web/handler/summary.go
+++ b/backend/pkg/web/handler/summary.go
@@ -1,8 +1,10 @@
package handler
import (
+ _ "embed"
"github.com/fastenhealth/fasten-onprem/backend/pkg"
"github.com/fastenhealth/fasten-onprem/backend/pkg/database"
+ "github.com/fastenhealth/fasten-onprem/backend/pkg/utils/ips"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"net/http"
@@ -20,3 +22,51 @@ func GetSummary(c *gin.Context) {
}
c.JSON(http.StatusOK, gin.H{"success": true, "data": summary})
}
+
+func GetIPSSummary(c *gin.Context) {
+ logger := c.MustGet(pkg.ContextKeyTypeLogger).(*logrus.Entry)
+ databaseRepo := c.MustGet(pkg.ContextKeyTypeDatabase).(database.DatabaseRepository)
+
+ ipsExport, err := databaseRepo.GetInternationalPatientSummaryExport(c)
+ if err != nil {
+ logger.Errorln("An error occurred while retrieving IPS summary", err)
+ c.JSON(http.StatusInternalServerError, gin.H{"success": false})
+ return
+ }
+
+ if c.Query("format") == "" {
+ c.JSON(http.StatusOK, gin.H{"success": true, "data": ipsExport.Bundle})
+ return
+ }
+
+ narrative, err := ips.NewNarrative()
+ if err != nil {
+ logger.Errorln("An error occurred while parsing template", err)
+ c.JSON(http.StatusInternalServerError, gin.H{"success": false})
+ return
+ }
+
+ composititon := ipsExport.Composition
+
+ if c.Query("format") == "html" {
+
+ logger.Debugln("Rendering HTML")
+ //create string writer
+ content, err := narrative.RenderTemplate("index.gohtml", ips.NarrativeTemplateData{Composition: composititon, Patient: *ipsExport.Patient})
+ if err != nil {
+ logger.Errorln("An error occurred while executing template", err)
+ c.JSON(http.StatusInternalServerError, gin.H{"success": false})
+ return
+ }
+ c.Header("Content-Type", "text/html; charset=utf-8")
+ c.String(http.StatusOK, content)
+ return
+ }
+ //} else if c.Query("format") == "pdf" {
+ //
+ // c.Header("Content-Disposition", "attachment; filename=ips_summary.pdf")
+ // c.Header("Content-Type", "application/pdf")
+ // c.String(http.StatusOK, b.String())
+ // return
+ //}
+}
diff --git a/backend/pkg/web/server.go b/backend/pkg/web/server.go
index 1d6eac818..93a6570d8 100644
--- a/backend/pkg/web/server.go
+++ b/backend/pkg/web/server.go
@@ -100,6 +100,7 @@ func (ae *AppEngine) Setup() (*gin.RouterGroup, *gin.Engine) {
secure.DELETE("/account/me", handler.DeleteAccount)
secure.GET("/summary", handler.GetSummary)
+ secure.GET("/summary/ips", handler.GetIPSSummary)
secure.POST("/source", handler.CreateReconnectSource)
secure.POST("/source/manual", handler.CreateManualSource)
diff --git a/frontend/src/app/components/report-header/report-header.component.html b/frontend/src/app/components/report-header/report-header.component.html
index 58723ec34..148fcd645 100644
--- a/frontend/src/app/components/report-header/report-header.component.html
+++ b/frontend/src/app/components/report-header/report-header.component.html
@@ -33,7 +33,7 @@ All Sources
diff --git a/frontend/src/app/components/report-header/report-header.component.ts b/frontend/src/app/components/report-header/report-header.component.ts
index b77053c0b..86db49a75 100644
--- a/frontend/src/app/components/report-header/report-header.component.ts
+++ b/frontend/src/app/components/report-header/report-header.component.ts
@@ -41,5 +41,9 @@ export class ReportHeaderComponent implements OnInit {
}
})
}
+ getIPSExport(event: Event){
+ event.preventDefault()
+ return this.fastenApi.getIPSExport()
+ }
}
diff --git a/frontend/src/app/services/fasten-api.service.ts b/frontend/src/app/services/fasten-api.service.ts
index acf5bccbe..8b6d2944e 100644
--- a/frontend/src/app/services/fasten-api.service.ts
+++ b/frontend/src/app/services/fasten-api.service.ts
@@ -368,4 +368,54 @@ export class FastenApiService {
);
}
+ getIPSExport(exportType?: string) {
+ // // PDF
+ //
+ // // function openPdf($event) {
+ // // Prevent default behavior when clicking a link
+ // $event.preventDefault();
+ //
+ // // Get filename from href
+ // var filename = $event.target.href;
+ //
+ // $http.get('/api/secure/summary/ips?format=html', {responseType: 'arraybuffer'})
+ // .success(function (data) {
+ // var file = new Blob([data], {type: 'application/pdf'});
+ // var fileURL = URL.createObjectURL(file);
+ //
+ // // Open new windows and show PDF
+ // window.open(fileURL);
+ // });
+ //
+ // $vent.
+ // // }
+
+ let httpHeaders = new HttpHeaders();
+ //.set('Content-Type'
+ httpHeaders.set('Accept', 'text/html');
+
+
+ let queryParams = {
+ "format": exportType || "html"
+ }
+ console.log("requesting", `${GetEndpointAbsolutePath(globalThis.location, environment.fasten_api_endpoint_base)}/secure/summary/ips`)
+ return this._httpClient.get(`${GetEndpointAbsolutePath(globalThis.location, environment.fasten_api_endpoint_base)}/secure/summary/ips`, {
+ params: queryParams,
+ headers: httpHeaders,
+ // observe: 'response',
+ // @ts-ignore
+ responseType: 'arraybuffer'
+ })
+ .subscribe((data) => {
+
+ var file = new Blob([data]);
+ var fileURL = URL.createObjectURL(file);
+
+ // Open new windows and show PDF or HTML file
+ window.open(fileURL, "_blank");
+
+ });
+
+ }
+
}
diff --git a/frontend/src/assets/banner/banner-transparent.svg b/frontend/src/assets/banner/banner-transparent.svg
new file mode 100644
index 000000000..addab89ae
--- /dev/null
+++ b/frontend/src/assets/banner/banner-transparent.svg
@@ -0,0 +1,49 @@
+
+
+
diff --git a/frontend/src/assets/sources/04cee620-af39-4d39-8f39-a083e66c2575.png b/frontend/src/assets/sources/04cee620-af39-4d39-8f39-a083e66c2575.png
index 6eb2f215e..125f942b7 100644
Binary files a/frontend/src/assets/sources/04cee620-af39-4d39-8f39-a083e66c2575.png and b/frontend/src/assets/sources/04cee620-af39-4d39-8f39-a083e66c2575.png differ
diff --git a/frontend/src/assets/sources/0818eba3-9dde-4715-9240-d6f43e24602d.png b/frontend/src/assets/sources/0818eba3-9dde-4715-9240-d6f43e24602d.png
index a7b22cb02..b613232b6 100644
Binary files a/frontend/src/assets/sources/0818eba3-9dde-4715-9240-d6f43e24602d.png and b/frontend/src/assets/sources/0818eba3-9dde-4715-9240-d6f43e24602d.png differ
diff --git a/frontend/src/assets/sources/1010c410-9cde-46b4-b497-30a49d7c52f9.png b/frontend/src/assets/sources/1010c410-9cde-46b4-b497-30a49d7c52f9.png
index f0d51d5b9..a3fa0fada 100644
Binary files a/frontend/src/assets/sources/1010c410-9cde-46b4-b497-30a49d7c52f9.png and b/frontend/src/assets/sources/1010c410-9cde-46b4-b497-30a49d7c52f9.png differ
diff --git a/frontend/src/assets/sources/15ff9fe5-57eb-4483-ab1a-f75ed9204556.png b/frontend/src/assets/sources/15ff9fe5-57eb-4483-ab1a-f75ed9204556.png
index 341895c8b..64af2a617 100644
Binary files a/frontend/src/assets/sources/15ff9fe5-57eb-4483-ab1a-f75ed9204556.png and b/frontend/src/assets/sources/15ff9fe5-57eb-4483-ab1a-f75ed9204556.png differ
diff --git a/frontend/src/assets/sources/1ac27911-47ab-4768-8f3b-9c4dd20efbed.png b/frontend/src/assets/sources/1ac27911-47ab-4768-8f3b-9c4dd20efbed.png
index c85b914f5..5a7f91be9 100644
Binary files a/frontend/src/assets/sources/1ac27911-47ab-4768-8f3b-9c4dd20efbed.png and b/frontend/src/assets/sources/1ac27911-47ab-4768-8f3b-9c4dd20efbed.png differ
diff --git a/frontend/src/assets/sources/20ac8143-daac-4c68-8f37-b518351f6e75.png b/frontend/src/assets/sources/20ac8143-daac-4c68-8f37-b518351f6e75.png
index f31153d27..f91913cd0 100644
Binary files a/frontend/src/assets/sources/20ac8143-daac-4c68-8f37-b518351f6e75.png and b/frontend/src/assets/sources/20ac8143-daac-4c68-8f37-b518351f6e75.png differ
diff --git a/frontend/src/assets/sources/2e7caeeb-5b3d-421c-9fb9-2f5453547f13.png b/frontend/src/assets/sources/2e7caeeb-5b3d-421c-9fb9-2f5453547f13.png
index bf113da13..c084e165d 100644
Binary files a/frontend/src/assets/sources/2e7caeeb-5b3d-421c-9fb9-2f5453547f13.png and b/frontend/src/assets/sources/2e7caeeb-5b3d-421c-9fb9-2f5453547f13.png differ
diff --git a/frontend/src/assets/sources/3aa0125e-1b02-49f9-a287-da4a320017ee.png b/frontend/src/assets/sources/3aa0125e-1b02-49f9-a287-da4a320017ee.png
index 1b46237f4..f950818e9 100644
Binary files a/frontend/src/assets/sources/3aa0125e-1b02-49f9-a287-da4a320017ee.png and b/frontend/src/assets/sources/3aa0125e-1b02-49f9-a287-da4a320017ee.png differ
diff --git a/frontend/src/assets/sources/41dd89d6-276c-41ac-ae6c-71c6e9df9910.png b/frontend/src/assets/sources/41dd89d6-276c-41ac-ae6c-71c6e9df9910.png
index d6a8c2531..85e37a600 100644
Binary files a/frontend/src/assets/sources/41dd89d6-276c-41ac-ae6c-71c6e9df9910.png and b/frontend/src/assets/sources/41dd89d6-276c-41ac-ae6c-71c6e9df9910.png differ
diff --git a/frontend/src/assets/sources/4d544584-e166-4cdf-9030-68b68a47e95d.png b/frontend/src/assets/sources/4d544584-e166-4cdf-9030-68b68a47e95d.png
index ebd2eb093..4a50ec973 100644
Binary files a/frontend/src/assets/sources/4d544584-e166-4cdf-9030-68b68a47e95d.png and b/frontend/src/assets/sources/4d544584-e166-4cdf-9030-68b68a47e95d.png differ
diff --git a/frontend/src/assets/sources/595c488a-6f16-470a-b795-dede8b0dbdc9.png b/frontend/src/assets/sources/595c488a-6f16-470a-b795-dede8b0dbdc9.png
index 1d8bdae4b..8e6c8f18b 100644
Binary files a/frontend/src/assets/sources/595c488a-6f16-470a-b795-dede8b0dbdc9.png and b/frontend/src/assets/sources/595c488a-6f16-470a-b795-dede8b0dbdc9.png differ
diff --git a/frontend/src/assets/sources/5be6c92b-ae9c-4ad5-9db6-341981072313.png b/frontend/src/assets/sources/5be6c92b-ae9c-4ad5-9db6-341981072313.png
index 29bc081fe..ebcca7ee2 100644
Binary files a/frontend/src/assets/sources/5be6c92b-ae9c-4ad5-9db6-341981072313.png and b/frontend/src/assets/sources/5be6c92b-ae9c-4ad5-9db6-341981072313.png differ
diff --git a/frontend/src/assets/sources/68d3119a-61d8-4086-a564-1033f8dd39b1.png b/frontend/src/assets/sources/68d3119a-61d8-4086-a564-1033f8dd39b1.png
index 03f483eaa..9644c5392 100644
Binary files a/frontend/src/assets/sources/68d3119a-61d8-4086-a564-1033f8dd39b1.png and b/frontend/src/assets/sources/68d3119a-61d8-4086-a564-1033f8dd39b1.png differ
diff --git a/frontend/src/assets/sources/7321fe44-7967-4544-bc9a-38c1e6bff97f.png b/frontend/src/assets/sources/7321fe44-7967-4544-bc9a-38c1e6bff97f.png
index bd0e485cb..55934b74a 100644
Binary files a/frontend/src/assets/sources/7321fe44-7967-4544-bc9a-38c1e6bff97f.png and b/frontend/src/assets/sources/7321fe44-7967-4544-bc9a-38c1e6bff97f.png differ
diff --git a/frontend/src/assets/sources/7b5c9f5e-9750-4394-a07c-f2c707b11960.png b/frontend/src/assets/sources/7b5c9f5e-9750-4394-a07c-f2c707b11960.png
index cd738ba9f..7413f6e0a 100644
Binary files a/frontend/src/assets/sources/7b5c9f5e-9750-4394-a07c-f2c707b11960.png and b/frontend/src/assets/sources/7b5c9f5e-9750-4394-a07c-f2c707b11960.png differ
diff --git a/frontend/src/assets/sources/7cd62665-7458-436f-b19e-5f55f42b1887.png b/frontend/src/assets/sources/7cd62665-7458-436f-b19e-5f55f42b1887.png
index 4d3de6059..8f84cd47f 100644
Binary files a/frontend/src/assets/sources/7cd62665-7458-436f-b19e-5f55f42b1887.png and b/frontend/src/assets/sources/7cd62665-7458-436f-b19e-5f55f42b1887.png differ
diff --git a/frontend/src/assets/sources/8c99ab4c-b467-4454-957a-98f2f025a130.png b/frontend/src/assets/sources/8c99ab4c-b467-4454-957a-98f2f025a130.png
index d01587720..424b20e73 100644
Binary files a/frontend/src/assets/sources/8c99ab4c-b467-4454-957a-98f2f025a130.png and b/frontend/src/assets/sources/8c99ab4c-b467-4454-957a-98f2f025a130.png differ
diff --git a/frontend/src/assets/sources/92b014ed-8f8a-4ebc-844c-967368286cd0.png b/frontend/src/assets/sources/92b014ed-8f8a-4ebc-844c-967368286cd0.png
index 472ca0c5e..6d94db637 100644
Binary files a/frontend/src/assets/sources/92b014ed-8f8a-4ebc-844c-967368286cd0.png and b/frontend/src/assets/sources/92b014ed-8f8a-4ebc-844c-967368286cd0.png differ
diff --git a/frontend/src/assets/sources/940b2b83-e259-4fa5-b601-a7608d078e92.png b/frontend/src/assets/sources/940b2b83-e259-4fa5-b601-a7608d078e92.png
new file mode 100644
index 000000000..8f24cf896
Binary files /dev/null and b/frontend/src/assets/sources/940b2b83-e259-4fa5-b601-a7608d078e92.png differ
diff --git a/frontend/src/assets/sources/9532878a-4850-45ee-bd58-1d6422021b9c.png b/frontend/src/assets/sources/9532878a-4850-45ee-bd58-1d6422021b9c.png
index 0308e1f1f..f8850d56a 100644
Binary files a/frontend/src/assets/sources/9532878a-4850-45ee-bd58-1d6422021b9c.png and b/frontend/src/assets/sources/9532878a-4850-45ee-bd58-1d6422021b9c.png differ
diff --git a/frontend/src/assets/sources/966e70b6-eb51-40f8-ad63-89bd77d28927.png b/frontend/src/assets/sources/966e70b6-eb51-40f8-ad63-89bd77d28927.png
index a5b6cffd3..47c3333da 100644
Binary files a/frontend/src/assets/sources/966e70b6-eb51-40f8-ad63-89bd77d28927.png and b/frontend/src/assets/sources/966e70b6-eb51-40f8-ad63-89bd77d28927.png differ
diff --git a/frontend/src/assets/sources/986139aa-d14b-4215-bdd1-f25f812741b0.png b/frontend/src/assets/sources/986139aa-d14b-4215-bdd1-f25f812741b0.png
index a12d1a5b1..e57ec1c6f 100644
Binary files a/frontend/src/assets/sources/986139aa-d14b-4215-bdd1-f25f812741b0.png and b/frontend/src/assets/sources/986139aa-d14b-4215-bdd1-f25f812741b0.png differ
diff --git a/frontend/src/assets/sources/a0dcfff4-b168-4766-b7f3-5269a1eb6b2b.png b/frontend/src/assets/sources/a0dcfff4-b168-4766-b7f3-5269a1eb6b2b.png
index 72ba34214..1f9d3340f 100644
Binary files a/frontend/src/assets/sources/a0dcfff4-b168-4766-b7f3-5269a1eb6b2b.png and b/frontend/src/assets/sources/a0dcfff4-b168-4766-b7f3-5269a1eb6b2b.png differ
diff --git a/frontend/src/assets/sources/a5c6977a-00e2-4c12-8ccd-587105bd17c9.png b/frontend/src/assets/sources/a5c6977a-00e2-4c12-8ccd-587105bd17c9.png
index 35b391b42..3c6ff1860 100644
Binary files a/frontend/src/assets/sources/a5c6977a-00e2-4c12-8ccd-587105bd17c9.png and b/frontend/src/assets/sources/a5c6977a-00e2-4c12-8ccd-587105bd17c9.png differ
diff --git a/frontend/src/assets/sources/ab4c5504-d780-4da6-b512-4fbb0ab05d7e.png b/frontend/src/assets/sources/ab4c5504-d780-4da6-b512-4fbb0ab05d7e.png
index 693c187df..37a7ec46a 100644
Binary files a/frontend/src/assets/sources/ab4c5504-d780-4da6-b512-4fbb0ab05d7e.png and b/frontend/src/assets/sources/ab4c5504-d780-4da6-b512-4fbb0ab05d7e.png differ
diff --git a/frontend/src/assets/sources/b470d7c9-b7e4-4d7a-9973-e490ff4a880f.png b/frontend/src/assets/sources/b470d7c9-b7e4-4d7a-9973-e490ff4a880f.png
index 782b35a95..027ee01c5 100644
Binary files a/frontend/src/assets/sources/b470d7c9-b7e4-4d7a-9973-e490ff4a880f.png and b/frontend/src/assets/sources/b470d7c9-b7e4-4d7a-9973-e490ff4a880f.png differ
diff --git a/frontend/src/assets/sources/bbc89f13-66bb-4e96-812f-70f1f64d7604.png b/frontend/src/assets/sources/bbc89f13-66bb-4e96-812f-70f1f64d7604.png
index 6bfe0cb33..a21533c77 100644
Binary files a/frontend/src/assets/sources/bbc89f13-66bb-4e96-812f-70f1f64d7604.png and b/frontend/src/assets/sources/bbc89f13-66bb-4e96-812f-70f1f64d7604.png differ
diff --git a/frontend/src/assets/sources/c8f4312f-ac8f-4118-8b80-81d5076e8d32.png b/frontend/src/assets/sources/c8f4312f-ac8f-4118-8b80-81d5076e8d32.png
index 19bced574..d6295ef31 100644
Binary files a/frontend/src/assets/sources/c8f4312f-ac8f-4118-8b80-81d5076e8d32.png and b/frontend/src/assets/sources/c8f4312f-ac8f-4118-8b80-81d5076e8d32.png differ
diff --git a/frontend/src/assets/sources/cc311773-48ac-4fb7-bb8b-b5e9f4c77785.png b/frontend/src/assets/sources/cc311773-48ac-4fb7-bb8b-b5e9f4c77785.png
index 50fb54261..d2d4f0c30 100644
Binary files a/frontend/src/assets/sources/cc311773-48ac-4fb7-bb8b-b5e9f4c77785.png and b/frontend/src/assets/sources/cc311773-48ac-4fb7-bb8b-b5e9f4c77785.png differ
diff --git a/frontend/src/assets/sources/cd4082b0-48db-402b-88c3-18e4d3388fbd.png b/frontend/src/assets/sources/cd4082b0-48db-402b-88c3-18e4d3388fbd.png
index 6876bacbb..af6518ae5 100644
Binary files a/frontend/src/assets/sources/cd4082b0-48db-402b-88c3-18e4d3388fbd.png and b/frontend/src/assets/sources/cd4082b0-48db-402b-88c3-18e4d3388fbd.png differ
diff --git a/frontend/src/assets/sources/d90af467-72dd-4082-b45e-5883e418bdc1.png b/frontend/src/assets/sources/d90af467-72dd-4082-b45e-5883e418bdc1.png
index 5b7b19de2..c31e51fbe 100644
Binary files a/frontend/src/assets/sources/d90af467-72dd-4082-b45e-5883e418bdc1.png and b/frontend/src/assets/sources/d90af467-72dd-4082-b45e-5883e418bdc1.png differ
diff --git a/frontend/src/assets/sources/db607b32-d7f9-48df-a659-fdcba3945c35.png b/frontend/src/assets/sources/db607b32-d7f9-48df-a659-fdcba3945c35.png
index 76449cb60..47e8e032e 100644
Binary files a/frontend/src/assets/sources/db607b32-d7f9-48df-a659-fdcba3945c35.png and b/frontend/src/assets/sources/db607b32-d7f9-48df-a659-fdcba3945c35.png differ
diff --git a/frontend/src/assets/sources/dbdf1511-ed54-449b-9882-2abfd6a98d29.png b/frontend/src/assets/sources/dbdf1511-ed54-449b-9882-2abfd6a98d29.png
index aa1485c86..9fd8c6dc4 100644
Binary files a/frontend/src/assets/sources/dbdf1511-ed54-449b-9882-2abfd6a98d29.png and b/frontend/src/assets/sources/dbdf1511-ed54-449b-9882-2abfd6a98d29.png differ
diff --git a/frontend/src/assets/sources/e0bdaf29-5213-439e-ba79-66bcbe602ed8.png b/frontend/src/assets/sources/e0bdaf29-5213-439e-ba79-66bcbe602ed8.png
index 7668c58be..b3f21c0d7 100644
Binary files a/frontend/src/assets/sources/e0bdaf29-5213-439e-ba79-66bcbe602ed8.png and b/frontend/src/assets/sources/e0bdaf29-5213-439e-ba79-66bcbe602ed8.png differ
diff --git a/frontend/src/assets/sources/e342250a-e9fb-49f4-ad2b-3edea496e8e5.png b/frontend/src/assets/sources/e342250a-e9fb-49f4-ad2b-3edea496e8e5.png
index 50db9d66f..746a1800d 100644
Binary files a/frontend/src/assets/sources/e342250a-e9fb-49f4-ad2b-3edea496e8e5.png and b/frontend/src/assets/sources/e342250a-e9fb-49f4-ad2b-3edea496e8e5.png differ
diff --git a/frontend/src/assets/sources/e3f229a1-8637-49b1-abaa-84d228aff34a.png b/frontend/src/assets/sources/e3f229a1-8637-49b1-abaa-84d228aff34a.png
index 4c128a7f3..4ce1917b8 100644
Binary files a/frontend/src/assets/sources/e3f229a1-8637-49b1-abaa-84d228aff34a.png and b/frontend/src/assets/sources/e3f229a1-8637-49b1-abaa-84d228aff34a.png differ
diff --git a/frontend/src/assets/sources/f12e6c9c-f38d-4468-b158-656c096e21b8.png b/frontend/src/assets/sources/f12e6c9c-f38d-4468-b158-656c096e21b8.png
index 9b4a998aa..e25d830fb 100644
Binary files a/frontend/src/assets/sources/f12e6c9c-f38d-4468-b158-656c096e21b8.png and b/frontend/src/assets/sources/f12e6c9c-f38d-4468-b158-656c096e21b8.png differ
diff --git a/go.mod b/go.mod
index a5ea287a1..e34fe7c72 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,8 @@
module github.com/fastenhealth/fasten-onprem
-go 1.18
+go 1.21
+
+toolchain go1.21.1
//replace github.com/fastenhealth/fasten-sources => ../fasten-sources
@@ -11,6 +13,8 @@ replace github.com/mattn/go-sqlite3 v1.14.17 => github.com/jgiannuzzi/go-sqlite3
//replace gorm.io/driver/sqlite v1.5.4 => github.com/jgiannuzzi/gorm-sqlite v1.4.4-0.20221215225833-42389ad31305
require (
+ github.com/Masterminds/sprig/v3 v3.2.3
+ github.com/TwiN/deepmerge v0.2.1
github.com/analogj/go-util v0.0.0-20210417161720-39b497cca03b
github.com/dave/jennifer v1.6.1
github.com/dominikbraun/graph v0.15.0
@@ -40,11 +44,18 @@ require (
)
require (
+ github.com/Masterminds/goutils v1.1.1 // indirect
+ github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+ github.com/huandu/xstrings v1.3.3 // indirect
+ github.com/imdario/mergo v0.3.11 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/mattn/go-sqlite3 v1.14.17 // indirect
+ github.com/mitchellh/copystructure v1.0.0 // indirect
+ github.com/mitchellh/reflectwalk v1.0.0 // indirect
+ github.com/shopspring/decimal v1.2.0 // indirect
)
require (
diff --git a/go.sum b/go.sum
index a991b63cc..709df94bc 100644
--- a/go.sum
+++ b/go.sum
@@ -41,9 +41,17 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJc
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
+github.com/TwiN/deepmerge v0.2.1 h1:GowJr9O4THTVW4awX63x1BVg1hgr4q+35XKKCYbwsSs=
+github.com/TwiN/deepmerge v0.2.1/go.mod h1:LVBmCEBQvibYSF8Gyl/NqhHXH7yIiT7Ozqf9dHxGPW0=
github.com/analogj/go-util v0.0.0-20210417161720-39b497cca03b h1:Y/+MfmdKPPpVY7C6ggt/FpltFSitlpUtyJEdcQyFXQg=
github.com/analogj/go-util v0.0.0-20210417161720-39b497cca03b/go.mod h1:bRSzJXgXnT5+Ihah7RSC7Cvp16UmoLn3wq6ROciS1Ow=
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
@@ -109,6 +117,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
+github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
@@ -125,6 +134,7 @@ github.com/go-gormigrate/gormigrate/v2 v2.1.1/go.mod h1:L7nJ620PFDKei9QOhJzqA8kR
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@@ -189,6 +199,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v54 v54.0.0 h1:OZdXwow4EAD5jEo5qg+dGFH2DpkyZvVsAehjvJuUL/c=
github.com/google/go-github/v54 v54.0.0/go.mod h1:Sw1LXWHhXRZtzJ9LI5fyJg9wbQzYvFhW8W5P2yaAQ7s=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
@@ -210,6 +221,7 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -220,11 +232,15 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
+github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
@@ -333,10 +349,14 @@ github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp9
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -370,6 +390,7 @@ github.com/seborama/govcr v4.5.0+incompatible/go.mod h1:EgcISudCCYDLzbiAImJ8i7kk
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -377,6 +398,7 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
@@ -405,6 +427,7 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
+github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
@@ -456,6 +479,7 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
@@ -535,6 +559,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
@@ -617,6 +642,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -625,6 +651,7 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
@@ -638,6 +665,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
@@ -809,6 +837,7 @@ gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=