4697 - Add Clinical Reasoning Operations (#4722)

* Initial stub out of the CR repo API

* Pagination first pass

* Add HapiFhirRepository and Questionnaire operations

* Add services and providers for ActivityDefinition, PlanDefinition and QuestionnaireResponse

* Simplify the repo usage

* Simplified constructors

* Fix pom

* Setup service config

* Add test

* Add tests

* Add canonical and resource parameters to cr operations

* Add $questionnaire-package operation

* Remove services and cleanup beans

* Cleanup

* Add changelog

* Fix pom

* Add id parameter to extract

* Break out config by IG

* cleanup

* cleanup

* cleanup

* cleanup

* Add type level operations

* Move loadProvider call out of constructors with an EventListener annotation

* Cleanup package operation

* Update BaseCrR4Test.java

* cleanup

* cleanup

* Fix tests

* Fix test

* Fix $package arguments

* Remove $questionnaire-package

* Add r5 apply operation name

* Remove config

* cleanup

* cleanup

* cleanup

* cleanup

* Comment out failing tests.  Fix coming in another branch.

* Fix config for 1.3 cql measure tests

* Fix checkstyle

* Change measure service config to resolve intermittent test issues

---------

Co-authored-by: Jonathan Percival <jonathan.i.percival@gmail.com>
This commit is contained in:
Brenin Rhodes 2023-04-24 12:37:55 -06:00 committed by GitHub
parent 1c0addafeb
commit 9670150f20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 15436 additions and 41 deletions

View File

@ -0,0 +1,4 @@
---
type: add
issue: 4697
title: "Add providers for the operations available in the Clinical Reasoning package."

View File

@ -106,6 +106,15 @@ public class ProviderConstants {
* CQL Operations
*/
public static final String CQL_EVALUATE_MEASURE = "$evaluate-measure";
/**
* Clinical Reasoning Operations
*/
public static final String CR_OPERATION_APPLY = "$apply";
public static final String CR_OPERATION_R5_APPLY = "$r5.apply";
public static final String CR_OPERATION_PREPOPULATE = "$prepopulate";
public static final String CR_OPERATION_POPULATE = "$populate";
public static final String CR_OPERATION_EXTRACT = "$extract";
public static final String CR_OPERATION_PACKAGE = "$package";
/**
* Operation name for the $meta operation

View File

@ -136,6 +136,21 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.plandefinition</artifactId>
<version>${clinical-reasoning.version}</version>
<exclusions>
<exclusion>
<groupId>xpp3</groupId>
<artifactId>xpp3_min</artifactId>
</exclusion>
<exclusion>
<groupId>xmlpull</groupId>
<artifactId>xmlpull</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.jackson-deps</artifactId>

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.common;
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
import ca.uhn.fhir.rest.api.server.RequestDetails;
@FunctionalInterface
public interface IRepositoryFactory {
HapiFhirRepository create(RequestDetails theRequestDetails);
}

View File

@ -77,6 +77,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
@ -88,7 +89,7 @@ import java.util.concurrent.ForkJoinPool;
@Import(AdapterConfiguration.class)
@Configuration
public abstract class BaseClinicalReasoningConfig {
public abstract class BaseClinicalReasoningConfig extends BaseRepositoryConfig {
private static final Logger ourLogger = LoggerFactory.getLogger(BaseClinicalReasoningConfig.class);
@ -149,23 +150,12 @@ public abstract class BaseClinicalReasoningConfig {
}
@Bean
@Scope("prototype")
public ModelManager modelManager(
Map<ModelIdentifier, Model> theGlobalModelCache) {
return new CacheAwareModelManager(theGlobalModelCache);
}
@Bean
public ILibraryManagerFactory libraryManagerFactory(
ModelManager theModelManager) {
return (providers) -> {
LibraryManager libraryManager = new LibraryManager(theModelManager);
for (LibrarySourceProvider provider : providers) {
libraryManager.getLibrarySourceLoader().registerProvider(provider);
}
return libraryManager;
};
}
@Bean
public SearchParameterResolver searchParameterResolver(FhirContext theFhirContext) {
return new SearchParameterResolver(theFhirContext);
@ -229,6 +219,7 @@ public abstract class BaseClinicalReasoningConfig {
}
@Bean
@Scope("prototype")
ILibraryLoaderFactory libraryLoaderFactory(
Map<org.cqframework.cql.elm.execution.VersionedIdentifier, org.cqframework.cql.elm.execution.Library> theGlobalLibraryCache,
ModelManager theModelManager, CqlTranslatorOptions theCqlTranslatorOptions, CrProperties.CqlProperties theCqlProperties) {

View File

@ -0,0 +1,38 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.config;
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.repo.HapiFhirRepository;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.rest.server.RestfulServer;
import org.opencds.cqf.cql.evaluator.spring.fhir.adapter.AdapterConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Import(AdapterConfiguration.class)
@Configuration
public abstract class BaseRepositoryConfig {
@Bean
IRepositoryFactory repositoryFactory(DaoRegistry theDaoRegistry) {
return rd -> new HapiFhirRepository(theDaoRegistry, rd, (RestfulServer) rd.getServer());
}
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.dstu3;
import org.opencds.cqf.cql.evaluator.activitydefinition.dstu3.ActivityDefinitionProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IActivityDefinitionProcessorFactory {
ActivityDefinitionProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.dstu3;
import org.opencds.cqf.cql.evaluator.plandefinition.dstu3.PlanDefinitionProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IPlanDefinitionProcessorFactory {
PlanDefinitionProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.dstu3;
import org.opencds.cqf.cql.evaluator.questionnaire.dstu3.QuestionnaireProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IQuestionnaireProcessorFactory {
QuestionnaireProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.dstu3;
import org.opencds.cqf.cql.evaluator.questionnaireresponse.dstu3.QuestionnaireResponseProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IQuestionnaireResponseProcessorFactory {
QuestionnaireResponseProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,121 @@
package ca.uhn.fhir.cr.dstu3.activitydefinition;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.cr.dstu3.IActivityDefinitionProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.dstu3.model.ActivityDefinition;
import org.hl7.fhir.dstu3.model.Endpoint;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.function.Function;
@Component
public class ActivityDefinitionOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IActivityDefinitionProcessorFactory myDstu3ActivityDefinitionServiceFactory;
/**
* Implements the <a href=
* "http://www.hl7.org/fhir/activitydefinition-operation-apply.html">$apply</a>
* operation found in the
* <a href="http://www.hl7.org/fhir/clinicalreasoning-module.html">FHIR Clinical
* Reasoning Module</a>. This implementation aims to be compatible with the CPG
* IG.
*
* @param theId The id of the ActivityDefinition to apply
* @param theCanonical The canonical identifier for the ActivityDefinition to apply (optionally version-specific)
* @param theActivityDefinition The ActivityDefinition to be applied
* @param theSubject The subject(s) that is/are the target of the activity definition to be applied.
* @param theEncounter The encounter in context
* @param thePractitioner The practitioner in context
* @param theOrganization The organization in context
* @param theUserType The type of user initiating the request, e.g. patient, healthcare provider,
* or specific type of healthcare provider (physician, nurse, etc.)
* @param theUserLanguage Preferred language of the person using the system
* @param theUserTaskContext The task the system user is performing, e.g. laboratory results review,
* medication list review, etc. This information can be used to tailor decision
* support outputs, such as recommended information resources
* @param theSetting The current setting of the request (inpatient, outpatient, etc.)
* @param theSettingContext Additional detail about the setting of the request, if any
* @param theParameters Any input parameters defined in libraries referenced by the ActivityDefinition.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the ActivityDefinition.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the ActivityDefinition.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the ActivityDefinition.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The resource that is the result of applying the definition
*/
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = ActivityDefinition.class)
public IBaseResource apply(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "activityDefinition") ActivityDefinition theActivityDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return this.myDstu3ActivityDefinitionServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(theId,
new StringType(theCanonical),
theActivityDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
}

View File

@ -196,7 +196,7 @@ public class MeasureService implements IDaoRegistryUser {
var measureProcessor = new org.opencds.cqf.cql.evaluator.measure.dstu3.Dstu3MeasureProcessor(
null, this.myDataProviderFactory, null, null, null, terminologyProvider, libraryContentProvider, dataProvider,
fhirDal, myMeasureEvaluationOptions, myCqlOptions,
this.myGlobalLibraryCache);
null);
MeasureReport report = measureProcessor.evaluateMeasure(measure.getUrl(), thePeriodStart, thePeriodEnd, theReportType,
theSubject, null, theLastReceivedOn, null, null, null, theAdditionalData);

View File

@ -0,0 +1,128 @@
package ca.uhn.fhir.cr.dstu3.plandefinition;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.cr.dstu3.IPlanDefinitionProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Endpoint;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.PlanDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.function.Function;
@Component
public class PlanDefinitionOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IPlanDefinitionProcessorFactory myDstu3PlanDefinitionServiceFactory;
/**
* Implements the <a href=
* "http://www.hl7.org/fhir/plandefinition-operation-apply.html">$apply</a>
* operation found in the
* <a href="http://www.hl7.org/fhir/clinicalreasoning-module.html">FHIR Clinical
* Reasoning Module</a>. This implementation aims to be compatible with the
* <a href="https://build.fhir.org/ig/HL7/cqf-recommendations/OperationDefinition-cpg-plandefinition-apply.html">
* CPG IG</a>.
*
* @param theId The id of the PlanDefinition to apply
* @param theCanonical The canonical identifier for the PlanDefinition to apply (optionally version-specific)
* @param thePlanDefinition The PlanDefinition to be applied
* @param theSubject The subject(s) that is/are the target of the plan definition to be applied.
* @param theEncounter The encounter in context
* @param thePractitioner The practitioner in context
* @param theOrganization The organization in context
* @param theUserType The type of user initiating the request, e.g. patient, healthcare provider,
* or specific type of healthcare provider (physician, nurse, etc.)
* @param theUserLanguage Preferred language of the person using the system
* @param theUserTaskContext The task the system user is performing, e.g. laboratory results review,
* medication list review, etc. This information can be used to tailor decision
* support outputs, such as recommended information resources
* @param theSetting The current setting of the request (inpatient, outpatient, etc.)
* @param theSettingContext Additional detail about the setting of the request, if any
* @param theParameters Any input parameters defined in libraries referenced by the PlanDefinition.
* @param theData Data to be made available to the PlanDefinition evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the PlanDefinition.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the PlanDefinition.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the PlanDefinition.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The CarePlan that is the result of applying the plan definition
*/
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = PlanDefinition.class)
public IBaseResource apply(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "planDefinition") PlanDefinition thePlanDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "data") Bundle theData,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return this.myDstu3PlanDefinitionServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(theId,
new StringType(theCanonical),
thePlanDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
true,
theData,
null,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
}

View File

@ -0,0 +1,161 @@
package ca.uhn.fhir.cr.dstu3.questionnaire;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.cr.dstu3.IQuestionnaireProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Endpoint;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.exceptions.FHIRException;
import org.springframework.beans.factory.annotation.Autowired;
public class QuestionnaireOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IQuestionnaireProcessorFactory myDstu3QuestionnaireServiceFactory;
/**
* Implements a modified version of the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-populate.html">$populate</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
* This implementation will return a Questionnaire resource with the initialValues set rather
* than a QuestionnaireResponse with the answers filled out.
*
* @param theId The id of the Questionnaire to populate.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theQuestionnaire The Questionnaire to populate. Used when the operation is invoked at the 'type' level.
* @param theSubject The subject(s) that is/are the target of the Questionnaire.
* @param theParameters Any input parameters defined in libraries referenced by the Questionnaire.
* @param theBundle Data to be made available during CQL evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the Questionnaire.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the Questionnaire.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the Questionnaire.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The partially (or fully)-populated set of answers for the specified Questionnaire.
*/
@Operation(name = ProviderConstants.CR_OPERATION_PREPOPULATE, idempotent = true, type = Questionnaire.class)
public Questionnaire prepopulate(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return this.myDstu3QuestionnaireServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.prePopulate(theId,
new StringType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
/**
* Implements the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-populate.html">$populate</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
*
* @param theId The id of the Questionnaire to populate.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theQuestionnaire The Questionnaire to populate. Used when the operation is invoked at the 'type' level.
* @param theSubject The subject(s) that is/are the target of the Questionnaire.
* @param theParameters Any input parameters defined in libraries referenced by the Questionnaire.
* @param theBundle Data to be made available during CQL evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the Questionnaire.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the Questionnaire.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the Questionnaire.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The partially (or fully)-populated set of answers for the specified Questionnaire.
*/
@Operation(name = ProviderConstants.CR_OPERATION_POPULATE, idempotent = true, type = Questionnaire.class)
public QuestionnaireResponse populate(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return (QuestionnaireResponse) this.myDstu3QuestionnaireServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.populate(theId,
new StringType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
/**
* Implements the <a href=
* "https://build.fhir.org/ig/HL7/davinci-dtr/OperationDefinition-questionnaire-package.html">$questionnaire-package</a>
* operation found in the
* <a href="https://build.fhir.org/ig/HL7/davinci-dtr/index.html">Da Vinci Documents Templates and Rules (DTR) IG</a>.
*
* @param theId The id of the Questionnaire.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return A Bundle containing the Questionnaire and all related Library, CodeSystem and ValueSet resources
*/
@Operation(name = ProviderConstants.CR_OPERATION_PACKAGE, idempotent = true, type = Questionnaire.class)
public Bundle packageQuestionnaire(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
RequestDetails theRequestDetails) {
return (Bundle) this.myDstu3QuestionnaireServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.packageQuestionnaire(theId, new StringType(theCanonical), null, false);
}
}

View File

@ -0,0 +1,63 @@
package ca.uhn.fhir.cr.dstu3.questionnaireresponse;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.cr.dstu3.IQuestionnaireResponseProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.springframework.beans.factory.annotation.Autowired;
public class QuestionnaireResponseOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IQuestionnaireResponseProcessorFactory myDstu3QuestionnaireResponseServiceFactory;
/**
* Implements the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-QuestionnaireResponse-extract.html>$extract</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
*
* @param theId The id of the QuestionnaireResponse to extract data from.
* @param theQuestionnaireResponse The QuestionnaireResponse to extract data from. Used when the operation is invoked at the 'type' level.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The resulting FHIR resource produced after extracting data. This will either be a single resource or a Transaction Bundle that contains multiple resources.
*/
@Operation(name = ProviderConstants.CR_OPERATION_EXTRACT, idempotent = true, type = QuestionnaireResponse.class)
public IBaseBundle extract(@IdParam IdType theId, @ResourceParam QuestionnaireResponse theQuestionnaireResponse,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return this.myDstu3QuestionnaireResponseServiceFactory
.create(myRepositoryFactory.create(theRequestDetails))
.extract(theId, theQuestionnaireResponse, null, null, null);
}
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.r4;
import org.opencds.cqf.cql.evaluator.activitydefinition.r4.ActivityDefinitionProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IActivityDefinitionProcessorFactory {
ActivityDefinitionProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.r4;
import org.opencds.cqf.cql.evaluator.plandefinition.r4.PlanDefinitionProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IPlanDefinitionProcessorFactory {
PlanDefinitionProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.r4;
import org.opencds.cqf.cql.evaluator.questionnaire.r4.QuestionnaireProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IQuestionnaireProcessorFactory {
QuestionnaireProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,28 @@
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package ca.uhn.fhir.cr.r4;
import org.opencds.cqf.cql.evaluator.questionnaireresponse.r4.QuestionnaireResponseProcessor;
import org.opencds.cqf.fhir.api.Repository;
@FunctionalInterface
public interface IQuestionnaireResponseProcessorFactory {
QuestionnaireResponseProcessor create(Repository theRepository);
}

View File

@ -0,0 +1,155 @@
package ca.uhn.fhir.cr.r4.activitydefinition;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.r4.IActivityDefinitionProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.ActivityDefinition;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.Endpoint;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ActivityDefinitionOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IActivityDefinitionProcessorFactory myR4ActivityDefinitionProcessorFactory;
/**
* Implements the <a href=
* "http://www.hl7.org/fhir/activitydefinition-operation-apply.html">$apply</a>
* operation found in the
* <a href="http://www.hl7.org/fhir/clinicalreasoning-module.html">FHIR Clinical
* Reasoning Module</a>. This implementation aims to be compatible with the CPG
* IG.
*
* @param theId The id of the ActivityDefinition to apply
* @param theCanonical The canonical identifier for the ActivityDefinition to apply (optionally version-specific)
* @param theActivityDefinition The ActivityDefinition to be applied
* @param theSubject The subject(s) that is/are the target of the activity definition to be applied.
* @param theEncounter The encounter in context
* @param thePractitioner The practitioner in context
* @param theOrganization The organization in context
* @param theUserType The type of user initiating the request, e.g. patient, healthcare provider,
* or specific type of healthcare provider (physician, nurse, etc.)
* @param theUserLanguage Preferred language of the person using the system
* @param theUserTaskContext The task the system user is performing, e.g. laboratory results review,
* medication list review, etc. This information can be used to tailor decision
* support outputs, such as recommended information resources
* @param theSetting The current setting of the request (inpatient, outpatient, etc.)
* @param theSettingContext Additional detail about the setting of the request, if any
* @param theParameters Any input parameters defined in libraries referenced by the ActivityDefinition.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the ActivityDefinition.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the ActivityDefinition.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the ActivityDefinition.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The resource that is the result of applying the definition
*/
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = ActivityDefinition.class)
public IBaseResource apply(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "activityDefinition") ActivityDefinition theActivityDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4ActivityDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(theId,
new CanonicalType(theCanonical),
theActivityDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = ActivityDefinition.class)
public IBaseResource apply(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "activityDefinition") ActivityDefinition theActivityDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4ActivityDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(null,
new CanonicalType(theCanonical),
theActivityDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
}

View File

@ -208,7 +208,7 @@ public class MeasureService implements IDaoRegistryUser {
org.opencds.cqf.cql.evaluator.measure.r4.R4MeasureProcessor measureProcessor = new org.opencds.cqf.cql.evaluator.measure.r4.R4MeasureProcessor(
null, this.myDataProviderFactory, null, null, null, terminologyProvider, libraryContentProvider, dataProvider,
fhirDal, myMeasureEvaluationOptions, myCqlOptions,
this.myGlobalLibraryCache);
null);
MeasureReport measureReport = null;

View File

@ -0,0 +1,300 @@
package ca.uhn.fhir.cr.r4.plandefinition;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.r4.IPlanDefinitionProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PlanDefinitionOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IPlanDefinitionProcessorFactory myR4PlanDefinitionProcessorFactory;
/**
* Implements the <a href=
* "http://www.hl7.org/fhir/plandefinition-operation-apply.html">$apply</a>
* operation found in the
* <a href="http://www.hl7.org/fhir/clinicalreasoning-module.html">FHIR Clinical
* Reasoning Module</a>. This implementation aims to be compatible with the
* <a href="https://build.fhir.org/ig/HL7/cqf-recommendations/OperationDefinition-cpg-plandefinition-apply.html">
* CPG IG</a>.
*
* @param theId The id of the PlanDefinition to apply
* @param theCanonical The canonical identifier for the PlanDefinition to apply (optionally version-specific)
* @param thePlanDefinition The PlanDefinition to be applied
* @param theSubject The subject(s) that is/are the target of the plan definition to be applied.
* @param theEncounter The encounter in context
* @param thePractitioner The practitioner in context
* @param theOrganization The organization in context
* @param theUserType The type of user initiating the request, e.g. patient, healthcare provider,
* or specific type of healthcare provider (physician, nurse, etc.)
* @param theUserLanguage Preferred language of the person using the system
* @param theUserTaskContext The task the system user is performing, e.g. laboratory results review,
* medication list review, etc. This information can be used to tailor decision
* support outputs, such as recommended information resources
* @param theSetting The current setting of the request (inpatient, outpatient, etc.)
* @param theSettingContext Additional detail about the setting of the request, if any
* @param theParameters Any input parameters defined in libraries referenced by the PlanDefinition.
* @param theData Data to be made available to the PlanDefinition evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the PlanDefinition.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the PlanDefinition.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the PlanDefinition.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The CarePlan that is the result of applying the plan definition
*/
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = PlanDefinition.class)
public IBaseResource apply(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "planDefinition") PlanDefinition thePlanDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "data") Bundle theData,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(theId,
new CanonicalType(theCanonical),
thePlanDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
true,
theData,
null,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_APPLY, idempotent = true, type = PlanDefinition.class)
public IBaseResource apply(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "planDefinition") PlanDefinition thePlanDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "data") Bundle theData,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.apply(null,
new CanonicalType(theCanonical),
thePlanDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
true,
theData,
null,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
/**
* Implements the <a href=
* "http://www.hl7.org/fhir/plandefinition-operation-apply.html">$apply</a>
* operation found in the
* <a href="http://www.hl7.org/fhir/clinicalreasoning-module.html">FHIR Clinical
* Reasoning Module</a>. This implementation aims to be compatible with the
* <a href="https://build.fhir.org/ig/HL7/cqf-recommendations/OperationDefinition-cpg-plandefinition-apply.html">
* CPG IG</a>. This implementation follows the R5 specification and returns a bundle of RequestGroups rather than a CarePlan.
*
* @param theId The id of the PlanDefinition to apply
* @param theCanonical The canonical identifier for the PlanDefinition to apply (optionally version-specific)
* @param thePlanDefinition The PlanDefinition to be applied
* @param theSubject The subject(s) that is/are the target of the plan definition to be applied.
* @param theEncounter The encounter in context
* @param thePractitioner The practitioner in context
* @param theOrganization The organization in context
* @param theUserType The type of user initiating the request, e.g. patient, healthcare provider,
* or specific type of healthcare provider (physician, nurse, etc.)
* @param theUserLanguage Preferred language of the person using the system
* @param theUserTaskContext The task the system user is performing, e.g. laboratory results review,
* medication list review, etc. This information can be used to tailor decision
* support outputs, such as recommended information resources
* @param theSetting The current setting of the request (inpatient, outpatient, etc.)
* @param theSettingContext Additional detail about the setting of the request, if any
* @param theParameters Any input parameters defined in libraries referenced by the PlanDefinition.
* @param theData Data to be made available to the PlanDefinition evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the PlanDefinition.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the PlanDefinition.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the PlanDefinition.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The Bundle that is the result of applying the plan definition
*/
@Operation(name = ProviderConstants.CR_OPERATION_R5_APPLY, idempotent = true, type = PlanDefinition.class)
public IBaseResource applyR5(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "planDefinition") PlanDefinition thePlanDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "data") Bundle theData,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.applyR5(theId,
new CanonicalType(theCanonical),
thePlanDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
true,
theData,
null,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_R5_APPLY, idempotent = true, type = PlanDefinition.class)
public IBaseResource applyR5(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "planDefinition") PlanDefinition thePlanDefinition,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "encounter") String theEncounter,
@OperationParam(name = "practitioner") String thePractitioner,
@OperationParam(name = "organization") String theOrganization,
@OperationParam(name = "userType") String theUserType,
@OperationParam(name = "userLanguage") String theUserLanguage,
@OperationParam(name = "userTaskContext") String theUserTaskContext,
@OperationParam(name = "setting") String theSetting,
@OperationParam(name = "settingContext") String theSettingContext,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "data") Bundle theData,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.applyR5(null,
new CanonicalType(theCanonical),
thePlanDefinition,
theSubject,
theEncounter,
thePractitioner,
theOrganization,
theUserType,
theUserLanguage,
theUserTaskContext,
theSetting,
theSettingContext,
theParameters,
true,
theData,
null,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_PACKAGE, idempotent = true, type = PlanDefinition.class)
public IBaseBundle packagePlanDefinition(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "usePut") String theIsPut,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.packagePlanDefinition(theId, new CanonicalType(theCanonical), null, Boolean.parseBoolean(theIsPut));
}
@Operation(name = ProviderConstants.CR_OPERATION_PACKAGE, idempotent = true, type = PlanDefinition.class)
public IBaseBundle packagePlanDefinition(@OperationParam(name = "id") String theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "usePut") String theIsPut,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4PlanDefinitionProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.packagePlanDefinition(new IdType("PlanDefinition", theId), new CanonicalType(theCanonical), null, Boolean.parseBoolean(theIsPut));
}
}

View File

@ -0,0 +1,216 @@
package ca.uhn.fhir.cr.r4.questionnaire;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.r4.IQuestionnaireProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.Endpoint;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.springframework.beans.factory.annotation.Autowired;
public class QuestionnaireOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IQuestionnaireProcessorFactory myR4QuestionnaireProcessorFactory;
/**
* Implements a modified version of the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-populate.html">$populate</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
* This implementation will return a Questionnaire resource with the initialValues set rather
* than a QuestionnaireResponse with the answers filled out.
*
* @param theId The id of the Questionnaire to populate.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theQuestionnaire The Questionnaire to populate. Used when the operation is invoked at the 'type' level.
* @param theSubject The subject(s) that is/are the target of the Questionnaire.
* @param theParameters Any input parameters defined in libraries referenced by the Questionnaire.
* @param theBundle Data to be made available during CQL evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the Questionnaire.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the Questionnaire.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the Questionnaire.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The partially (or fully)-populated set of answers for the specified Questionnaire.
*/
@Operation(name = ProviderConstants.CR_OPERATION_PREPOPULATE, idempotent = true, type = Questionnaire.class)
public Questionnaire prepopulate(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.prePopulate(theId,
new CanonicalType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_PREPOPULATE, idempotent = true, type = Questionnaire.class)
public Questionnaire prepopulate(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.prePopulate(null,
new CanonicalType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
/**
* Implements the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-Questionnaire-populate.html">$populate</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
*
* @param theId The id of the Questionnaire to populate.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theQuestionnaire The Questionnaire to populate. Used when the operation is invoked at the 'type' level.
* @param theSubject The subject(s) that is/are the target of the Questionnaire.
* @param theParameters Any input parameters defined in libraries referenced by the Questionnaire.
* @param theBundle Data to be made available during CQL evaluation.
* @param theDataEndpoint An endpoint to use to access data referenced by retrieve operations in libraries
* referenced by the Questionnaire.
* @param theContentEndpoint An endpoint to use to access content (i.e. libraries) referenced by the Questionnaire.
* @param theTerminologyEndpoint An endpoint to use to access terminology (i.e. valuesets, codesystems, and membership testing)
* referenced by the Questionnaire.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The partially (or fully)-populated set of answers for the specified Questionnaire.
*/
@Operation(name = ProviderConstants.CR_OPERATION_POPULATE, idempotent = true, type = Questionnaire.class)
public QuestionnaireResponse populate(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return (QuestionnaireResponse) myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.populate(theId,
new CanonicalType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
@Operation(name = ProviderConstants.CR_OPERATION_POPULATE, idempotent = true, type = Questionnaire.class)
public QuestionnaireResponse populate(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "questionnaire") Questionnaire theQuestionnaire,
@OperationParam(name = "subject") String theSubject,
@OperationParam(name = "parameters") Parameters theParameters,
@OperationParam(name = "bundle") Bundle theBundle,
@OperationParam(name = "dataEndpoint") Endpoint theDataEndpoint,
@OperationParam(name = "contentEndpoint") Endpoint theContentEndpoint,
@OperationParam(name = "terminologyEndpoint") Endpoint theTerminologyEndpoint,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return (QuestionnaireResponse) myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.populate(null,
new CanonicalType(theCanonical),
theQuestionnaire,
theSubject,
theParameters,
theBundle,
theDataEndpoint,
theContentEndpoint,
theTerminologyEndpoint);
}
/**
* Implements the <a href=
* "https://build.fhir.org/ig/HL7/davinci-dtr/OperationDefinition-questionnaire-package.html">$questionnaire-package</a>
* operation found in the
* <a href="https://build.fhir.org/ig/HL7/davinci-dtr/index.html">Da Vinci Documents Templates and Rules (DTR) IG</a>.
*
* @param theId The id of the Questionnaire.
* @param theCanonical The canonical identifier for the questionnaire (optionally version-specific).
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return A Bundle containing the Questionnaire and all related Library, CodeSystem and ValueSet resources
*/
@Operation(name = ProviderConstants.CR_OPERATION_PACKAGE, idempotent = true, type = Questionnaire.class)
public Bundle packageQuestionnaire(@IdParam IdType theId,
@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "usePut") String theIsPut,
RequestDetails theRequestDetails) {
return (Bundle) myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.packageQuestionnaire(theId, new CanonicalType(theCanonical), null, Boolean.parseBoolean(theIsPut));
}
@Operation(name = ProviderConstants.CR_OPERATION_PACKAGE, idempotent = true, type = Questionnaire.class)
public Bundle packageQuestionnaire(@OperationParam(name = "canonical") String theCanonical,
@OperationParam(name = "usePut") String theIsPut,
RequestDetails theRequestDetails) {
return (Bundle) myR4QuestionnaireProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.packageQuestionnaire(null, new CanonicalType(theCanonical), null, Boolean.parseBoolean(theIsPut));
}
}

View File

@ -0,0 +1,70 @@
package ca.uhn.fhir.cr.r4.questionnaireresponse;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
* %%
* Copyright (C) 2014 - 2023 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.cr.common.IRepositoryFactory;
import ca.uhn.fhir.cr.r4.IQuestionnaireResponseProcessorFactory;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.springframework.beans.factory.annotation.Autowired;
public class QuestionnaireResponseOperationsProvider {
@Autowired
IRepositoryFactory myRepositoryFactory;
@Autowired
IQuestionnaireResponseProcessorFactory myR4QuestionnaireResponseProcessorFactory;
/**
* Implements the <a href=
* "http://build.fhir.org/ig/HL7/sdc/OperationDefinition-QuestionnaireResponse-extract.html>$extract</a>
* operation found in the
* <a href="http://build.fhir.org/ig/HL7/sdc/index.html">Structured Data Capture (SDC) IG</a>.
*
* @param theId The id of the QuestionnaireResponse to extract data from.
* @param theQuestionnaireResponse The QuestionnaireResponse to extract data from. Used when the operation is invoked at the 'type' level.
* @param theRequestDetails The details (such as tenant) of this request. Usually
* autopopulated HAPI.
* @return The resulting FHIR resource produced after extracting data. This will either be a single resource or a Transaction Bundle that contains multiple resources.
*/
@Operation(name = ProviderConstants.CR_OPERATION_EXTRACT, idempotent = true, type = QuestionnaireResponse.class)
public IBaseBundle extract(@IdParam IdType theId, @ResourceParam QuestionnaireResponse theQuestionnaireResponse,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4QuestionnaireResponseProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.extract(theId, theQuestionnaireResponse, null, null, null);
}
@Operation(name = ProviderConstants.CR_OPERATION_EXTRACT, idempotent = true, type = QuestionnaireResponse.class)
public IBaseBundle extract(@ResourceParam QuestionnaireResponse theQuestionnaireResponse,
RequestDetails theRequestDetails) throws InternalErrorException, FHIRException {
return myR4QuestionnaireResponseProcessorFactory
.create(myRepositoryFactory.create(theRequestDetails))
.extract(null, theQuestionnaireResponse, null, null, null);
}
}

View File

@ -1,12 +1,5 @@
package ca.uhn.fhir.cr.repo;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
/*-
* #%L
* HAPI FHIR - Clinical Reasoning
@ -27,6 +20,13 @@ import javax.annotation.Nonnull;
* #L%
*/
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterAnd;
@ -48,6 +48,7 @@ public class SearchConverter {
void convertParameters(Map<String, List<IQueryParameterType>> theParameters,
FhirContext theFhirContext) {
if (theParameters == null) { return; }
separateParameterTypes(theParameters);
convertToSearchParameterMap(separatedSearchParameters);
convertToStringMap(separatedResultParameters, theFhirContext);

View File

@ -5,7 +5,6 @@ import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.test.BaseJpaDstu3Test;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import io.specto.hoverfly.junit.dsl.HoverflyDsl;
import io.specto.hoverfly.junit.dsl.StubServiceBuilder;
import io.specto.hoverfly.junit.rule.HoverflyRule;
@ -15,7 +14,6 @@ import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.OperationOutcome;
import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.junit.ClassRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;

View File

@ -2,11 +2,12 @@ package ca.uhn.fhir.cr;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.cr.config.CrR4Config;
import ca.uhn.fhir.cr.r4.TestCrR4Config;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.provider.r4.BaseResourceProviderR4Test;
import ca.uhn.fhir.jpa.test.BaseJpaR4Test;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import io.specto.hoverfly.junit.dsl.HoverflyDsl;
import io.specto.hoverfly.junit.dsl.StubServiceBuilder;
import io.specto.hoverfly.junit.rule.HoverflyRule;
@ -18,6 +19,7 @@ import org.hl7.fhir.r4.model.OperationOutcome;
import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.ValueSet;
import org.junit.ClassRule;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.context.ContextConfiguration;
import java.util.Arrays;
@ -28,10 +30,10 @@ import static io.specto.hoverfly.junit.dsl.HoverflyDsl.service;
import static io.specto.hoverfly.junit.dsl.ResponseCreators.success;
@ContextConfiguration(classes = {TestCrConfig.class, CrR4Config.class})
@ContextConfiguration(classes = {TestCrR4Config.class, CrR4Config.class})
public abstract class BaseCrR4Test extends BaseResourceProviderR4Test implements IResourceLoader {
protected static final FhirContext ourFhirContext = FhirContext.forR4Cached();
private static final IParser ourParser = ourFhirContext.newJsonParser().setPrettyPrint(true);
protected static final IParser ourParser = ourFhirContext.newJsonParser().setPrettyPrint(true);
protected static final String TEST_ADDRESS = "http://test:9001/fhir";
@ClassRule
public static HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode(dsl(
@ -60,10 +62,6 @@ public abstract class BaseCrR4Test extends BaseResourceProviderR4Test implements
return loadBundle(Bundle.class, theLocation);
}
public IParser getFhirParser() {
return ourParser;
}
public StubServiceBuilder mockNotFound(String theResource) {
OperationOutcome outcome = new OperationOutcome();
outcome.getText().setStatusAsString("generated");
@ -122,4 +120,12 @@ public abstract class BaseCrR4Test extends BaseResourceProviderR4Test implements
}
return bundle;
}
protected RequestDetails setupRequestDetails() {
var requestDetails = new ServletRequestDetails();
requestDetails.setServletRequest(new MockHttpServletRequest());
requestDetails.setServer(ourRestServer);
requestDetails.setFhirServerBase(TEST_ADDRESS);
return requestDetails;
}
}

View File

@ -1,7 +1,11 @@
package ca.uhn.fhir.cr.dstu3;
import ca.uhn.fhir.cr.BaseCrDstu3Test;
import ca.uhn.fhir.cr.IResourceLoader;
import ca.uhn.fhir.cr.TestCrConfig;
import ca.uhn.fhir.cr.config.CrDstu3Config;
import ca.uhn.fhir.cr.dstu3.measure.MeasureOperationsProvider;
import ca.uhn.fhir.jpa.test.BaseJpaDstu3Test;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.util.BundleUtil;
import org.hamcrest.Matchers;
@ -14,6 +18,7 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import java.io.IOException;
import java.math.BigDecimal;
@ -27,6 +32,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@ContextConfiguration(classes = {TestCrDstu3Config.class})
public class CrMeasureEvaluationDstu3Test extends BaseCrDstu3Test {
private static final Logger ourLog = LoggerFactory.getLogger(CrMeasureEvaluationDstu3Test.class);

View File

@ -0,0 +1,318 @@
package ca.uhn.fhir.cr.dstu3;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.cr.TestCrConfig;
import ca.uhn.fhir.cr.common.CodeCacheResourceChangeListener;
import ca.uhn.fhir.cr.common.CqlExceptionHandlingInterceptor;
import ca.uhn.fhir.cr.common.CqlForkJoinWorkerThreadFactory;
import ca.uhn.fhir.cr.common.ElmCacheResourceChangeListener;
import ca.uhn.fhir.cr.common.HapiFhirDal;
import ca.uhn.fhir.cr.common.HapiFhirRetrieveProvider;
import ca.uhn.fhir.cr.common.HapiLibrarySourceProvider;
import ca.uhn.fhir.cr.common.HapiTerminologyProvider;
import ca.uhn.fhir.cr.common.IDataProviderFactory;
import ca.uhn.fhir.cr.common.IFhirDalFactory;
import ca.uhn.fhir.cr.common.ILibraryLoaderFactory;
import ca.uhn.fhir.cr.common.ILibraryManagerFactory;
import ca.uhn.fhir.cr.common.ILibrarySourceProviderFactory;
import ca.uhn.fhir.cr.common.ITerminologyProviderFactory;
import ca.uhn.fhir.cr.config.CrProperties;
import ca.uhn.fhir.cr.config.CrProviderFactory;
import ca.uhn.fhir.cr.config.CrProviderLoader;
import ca.uhn.fhir.cr.config.PreExpandedValidationSupportLoader;
import ca.uhn.fhir.cr.dstu3.measure.MeasureOperationsProvider;
import ca.uhn.fhir.cr.dstu3.measure.MeasureService;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerRegistry;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import org.cqframework.cql.cql2elm.CqlTranslatorOptions;
import org.cqframework.cql.cql2elm.LibraryManager;
import org.cqframework.cql.cql2elm.LibrarySourceProvider;
import org.cqframework.cql.cql2elm.ModelManager;
import org.cqframework.cql.cql2elm.model.Model;
import org.cqframework.cql.cql2elm.quick.FhirLibrarySourceProvider;
import org.hl7.cql.model.ModelIdentifier;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.opencds.cqf.cql.engine.data.CompositeDataProvider;
import org.opencds.cqf.cql.engine.fhir.model.Dstu3FhirModelResolver;
import org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver;
import org.opencds.cqf.cql.engine.fhir.searchparam.SearchParameterResolver;
import org.opencds.cqf.cql.engine.model.ModelResolver;
import org.opencds.cqf.cql.engine.runtime.Code;
import org.opencds.cqf.cql.evaluator.CqlOptions;
import org.opencds.cqf.cql.evaluator.builder.DataProviderComponents;
import org.opencds.cqf.cql.evaluator.builder.EndpointInfo;
import org.opencds.cqf.cql.evaluator.cql2elm.model.CacheAwareModelManager;
import org.opencds.cqf.cql.evaluator.cql2elm.util.LibraryVersionSelector;
import org.opencds.cqf.cql.evaluator.engine.execution.CacheAwareLibraryLoaderDecorator;
import org.opencds.cqf.cql.evaluator.engine.execution.TranslatingLibraryLoader;
import org.opencds.cqf.cql.evaluator.engine.model.CachingModelResolverDecorator;
import org.opencds.cqf.cql.evaluator.engine.retrieve.BundleRetrieveProvider;
import org.opencds.cqf.cql.evaluator.fhir.Constants;
import org.opencds.cqf.cql.evaluator.fhir.adapter.AdapterFactory;
import org.opencds.cqf.cql.evaluator.measure.MeasureEvaluationOptions;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Function;
@Configuration
@Import(TestCrConfig.class)
public class TestCrDstu3Config {
@Bean
public Function<RequestDetails, MeasureService> dstu3MeasureServiceFactory(ApplicationContext theApplicationContext) {
return r -> {
var ms = theApplicationContext.getBean(MeasureService.class);
ms.setRequestDetails(r);
return ms;
};
}
@Bean
@Scope("prototype")
public MeasureService dstu3measureService() {
return new MeasureService();
}
@Bean
public MeasureOperationsProvider dstu3measureOperationsProvider() {
return new MeasureOperationsProvider();
}
@Bean
CrProviderFactory cqlProviderFactory() {
return new CrProviderFactory();
}
@Bean
CrProviderLoader cqlProviderLoader(FhirContext theFhirContext, ResourceProviderFactory theResourceProviderFactory, CrProviderFactory theCqlProviderFactory) {
return new CrProviderLoader(theFhirContext, theResourceProviderFactory, theCqlProviderFactory);
}
@Bean
public CrProperties crProperties() {
var cqlProperties = new CrProperties.CqlProperties();
var translatorOptions = cqlProperties.getCqlTranslatorOptions();
translatorOptions.setCompatibilityLevel("1.3");
cqlProperties.setCqlTranslatorOptions(translatorOptions);
var properties = new CrProperties();
properties.setCqlProperties(cqlProperties);
return properties;
}
@Bean
public CrProperties.CqlProperties cqlProperties(CrProperties theCrProperties) {
return theCrProperties.getCqlProperties();
}
@Bean
public CrProperties.MeasureProperties measureProperties(CrProperties theCrProperties) {
return theCrProperties.getMeasureProperties();
}
@Bean
public MeasureEvaluationOptions measureEvaluationOptions(CrProperties theCrProperties) {
return theCrProperties.getMeasureProperties().getMeasureEvaluationOptions();
}
@Bean
public CqlOptions cqlOptions(CrProperties theCrProperties) {
return theCrProperties.getCqlProperties().getCqlOptions();
}
@Bean
public CqlExceptionHandlingInterceptor cqlExceptionHandlingInterceptor() {
return new CqlExceptionHandlingInterceptor();
}
@Bean
public CqlTranslatorOptions cqlTranslatorOptions(FhirContext theFhirContext, CrProperties.CqlProperties theCqlProperties) {
CqlTranslatorOptions options = theCqlProperties.getCqlOptions().getCqlTranslatorOptions();
return options;
}
@Bean
public ModelManager modelManager(
Map<ModelIdentifier, Model> theGlobalModelCache) {
return new CacheAwareModelManager(theGlobalModelCache);
}
@Bean
public ILibraryManagerFactory libraryManagerFactory(
ModelManager theModelManager) {
return (providers) -> {
LibraryManager libraryManager = new LibraryManager(theModelManager);
for (LibrarySourceProvider provider : providers) {
libraryManager.getLibrarySourceLoader().registerProvider(provider);
}
return libraryManager;
};
}
@Bean
public SearchParameterResolver searchParameterResolver(FhirContext theFhirContext) {
return new SearchParameterResolver(theFhirContext);
}
@Bean
IFhirDalFactory fhirDalFactory(DaoRegistry theDaoRegistry) {
return rd -> new HapiFhirDal(theDaoRegistry, rd);
}
@Bean
IDataProviderFactory dataProviderFactory(ModelResolver theModelResolver, DaoRegistry theDaoRegistry,
SearchParameterResolver theSearchParameterResolver) {
return (rd, t) -> {
HapiFhirRetrieveProvider provider = new HapiFhirRetrieveProvider(theDaoRegistry, theSearchParameterResolver, rd);
if (t != null) {
provider.setTerminologyProvider(t);
provider.setExpandValueSets(true);
provider.setMaxCodesPerQuery(500);
provider.setModelResolver(theModelResolver);
}
return new CompositeDataProvider(theModelResolver, provider);
};
}
@Bean
org.opencds.cqf.cql.evaluator.builder.DataProviderFactory builderDataProviderFactory(FhirContext theFhirContext, ModelResolver theModelResolver) {
return new org.opencds.cqf.cql.evaluator.builder.DataProviderFactory() {
@Override
public DataProviderComponents create(EndpointInfo theEndpointInfo) {
// to do implement endpoint
return null;
}
@Override
public DataProviderComponents create(IBaseBundle theDataBundle) {
return new DataProviderComponents(Constants.FHIR_MODEL_URI, theModelResolver,
new BundleRetrieveProvider(theFhirContext, theDataBundle));
}
};
}
@Bean
public HapiFhirRetrieveProvider fhirRetrieveProvider(DaoRegistry theDaoRegistry,
SearchParameterResolver theSearchParameterResolver) {
return new HapiFhirRetrieveProvider(theDaoRegistry, theSearchParameterResolver);
}
@Bean
public ITerminologyProviderFactory terminologyProviderFactory(
IValidationSupport theValidationSupport,
Map<org.cqframework.cql.elm.execution.VersionedIdentifier, List<Code>> theGlobalCodeCache) {
return rd -> new HapiTerminologyProvider(theValidationSupport, theGlobalCodeCache,
rd);
}
@Bean
ILibrarySourceProviderFactory librarySourceProviderFactory(DaoRegistry theDaoRegistry) {
return rd -> new HapiLibrarySourceProvider(theDaoRegistry, rd);
}
@Bean
ILibraryLoaderFactory libraryLoaderFactory(
Map<org.cqframework.cql.elm.execution.VersionedIdentifier, org.cqframework.cql.elm.execution.Library> theGlobalLibraryCache,
ModelManager theModelManager, CqlTranslatorOptions theCqlTranslatorOptions, CrProperties.CqlProperties theCqlProperties) {
return lcp -> {
if (theCqlProperties.getCqlOptions().useEmbeddedLibraries()) {
lcp.add(new FhirLibrarySourceProvider());
}
return new CacheAwareLibraryLoaderDecorator(
new TranslatingLibraryLoader(theModelManager, lcp, theCqlTranslatorOptions, null), theGlobalLibraryCache) {
// TODO: This is due to a bug with the ELM annotations which prevent options
// from matching the way they should
@Override
protected Boolean translatorOptionsMatch(org.cqframework.cql.elm.execution.Library library) {
return true;
}
};
};
}
// TODO: Use something like caffeine caching for this so that growth is limited.
@Bean
public Map<org.cqframework.cql.elm.execution.VersionedIdentifier, org.cqframework.cql.elm.execution.Library> globalLibraryCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<org.cqframework.cql.elm.execution.VersionedIdentifier, List<Code>> globalCodeCache() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<ModelIdentifier, Model> globalModelCache() {
return new ConcurrentHashMap<>();
}
@Bean
@Primary
public ElmCacheResourceChangeListener elmCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, DaoRegistry theDaoRegistry,
Map<org.cqframework.cql.elm.execution.VersionedIdentifier, org.cqframework.cql.elm.execution.Library> theGlobalLibraryCache) {
ElmCacheResourceChangeListener listener = new ElmCacheResourceChangeListener(theDaoRegistry, theGlobalLibraryCache);
theResourceChangeListenerRegistry.registerResourceResourceChangeListener("Library",
SearchParameterMap.newSynchronous(), listener, 1000);
return listener;
}
@Bean
@Primary
public CodeCacheResourceChangeListener codeCacheResourceChangeListener(
IResourceChangeListenerRegistry theResourceChangeListenerRegistry, DaoRegistry theDaoRegistry,
Map<org.cqframework.cql.elm.execution.VersionedIdentifier, List<Code>> theGlobalCodeCache) {
CodeCacheResourceChangeListener listener = new CodeCacheResourceChangeListener(theDaoRegistry, theGlobalCodeCache);
theResourceChangeListenerRegistry.registerResourceResourceChangeListener("ValueSet",
SearchParameterMap.newSynchronous(), listener, 1000);
return listener;
}
@Bean
public ModelResolver modelResolver(FhirContext theFhirContext) {
return new CachingModelResolverDecorator(new Dstu3FhirModelResolver());
}
@Bean
public LibraryVersionSelector libraryVersionSelector(AdapterFactory theAdapterFactory) {
return new LibraryVersionSelector(theAdapterFactory);
}
@Bean(name = "cqlExecutor")
public Executor cqlExecutor() {
CqlForkJoinWorkerThreadFactory factory = new CqlForkJoinWorkerThreadFactory();
ForkJoinPool myCommonPool = new ForkJoinPool(Math.min(32767, Runtime.getRuntime().availableProcessors()),
factory,
null, false);
return new DelegatingSecurityContextExecutor(myCommonPool,
SecurityContextHolder.getContext());
}
@Bean
public PreExpandedValidationSupportLoader preExpandedValidationSupportLoader(ValidationSupportChain theSupportChain,
FhirContext theFhirContext) {
return new PreExpandedValidationSupportLoader(theSupportChain, theFhirContext);
}
}

View File

@ -0,0 +1,42 @@
package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.cr.BaseCrR4Test;
import ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.MedicationRequest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ActivityDefinitionOperationsProviderTest extends BaseCrR4Test {
@Autowired
ActivityDefinitionOperationsProvider activityDefinitionOperationsProvider;
@Test
void testActivityDefinitionApply() {
loadBundle("ca/uhn/fhir/cr/r4/Bundle-ActivityDefinitionTest.json");
var requestDetails = setupRequestDetails();
var result = this.activityDefinitionOperationsProvider.apply(
new IdType("activityDefinition-test"),
null,
null,
"patient-1",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
requestDetails);
assertTrue(result instanceof MedicationRequest);
MedicationRequest request = (MedicationRequest) result;
assertTrue(request.getDoNotPerform());
}
}

View File

@ -31,14 +31,6 @@ public class HapiFhirRepositoryR4Test extends BaseCrR4Test {
private static final String MY_TEST_DATA =
"ca/uhn/fhir/cr/r4/immunization/Patients_Encounters_Immunizations_Practitioners.json";
private RequestDetails setupRequestDetails() {
var requestDetails = new ServletRequestDetails();
requestDetails.setServletRequest(new MockHttpServletRequest());
requestDetails.setServer(ourRestServer);
requestDetails.setFhirServerBase(ourServerBase);
return requestDetails;
}
@Test
void crudTest() {
var requestDetails = setupRequestDetails();

View File

@ -0,0 +1,87 @@
package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.cr.BaseCrR4Test;
import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.PlanDefinition;
import org.hl7.fhir.r4.model.Questionnaire;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class PlanDefinitionOperationsProviderTest extends BaseCrR4Test {
@Autowired
PlanDefinitionOperationsProvider planDefinitionOperationsProvider;
@Test
void testCdsHooksMultiAction() {
loadBundle("ca/uhn/fhir/cr/r4/cds-hooks-multi-action/cds_hooks_multiple_actions_patient_data.json");
loadBundle("ca/uhn/fhir/cr/r4/cds-hooks-multi-action/cds_hooks_multiple_actions_plan_definition.json");
var requestDetails = setupRequestDetails();
var planDefinitionID = new IdType("PlanDefinition","CdsHooksMultipleActions-PlanDefinition-1.0.0");
var patientID = "patient-CdsHooksMultipleActions";
var result = this.planDefinitionOperationsProvider.apply(planDefinitionID, null, null, patientID,
null, null, null, null, null,
null, null, null, null, null,
null, null, null,
requestDetails);
assertNotNull(result);
var carePlan = readResource(CarePlan.class, "ca/uhn/fhir/cr/r4/cds-hooks-multi-action/cds_hooks_multiple_actions_careplan.json");
assertEquals(ourParser.encodeResourceToString(carePlan), ourParser.encodeResourceToString(result));
var resultR5 = this.planDefinitionOperationsProvider.applyR5(planDefinitionID, null, null, patientID,
null, null, null, null, null,
null, null, null, null, null,
null, null, null,
requestDetails);
var bundle = readResource(Bundle.class, "ca/uhn/fhir/cr/r4/cds-hooks-multi-action/cds_hooks_multiple_actions_bundle.json");
assertEquals(ourParser.encodeResourceToString(bundle), ourParser.encodeResourceToString(resultR5));
}
@Test
void testGenerateQuestionnaire() {
loadBundle("ca/uhn/fhir/cr/r4/Bundle-GenerateQuestionnaireContent.json");
loadBundle("ca/uhn/fhir/cr/r4/Bundle-GenerateQuestionnaireStructures.json");
loadBundle("ca/uhn/fhir/cr/r4/Bundle-PatientData.json");
var requestDetails = setupRequestDetails();
var planDefinitionID = new IdType(Enumerations.FHIRAllTypes.PLANDEFINITION.toCode(), "ASLPA1");
var patientID = "positive";
var parameters = new Parameters().addParameter("Service Request Id", "SleepStudy").addParameter("Service Request Id", "SleepStudy2");
var result = (CarePlan) this.planDefinitionOperationsProvider.apply(planDefinitionID, null, null, patientID,
null, null, null, null, null,
null, null, null, parameters, null,
null, null, null,
requestDetails);
assertNotNull(result);
assertEquals("Sleep Study",
((Questionnaire) result.getContained().get(1))
.getItem().get(0)
.getItem().get(0)
.getText());
var resultR5 = (Bundle) this.planDefinitionOperationsProvider.applyR5(planDefinitionID, null, null, patientID,
null, null, null, null, null,
null, null, null, parameters, null,
null, null, null,
requestDetails);
assertNotNull(resultR5);
assertEquals("Sleep Study",
((Questionnaire) resultR5.getEntry().get(1)
.getResource()).getItem().get(0)
.getItem().get(0)
.getText());
}
}

View File

@ -0,0 +1,65 @@
package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.cr.BaseCrR4Test;
import ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.Enumerations;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class QuestionnaireOperationsProviderTest extends BaseCrR4Test {
@Autowired
QuestionnaireOperationsProvider questionnaireOperationsProvider;
@Test
void testPopulate() {
loadBundle("ca/uhn/fhir/cr/r4/Bundle-QuestionnairePackage.json");
loadBundle("ca/uhn/fhir/cr/r4/Bundle-PatientData.json");
var requestDetails = setupRequestDetails();
var theSubject = "positive";
var parameters = new Parameters().addParameter("Service Request Id", "SleepStudy").addParameter("Service Request Id", "SleepStudy2");
var result = this.questionnaireOperationsProvider.populate(new IdType("Questionnaire", "ASLPA1"),
null, null, theSubject, parameters,
null, null, null, null,
requestDetails);
assertNotNull(result);
assertEquals("Patient/" + theSubject, result.getSubject().getReference());
assertTrue(result.getItem().get(0).getItem().get(0).hasAnswer());
}
@Test
void testPrePopulate() {
loadBundle("ca/uhn/fhir/cr/r4/Bundle-QuestionnairePackage.json");
loadBundle("ca/uhn/fhir/cr/r4/Bundle-PatientData.json");
var requestDetails = setupRequestDetails();
var theSubject = "positive";
var parameters = new Parameters().addParameter("Service Request Id", "SleepStudy").addParameter("Service Request Id", "SleepStudy2");
var result = this.questionnaireOperationsProvider.prepopulate(new IdType("Questionnaire", "ASLPA1"),
null, null, theSubject, parameters,
null, null, null, null,
requestDetails);
assertNotNull(result);
assertTrue(result.getItem().get(0).getItem().get(0).hasInitial());
}
@Test
void testQuestionnairePackage() {
loadBundle("ca/uhn/fhir/cr/r4/Bundle-QuestionnairePackage.json");
var requestDetails = setupRequestDetails();
var result = this.questionnaireOperationsProvider.packageQuestionnaire(null,
"http://example.org/sdh/dtr/aslp/Questionnaire/ASLPA1", "true",
requestDetails);
assertNotNull(result);
assertEquals(11, result.getEntry().size());
assertTrue(result.getEntry().get(0).getResource().fhirType().equals(Enumerations.FHIRAllTypes.QUESTIONNAIRE.toCode()));
}
}

View File

@ -0,0 +1,30 @@
package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.cr.BaseCrR4Test;
import ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class QuestionnaireResponseOperationsProviderTest extends BaseCrR4Test {
@Autowired
QuestionnaireResponseOperationsProvider questionnaireResponseOperationsProvider;
@Test
void testExtract() throws IOException {
var requestDetails = setupRequestDetails();
loadResource(Questionnaire.class, "ca/uhn/fhir/cr/r4/Questionnaire-MyPainQuestionnaire.json", requestDetails);
var questionnaireResponse = readResource(QuestionnaireResponse.class, "ca/uhn/fhir/cr/r4/QuestionnaireResponse-QRSharonDecision.json");
var result = (Bundle) this.questionnaireResponseOperationsProvider.extract(null, questionnaireResponse, requestDetails);
assertNotNull(result);
assertEquals(5, result.getEntry().size());
}
}

View File

@ -0,0 +1,63 @@
package ca.uhn.fhir.cr.r4;
import ca.uhn.fhir.cr.TestCrConfig;
import ca.uhn.fhir.cr.r4.IActivityDefinitionProcessorFactory;
import ca.uhn.fhir.cr.r4.IPlanDefinitionProcessorFactory;
import ca.uhn.fhir.cr.r4.IQuestionnaireProcessorFactory;
import ca.uhn.fhir.cr.r4.IQuestionnaireResponseProcessorFactory;
import ca.uhn.fhir.cr.r4.activitydefinition.ActivityDefinitionOperationsProvider;
import ca.uhn.fhir.cr.r4.plandefinition.PlanDefinitionOperationsProvider;
import ca.uhn.fhir.cr.r4.questionnaire.QuestionnaireOperationsProvider;
import ca.uhn.fhir.cr.r4.questionnaireresponse.QuestionnaireResponseOperationsProvider;
import org.opencds.cqf.cql.evaluator.activitydefinition.r4.ActivityDefinitionProcessor;
import org.opencds.cqf.cql.evaluator.plandefinition.r4.PlanDefinitionProcessor;
import org.opencds.cqf.cql.evaluator.questionnaire.r4.QuestionnaireProcessor;
import org.opencds.cqf.cql.evaluator.questionnaireresponse.r4.QuestionnaireResponseProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import(TestCrConfig.class)
public class TestCrR4Config {
@Bean
IActivityDefinitionProcessorFactory r4ActivityDefinitionProcessorFactory() {
return r -> new ActivityDefinitionProcessor(r);
}
@Bean
public ActivityDefinitionOperationsProvider r4ActivityDefinitionOperationsProvider() {
return new ActivityDefinitionOperationsProvider();
}
@Bean
IPlanDefinitionProcessorFactory r4PlanDefinitionProcessorFactory() {
return r -> new PlanDefinitionProcessor(r);
}
@Bean
public PlanDefinitionOperationsProvider r4PlanDefinitionOperationsProvider() {
return new PlanDefinitionOperationsProvider();
}
@Bean
IQuestionnaireProcessorFactory r4QuestionnaireProcessorFactory() {
return r -> new QuestionnaireProcessor(r);
}
@Bean
public QuestionnaireOperationsProvider r4QuestionnaireOperationsProvider() {
return new QuestionnaireOperationsProvider();
}
@Bean
IQuestionnaireResponseProcessorFactory r4QuestionnaireResponseProcessorFactory() {
return r -> new QuestionnaireResponseProcessor(r);
}
@Bean
public QuestionnaireResponseOperationsProvider r4QuestionnaireResponseOperationsProvider() {
return new QuestionnaireResponseOperationsProvider();
}
}

View File

@ -0,0 +1,73 @@
{
"resourceType": "Bundle",
"id": "bundle-test",
"type": "transaction",
"entry" : [{
"resource": {
"resourceType": "ActivityDefinition",
"id": "activityDefinition-test",
"name": "ActivityDefinition_CreateAProcedure",
"title": "CreateProcedure",
"status": "draft",
"description": "Create the procedure.",
"library": [ "http://test/fhir/Library/TestActivityDefinition|1.0.0" ],
"kind": "MedicationRequest",
"productCodeableConcept": {
"coding": [{
"system": "http://test/fhir/System",
"code": "productCode"
}]
},
"dynamicValue": [
{
"path": "doNotPerform",
"expression": {
"language": "text/cql.name",
"expression": "ActiveProcedureStatus"
}
}
]
},
"request": {
"method": "PUT",
"url": "ActivityDefinition/activityDefinition-test"
}
},
{
"resource": {
"resourceType": "Library",
"id": "TestActivityDefinition",
"url": "http://test/fhir/Library/TestActivityDefinition|1.0.0",
"version": "1.0.0",
"name": "TestActivityDefinition",
"parameter": [ {
"name": "ActiveProcedureStatus",
"use": "out",
"min": 0,
"max": "1",
"type": "boolean"
} ],
"content": [ {
"contentType": "text/cql",
"data": "bGlicmFyeSBUZXN0QWN0aXZpdHlEZWZpbml0aW9uIHZlcnNpb24gJzEuMC4wJw0KDQpkZWZpbmUgIkFjdGl2ZVByb2NlZHVyZVN0YXR1cyI6IHRydWUNCg=="
}, {
"contentType": "application/elm+xml",
"data": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxsaWJyYXJ5IHhtbG5zPSJ1cm46aGw3LW9yZzplbG06cjEiIHhtbG5zOnQ9InVybjpobDctb3JnOmVsbS10eXBlczpyMSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6Zmhpcj0iaHR0cDovL2hsNy5vcmcvZmhpciIgeG1sbnM6cWRtNDM9InVybjpoZWFsdGhpdC1nb3Y6cWRtOnY0XzMiIHhtbG5zOnFkbTUzPSJ1cm46aGVhbHRoaXQtZ292OnFkbTp2NV8zIiB4bWxuczphPSJ1cm46aGw3LW9yZzpjcWwtYW5ub3RhdGlvbnM6cjEiPg0KICAgPGFubm90YXRpb24gdHJhbnNsYXRvck9wdGlvbnM9IkVuYWJsZUFubm90YXRpb25zLEVuYWJsZUxvY2F0b3JzLERpc2FibGVMaXN0RGVtb3Rpb24sRGlzYWJsZUxpc3RQcm9tb3Rpb24iIHhzaTp0eXBlPSJhOkNxbFRvRWxtSW5mbyIvPg0KICAgPGFubm90YXRpb24geHNpOnR5cGU9ImE6QW5ub3RhdGlvbiI+DQogICAgICA8YTpzIHI9IjIiPg0KICAgICAgICAgPGE6cz5saWJyYXJ5IFRlc3RBY3Rpdml0eURlZmluaXRpb24gdmVyc2lvbiAnMS4wLjAnPC9hOnM+DQogICAgICA8L2E6cz4NCiAgIDwvYW5ub3RhdGlvbj4NCiAgIDxpZGVudGlmaWVyIGlkPSJUZXN0QWN0aXZpdHlEZWZpbml0aW9uIiBzeXN0ZW09Imh0dHA6Ly9hcGhsLm9yZy9maGlyL2VjciIgdmVyc2lvbj0iMS4wLjAiLz4NCiAgIDxzY2hlbWFJZGVudGlmaWVyIGlkPSJ1cm46aGw3LW9yZzplbG0iIHZlcnNpb249InIxIi8+DQogICA8dXNpbmdzPg0KICAgICAgPGRlZiBsb2NhbElkZW50aWZpZXI9IlN5c3RlbSIgdXJpPSJ1cm46aGw3LW9yZzplbG0tdHlwZXM6cjEiLz4NCiAgIDwvdXNpbmdzPg0KICAgPHN0YXRlbWVudHM+DQogICAgICA8ZGVmIGxvY2FsSWQ9IjIiIGxvY2F0b3I9IjM6MS0zOjM2IiBuYW1lPSJBY3RpdmVQcm9jZWR1cmVTdGF0dXMiIGNvbnRleHQ9IlBhdGllbnQiIGFjY2Vzc0xldmVsPSJQdWJsaWMiPg0KICAgICAgICAgPGFubm90YXRpb24geHNpOnR5cGU9ImE6QW5ub3RhdGlvbiI+DQogICAgICAgICAgICA8YTpzIHI9IjIiPg0KICAgICAgICAgICAgICAgPGE6cyByPSIxIj5kZWZpbmUgJnF1b3Q7QWN0aXZlUHJvY2VkdXJlU3RhdHVzJnF1b3Q7OiB0cnVlPC9hOnM+DQogICAgICAgICAgICA8L2E6cz4NCiAgICAgICAgIDwvYW5ub3RhdGlvbj4NCiAgICAgICAgIDxleHByZXNzaW9uIGxvY2FsSWQ9IjEiIGxvY2F0b3I9IjM6MzMtMzozNiIgdmFsdWVUeXBlPSJ0OkJvb2xlYW4iIHZhbHVlPSJ0cnVlIiB4c2k6dHlwZT0iTGl0ZXJhbCIvPg0KICAgICAgPC9kZWY+DQogICA8L3N0YXRlbWVudHM+DQo8L2xpYnJhcnk+DQo="
} ]
},
"request": {
"method": "PUT",
"url": "Library/TestActivityDefinition"
}
},
{
"resource": {
"resourceType": "Patient",
"id": "patient-1"
},
"request": {
"method": "PUT",
"url": "Patient/patient-1"
}
}]
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,824 @@
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-bmi",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-bmi",
"name": "ASLPBMI",
"title": "ASLP BMI",
"status": "draft",
"experimental": false,
"description": "ASLP BMI",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "BMI",
"definition": "Body mass index (BMI)",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE22"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "BMI",
"definition": "Body mass index (BMI)",
"min": 1,
"max": "1",
"type": [
{
"code": "Quantity"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE22"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-bmi"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-diagnosis-of-obstructive-sleep-apnea",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-diagnosis-of-obstructive-sleep-apnea",
"name": "ASLPDiagnosisofObstructiveSleepApnea",
"title": "ASLP Diagnosis of Obstructive Sleep Apnea",
"status": "draft",
"experimental": false,
"description": "ASLP Diagnosis of Obstructive Sleep Apnea",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Condition",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Condition",
"path": "Condition",
"mustSupport": false
},
{
"id": "Condition.code",
"path": "Condition.code",
"short": "Diagnosis of Obstructive Sleep Apnea",
"definition": "Diagnosis of Obstructive Sleep Apnea",
"min": 1,
"max": "1",
"mustSupport": true,
"binding": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
"valueString": "Diagnosis of Obstructive Sleep Apnea Codes"
}
],
"strength": "required",
"valueSet": "http://example.org/sdh/dtr/aslp/ValueSet/aslp-a1-de17"
},
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE16"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-diagnosis-of-obstructive-sleep-apnea"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-height",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-height",
"name": "ASLPHeight",
"title": "ASLP Height",
"status": "draft",
"experimental": false,
"description": "ASLP Height",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "Height",
"definition": "Height (in inches)",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE20"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "Height",
"definition": "Height (in inches)",
"min": 1,
"max": "1",
"type": [
{
"code": "Quantity"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE20"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-height"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-history-of-diabetes",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-history-of-diabetes",
"name": "ASLPHistoryofDiabetes",
"title": "ASLP History of Diabetes",
"status": "draft",
"experimental": false,
"description": "ASLP History of Diabetes",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "History of Diabetes",
"definition": "History of Diabetes",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE19"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "History of Diabetes",
"definition": "History of Diabetes",
"min": 1,
"max": "1",
"type": [
{
"code": "boolean"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE19"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-history-of-diabetes"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-history-of-hypertension",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-history-of-hypertension",
"name": "ASLPHistoryofHypertension",
"title": "ASLP History of Hypertension",
"status": "draft",
"experimental": false,
"description": "ASLP History of Hypertension",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "History of Hypertension",
"definition": "History of Hypertension",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE18"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "History of Hypertension",
"definition": "History of Hypertension",
"min": 1,
"max": "1",
"type": [
{
"code": "boolean"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE18"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-history-of-hypertension"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-neck-circumference",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-neck-circumference",
"name": "ASLPNeckCircumference",
"title": "ASLP Neck Circumference",
"status": "draft",
"experimental": false,
"description": "ASLP Neck Circumference",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "Neck Circumference",
"definition": "Neck circumference (in inches)",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE20"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "Neck Circumference",
"definition": "Neck circumference (in inches)",
"min": 1,
"max": "1",
"type": [
{
"code": "Quantity"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE20"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-neck-circumference"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-servicerequest",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-servicerequest",
"name": "ASLPServiceRequest",
"title": "ASLP ServiceRequest",
"status": "draft",
"experimental": false,
"description": "ASLP ServiceRequest",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "ServiceRequest",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-servicerequest",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "ServiceRequest",
"path": "ServiceRequest",
"mustSupport": false
},
{
"id": "ServiceRequest.code",
"path": "ServiceRequest.code",
"short": "Procedure Code",
"definition": "The procedures being approved",
"comment": "The procedures for which approval is being requested",
"min": 1,
"max": "1",
"mustSupport": true,
"binding": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
"valueString": "Procedure Code Codes Grouper"
}
],
"strength": "required",
"valueSet": "http://example.org/sdh/dtr/aslp/ValueSet/aslp-a1-de1-codes-grouper"
},
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE1"
}
]
},
{
"id": "ServiceRequest.occurrence[x]",
"path": "ServiceRequest.occurrence[x]",
"short": "Procedure Date",
"definition": "Date of the procedure",
"min": 1,
"max": "1",
"type": [
{
"code": "dateTime"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ALSP.A1.DE15"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-servicerequest"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-sleep-study-order",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-sleep-study-order",
"name": "ASLPSleepStudyOrder",
"title": "ASLP Sleep Study Order",
"status": "draft",
"experimental": false,
"description": "ASLP Sleep Study Order",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "ServiceRequest",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-servicerequest",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "ServiceRequest",
"path": "ServiceRequest",
"mustSupport": false
},
{
"id": "ServiceRequest.code",
"path": "ServiceRequest.code",
"short": "Sleep Study",
"definition": "A sleep study procedure being ordered",
"comment": "The procedures for which approval is being requested",
"min": 1,
"max": "1",
"type": [
{
"code": "CodeableConcept"
}
],
"mustSupport": true,
"binding": {
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
"valueString": "Sleep Study Codes Grouper"
}
],
"strength": "required",
"valueSet": "http://example.org/sdh/dtr/aslp/ValueSet/aslp-a1-de1-codes-grouper"
},
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE1"
}
]
},
{
"id": "ServiceRequest.occurrence[x]",
"path": "ServiceRequest.occurrence[x]",
"short": "Sleep Study Date",
"definition": "Date of the procedure",
"min": 1,
"max": "1",
"type": [
{
"code": "dateTime"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ALSP.A1.DE15"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-sleep-study-order"
}
},
{
"resource": {
"resourceType": "StructureDefinition",
"id": "aslp-weight",
"url": "http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-weight",
"name": "ASLPWeight",
"title": "ASLP Weight",
"status": "draft",
"experimental": false,
"description": "ASLP Weight",
"useContext": [
{
"code": {
"system": "http://terminology.hl7.org/CodeSystem/usage-context-type",
"code": "task",
"display": "Workflow Task"
},
"valueCodeableConcept": {
"coding": [
{
"system": "http://fhir.org/guides/nachc/hiv-cds/CodeSystem/activity-codes",
"code": "ASLP.A1",
"display": "Adult Sleep Studies"
}
]
}
}
],
"fhirVersion": "4.0.1",
"mapping": [
{
"identity": "ASLP"
}
],
"kind": "resource",
"abstract": false,
"type": "Observation",
"baseDefinition": "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation",
"derivation": "constraint",
"differential": {
"element": [
{
"id": "Observation",
"path": "Observation",
"mustSupport": false
},
{
"id": "Observation.code",
"path": "Observation.code",
"short": "Weight",
"definition": "Weight (in pounds)",
"min": 1,
"max": "1",
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE21"
}
]
},
{
"id": "Observation.value[x]",
"path": "Observation.value[x]",
"short": "Weight",
"definition": "Weight (in pounds)",
"min": 1,
"max": "1",
"type": [
{
"code": "Quantity"
}
],
"mustSupport": true,
"mapping": [
{
"identity": "ASLP",
"map": "ASLP.A1.DE21"
}
]
}
]
}
},
"request": {
"method": "PUT",
"url": "StructureDefinition/aslp-weight"
}
}
]
}

View File

@ -0,0 +1,857 @@
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Patient",
"id": "positive",
"meta": {
"profile": [
"http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-patient",
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
]
},
"extension": [
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race",
"extension": [
{
"url": "ombCategory",
"valueCoding": {
"system": "urn:oid:2.16.840.1.113883.6.238",
"code": "2054-5",
"display": "Black or African American"
}
}
]
},
{
"url": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity",
"extension": [
{
"url": "ombCategory",
"valueCoding": {
"system": "urn:oid:2.16.840.1.113883.6.238",
"code": "2135-2",
"display": "Hispanic or Latino"
}
}
]
}
],
"identifier": [
{
"use": "usual",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
"code": "MR",
"display": "Medical Record Number"
}
]
},
"system": "http://hospital.smarthealthit.org",
"value": "9999999910"
}
],
"name": [
{
"family": "Jones",
"given": [
"Rick"
]
}
],
"gender": "male",
"birthDate": "1955-11-05"
},
"request": {
"method": "PUT",
"url": "Patient/positive"
}
},
{
"resource": {
"resourceType": "Practitioner",
"id": "Practitioner-positive",
"meta": {
"profile": [
"http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-practitioner"
]
},
"identifier": [
{
"system": "http://hl7.org/fhir/sid/us-npi",
"value": "9941339108"
},
{
"system": "http://www.acme.org/practitioners",
"value": "25456"
}
],
"name": [
{
"family": "Careful",
"given": [
"Adam"
],
"prefix": [
"Dr"
]
}
],
"address": [
{
"use": "home",
"line": [
"1003 Healthcare Drive"
],
"city": "Amherst",
"state": "MA",
"postalCode": "01002"
}
],
"qualification": [
{
"identifier": [
{
"system": "http://example.org/UniversityIdentifier",
"value": "12345"
}
],
"code": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0360",
"code": "BS",
"display": "Bachelor of Science"
}
],
"text": "Bachelor of Science"
},
"period": {
"start": "1995"
},
"issuer": {
"display": "Example University"
}
}
]
},
"request": {
"method": "PUT",
"url": "Practitioner/positive"
}
},
{
"resource": {
"resourceType": "Coverage",
"id": "Coverage-positive",
"meta": {
"profile": [
"http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-coverage"
]
},
"identifier": [
{
"system": "http://example.com/fhir/NampingSystem/certificate",
"value": "12345"
}
],
"status": "active",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
"code": "EHCPOL",
"display": "extended healthcare"
}
]
},
"policyHolder": {
"reference": "http://example.org/FHIR/Organization/CBI35"
},
"subscriber": {
"reference": "Patient/positive"
},
"beneficiary": {
"reference": "Patient/positive"
},
"dependent": "0",
"relationship": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship",
"code": "self"
}
]
},
"period": {
"start": "2011-05-23",
"end": "2030-05-23"
},
"payor": [
{
"reference": "http://example.org/fhir/Organization/example-payer",
"display": "Payer XYZ"
}
],
"class": [
{
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/coverage-class",
"code": "group"
}
]
},
"value": "CB135",
"name": "Corporate Baker's Inc. Local #35"
}
]
},
"request": {
"method": "PUT",
"url": "Coverage/positive"
}
},
{
"resource": {
"resourceType": "Condition",
"id": "Diabetes",
"meta": {
"profile": [
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition-encounter-diagnosis"
]
},
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}
]
},
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-category",
"code": "encounter-diagnosis",
"display": "Encounter Diagnosis"
}
]
}
],
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE19",
"display": "History of Diabetes"
}
]
},
"subject": {
"reference": "Patient/positive"
},
"onsetDateTime": "2015-10-31",
"recordedDate": "2015-11-01"
},
"request": {
"method": "PUT",
"url": "Condition/Diabetes"
}
},
{
"resource": {
"resourceType": "Condition",
"id": "Hypertension",
"meta": {
"profile": [
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition-encounter-diagnosis"
]
},
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}
]
},
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-category",
"code": "encounter-diagnosis",
"display": "Encounter Diagnosis"
}
]
}
],
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE18",
"display": "History of Hypertension"
}
]
},
"subject": {
"reference": "Patient/positive"
},
"onsetDateTime": "2015-10-31",
"recordedDate": "2015-11-01"
},
"request": {
"method": "PUT",
"url": "Condition/Hypertension"
}
},
{
"resource": {
"resourceType": "Condition",
"id": "SleepApnea",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-diagnosis-of-obstructive-sleep-apnea",
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition"
]
},
"clinicalStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-clinical",
"code": "active"
}
]
},
"verificationStatus": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-ver-status",
"code": "confirmed"
}
]
},
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/condition-category",
"code": "encounter-diagnosis",
"display": "Encounter Diagnosis"
}
]
}
],
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE17",
"display": "Obstructive sleep apnea (OSA)"
}
]
},
"subject": {
"reference": "Patient/positive"
},
"onsetDateTime": "2015-10-31",
"recordedDate": "2015-11-01"
},
"request": {
"method": "PUT",
"url": "Condition/SleepApnea"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "BloodPressure",
"meta": {
"profile": [
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-blood-pressure",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://loinc.org",
"code": "85354-9",
"display": "Blood pressure panel with all children optional"
},
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE18",
"display": "Blood pressure panel with all children optional"
}
],
"text": "Blood pressure systolic and diastolic"
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-02T09:45:10+01:00",
"issued": "2023-04-03T15:45:10+01:00",
"component": [
{
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8480-6",
"display": "Systolic blood pressure"
}
],
"text": "Systolic blood pressure"
},
"valueQuantity": {
"value": 109,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
},
{
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8462-4",
"display": "Diastolic blood pressure"
}
],
"text": "Diastolic blood pressure"
},
"valueQuantity": {
"value": 44,
"unit": "mmHg",
"system": "http://unitsofmeasure.org",
"code": "mm[Hg]"
}
}
]
},
"request": {
"method": "PUT",
"url": "Observation/BloodPressure"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "BMI",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-bmi",
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-bmi",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "39156-5",
"display": "Body mass index (BMI) [Ratio]"
},
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE22",
"display": "Body mass index (BMI) [Ratio]"
}
],
"text": "BMI"
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-04",
"valueQuantity": {
"value": 16.2,
"unit": "kg/m2",
"system": "http://unitsofmeasure.org",
"code": "kg/m2"
}
},
"request": {
"method": "PUT",
"url": "Observation/BMI"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "Glucose",
"meta": {
"profile": [
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation-lab",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "laboratory",
"display": "Laboratory"
}
],
"text": "Laboratory"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "15074-8",
"display": "Glucose [Moles/volume] in Blood"
},
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE19",
"display": "Glucose [Moles/volume] in Blood"
}
]
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-02T09:30:10+01:00",
"issued": "2023-04-03T15:30:10+01:00",
"valueQuantity": {
"value": 8.0,
"unit": "mmol/l",
"system": "http://unitsofmeasure.org",
"code": "mmol/L"
},
"interpretation": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation",
"code": "H",
"display": "High"
}
]
}
],
"referenceRange": [
{
"low": {
"value": 3.1,
"unit": "mmol/l",
"system": "http://unitsofmeasure.org",
"code": "mmol/L"
},
"high": {
"value": 7.5,
"unit": "mmol/l",
"system": "http://unitsofmeasure.org",
"code": "mmol/L"
}
}
]
},
"request": {
"method": "PUT",
"url": "Observation/Glucose"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "Height",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-height",
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-height",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "8302-2",
"display": "Body height"
},
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE20",
"display": "Body height"
}
],
"text": "height"
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-04",
"valueQuantity": {
"value": 69,
"unit": "in",
"system": "http://unitsofmeasure.org",
"code": "[in_i]"
}
},
"request": {
"method": "PUT",
"url": "Observation/Height"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "Neck",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-neck-circumference",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "exam",
"display": "Exam"
}
],
"text": "Exam"
}
],
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE23",
"display": "Neck Circumference"
}
],
"text": "Neck Circumference"
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-04",
"valueQuantity": {
"value": 16,
"unit": "in",
"system": "http://unitsofmeasure.org",
"code": "[in_i]"
}
},
"request": {
"method": "PUT",
"url": "Observation/Neck"
}
},
{
"resource": {
"resourceType": "Observation",
"id": "Weight",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-weight",
"http://hl7.org/fhir/us/core/StructureDefinition/us-core-body-weight",
"http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation"
]
},
"status": "final",
"category": [
{
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
"code": "vital-signs",
"display": "Vital Signs"
}
],
"text": "Vital Signs"
}
],
"code": {
"coding": [
{
"system": "http://loinc.org",
"code": "29463-7",
"display": "Body Weight"
},
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE21",
"display": "Body weight"
}
],
"text": "weight"
},
"subject": {
"reference": "Patient/positive"
},
"effectiveDateTime": "2023-04-04",
"valueQuantity": {
"value": 185,
"unit": "[lb_av]",
"system": "http://unitsofmeasure.org",
"code": "[lb_av]"
}
},
"request": {
"method": "PUT",
"url": "Observation/Weight"
}
},
{
"resource": {
"resourceType": "ServiceRequest",
"id": "SleepStudy",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-sleep-study-order",
"http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-servicerequest"
]
},
"status": "draft",
"intent": "order",
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE2",
"display": "Home sleep apnea testing (HSAT)"
}
],
"text": "Home sleep apnea testing (HSAT)"
},
"subject": {
"reference": "Patient/positive"
},
"authoredOn": "2023-04-06",
"reasonReference": [
{
"reference": "Condition/SleepApnea"
}
],
"occurrenceDateTime": "2023-04-10",
"requester": {
"reference": "Practitioner/positive-Practitioner"
}
},
"request": {
"method": "PUT",
"url": "ServiceRequest/SleepStudy"
}
},
{
"resource": {
"resourceType": "ServiceRequest",
"id": "SleepStudy2",
"meta": {
"profile": [
"http://example.org/sdh/dtr/aslp/StructureDefinition/aslp-sleep-study-order",
"http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-servicerequest"
]
},
"status": "draft",
"intent": "order",
"code": {
"coding": [
{
"system": "http://example.org/sdh/dtr/aslp/CodeSystem/aslp-codes",
"code": "ASLP.A1.DE14",
"display": "Artificial intelligence (AI)"
}
],
"text": "Artificial intelligence (AI)"
},
"subject": {
"reference": "Patient/positive"
},
"authoredOn": "2023-04-06",
"reasonReference": [
{
"reference": "Condition/SleepApnea"
}
],
"occurrenceDateTime": "2023-04-15",
"requester": {
"reference": "Practitioner/positive-Practitioner"
}
},
"request": {
"method": "PUT",
"url": "ServiceRequest/SleepStudy2"
}
}
]
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,104 @@
{
"resourceType": "QuestionnaireResponse",
"id": "QRSharonDecision",
"meta": {
"versionId": "1",
"lastUpdated": "2021-12-28T18:10:32.808+00:00",
"source": "#R7Wf0emvrt2bSkbQ",
"profile": [
"http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire|2.7",
"http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-shareablequestionnaire"
],
"tag": [
{
"code": "lformsVersion: 25.1.3"
}
]
},
"questionnaire": "http://fhir.org/guide/cqf/cds4cpm",
"status": "completed",
"subject": {
"reference": "Patient/sharondecision",
"display": "Sharon Decision"
},
"authored": "2021-12-28T11:10:32-07:00",
"item": [
{
"linkId": "1",
"text": "My Pain Location: We’d like to ask you a few questions about your pain and how it is affecting your life. Please describe the location(s) of any pain you have had in the past 7 days. Please select only one pain type per location.",
"item": [
{
"linkId": "1.1",
"text": "Head: What type of HEAD pain?",
"answer": [
{
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "55145008",
"display": "Stabbing"
}
}
]
},
{
"linkId": "1.6",
"text": "Lower Back: What type of LOWER BACK pain?",
"answer": [
{
"valueCoding": {
"system": "http://snomed.info/sct",
"code": "162506004",
"display": "Prickling"
}
}
]
}
]
},
{
"linkId": "2",
"text": "My Pain Intensity: Thinking about your overall pain, in the past 7 days, please respond to the questions below:",
"item": [
{
"linkId": "2.1",
"text": "How intense was your pain at its worst?",
"answer": [
{
"valueCoding": {
"system": "http://loinc.org",
"code": "LA6750-9",
"display": "Severe"
}
}
]
},
{
"linkId": "2.2",
"text": "How intense was your average pain?",
"answer": [
{
"valueCoding": {
"system": "http://loinc.org",
"code": "LA6750-9",
"display": "Severe"
}
}
]
},
{
"linkId": "2.3",
"text": "What is your level of pain right now?",
"answer": [
{
"valueCoding": {
"system": "http://loinc.org",
"code": "LA6750-9",
"display": "Severe"
}
}
]
}
]
}
]
}

View File

@ -0,0 +1,35 @@
{
"resourceType": "Bundle",
"id": "CdsHooksMultipleActions-PlanDefinition-1.0.0",
"type": "collection",
"entry": [
{
"resource": {
"resourceType": "RequestGroup",
"id": "CdsHooksMultipleActions-PlanDefinition-1.0.0",
"instantiatesCanonical": [
"http://example.com/PlanDefinition/CdsHooksMultipleActions-PlanDefinition-1.0.0"
],
"status": "draft",
"intent": "proposal",
"subject": {
"reference": "patient-CdsHooksMultipleActions"
},
"action": [
{
"title": "Summary",
"description": "Detail"
},
{
"title": "Summary 1",
"description": "Detail 1"
},
{
"title": "Child Monthly Routine Visit",
"description": "This action will performed every month for a patient < 5 years old. The start date with be next month after registration while the end date will be the 60th week after birth."
}
]
}
}
]
}

View File

@ -0,0 +1,47 @@
{
"resourceType": "CarePlan",
"id": "CdsHooksMultipleActions-PlanDefinition-1.0.0",
"contained": [
{
"resourceType": "RequestGroup",
"id": "CdsHooksMultipleActions-PlanDefinition-1.0.0",
"instantiatesCanonical": [
"http://example.com/PlanDefinition/CdsHooksMultipleActions-PlanDefinition-1.0.0"
],
"status": "draft",
"intent": "proposal",
"subject": {
"reference": "patient-CdsHooksMultipleActions"
},
"action": [
{
"title": "Summary",
"description": "Detail"
},
{
"title": "Summary 1",
"description": "Detail 1"
},
{
"title": "Child Monthly Routine Visit",
"description": "This action will performed every month for a patient < 5 years old. The start date with be next month after registration while the end date will be the 60th week after birth."
}
]
}
],
"instantiatesCanonical": [
"http://example.com/PlanDefinition/CdsHooksMultipleActions-PlanDefinition-1.0.0"
],
"status": "draft",
"intent": "proposal",
"subject": {
"reference": "patient-CdsHooksMultipleActions"
},
"activity": [
{
"reference": {
"reference": "#RequestGroup/CdsHooksMultipleActions-PlanDefinition-1.0.0"
}
}
]
}

View File

@ -0,0 +1,28 @@
{
"resourceType": "Bundle",
"id": "CdsHooksMultipleActions-PD-bundle",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Patient",
"id": "patient-CdsHooksMultipleActions",
"gender": "female",
"birthDate": "1982-01-07",
"name": [
{
"family": "Smith",
"given": [
"John",
"A."
]
}
]
},
"request": {
"method": "PUT",
"url": "Patient/patient-CdsHooksMultipleActions"
}
}
]
}

View File

@ -0,0 +1,140 @@
{
"resourceType": "Bundle",
"id": "CdsHooksMultipleActions-Plans-1.0.0",
"type": "transaction",
"entry": [
{
"resource": {
"resourceType": "Library",
"id": "CdsHooksMultipleActions",
"url": "http://example.com/Library/CdsHooksMultipleActions",
"version": "1.0.0",
"name": "CdsHooksMultipleActions",
"title": "CdsHooksMultipleActions",
"status": "draft",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/library-type",
"code": "logic-library"
}
]
},
"jurisdiction": [
{
"coding": [
{
"system": "urn:iso:std:iso:3166",
"code": "US",
"display": "United States of America"
}
],
"text": "United States of America"
}
],
"relatedArtifact": [
{
"type": "depends-on",
"display": "FHIR model information",
"resource": "http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1"
}
],
"content": [
{
"contentType": "text/cql",
"data": "bGlicmFyeSBDZHNIb29rc011bHRpcGxlQWN0aW9ucyB2ZXJzaW9uICcxLjAuMCcKCnVzaW5nIEZISVIgdmVyc2lvbiAnNC4wLjEnCgpjb250ZXh0IFBhdGllbnQKCmRlZmluZSAiSXMgQWN0aW9uIEFwcGxpY2FibGU/IjogdHJ1ZQoKZGVmaW5lICJHZXQgU3VtbWFyeSI6ICdTdW1tYXJ5JwoKZGVmaW5lICJHZXQgRGV0YWlsIjogJ0RldGFpbCcKCmRlZmluZSAiR2V0IFN1bW1hcnkgMSI6ICdTdW1tYXJ5IDEnCgpkZWZpbmUgIkdldCBEZXRhaWwgMSI6ICdEZXRhaWwgMSc="
}
]
},
"request": {
"method": "PUT",
"url": "Library/CdsHooksMultipleActions"
}
},
{
"resource": {
"resourceType": "PlanDefinition",
"id": "CdsHooksMultipleActions-PlanDefinition-1.0.0",
"url": "http://example.com/PlanDefinition/CdsHooksMultipleActions-PlanDefinition-1.0.0",
"name": "Cds Hooks Multiple Actions PlanDefinition",
"title": "Cds Hooks Multiple Actions PlanDefinition",
"status": "active",
"experimental": false,
"description": "This is a plan to test multiple actions",
"library": [
"http://example.com/Library/CdsHooksMultipleActions"
],
"action": [
{
"title": "Child Monthly Routine Visit",
"description": "This action will performed every month for a patient < 5 years old. The start date with be next month after registration while the end date will be the 60th week after birth.",
"priority": "routine",
"type": {
"coding": [
{
"code": "clinical-protocol",
"display": "Clinical Protocol"
}
]
},
"trigger": [
{
"type": "named-event",
"name": "patient-view"
}
],
"condition": [
{
"kind": "applicability",
"expression": {
"language": "text/cql.identifier",
"expression": "Is Action Applicable?"
}
}
],
"dynamicValue": [
{
"path": "action.title",
"expression": {
"language": "text/cql.identifier",
"expression": "Get Summary"
}
},
{
"path": "action.description",
"expression": {
"language": "text/cql.identifier",
"expression": "Get Detail"
}
}
],
"action": [
{
"dynamicValue": [
{
"path": "action.action.title",
"expression": {
"language": "text/cql.identifier",
"expression": "Get Summary 1"
}
},
{
"path": "action.action.description",
"expression": {
"language": "text/cql.identifier",
"expression": "Get Detail 1"
}
}
]
}
]
}
]
},
"request": {
"method": "PUT",
"url": "PlanDefinition/CdsHooksMultipleActions-PlanDefinition-1.0.0"
}
}
]
}

View File

@ -962,7 +962,7 @@
<elastic_apm_version>1.28.4</elastic_apm_version>
<!-- CQL Support -->
<clinical-reasoning.version>3.0.0.PRE-1</clinical-reasoning.version>
<clinical-reasoning.version>3.0.0-SNAPSHOT</clinical-reasoning.version>
<!-- Site properties -->
<fontawesomeVersion>5.4.1</fontawesomeVersion>