12.12.1Prior Auth CRD Examples

 

This page contains example interceptors that can be registered with Prior Auth CRD.

12.12.2Example: Starter Prior Auth CRD interceptor for PRIOR_AUTH_CRD_GATHER_CONTEXT pointcut

 

The following interceptor is intended to be used within the Prior Auth CRD module as a starter interceptor. The purpose of the pointcut is to provide customers with the capability to determine Patient in context.

/*-
 * #%L
 * Smile CDR - CDR
 * %%
 * Copyright (C) 2016 - 2025 Smile CDR, Inc.
 * %%
 * All rights reserved.
 * #L%
 */

package com.smilecdr.demo.priorauthcrd;

import ca.cdr.api.fhir.interceptor.CdrHook;
import ca.cdr.api.fhir.interceptor.CdrPointcut;
import ca.cdr.api.priorauth.PriorAuthCrdContextJson;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.api.server.cdshooks.CdsServiceRequestJson;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import jakarta.annotation.Nonnull;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Coverage;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.ResourceType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

/**
 * Sample interceptor codebase which allows getting Payer Patient ID by matching Provider and Payer Coverage resources
 * based off Identifier
 */
@SuppressWarnings({"unused"})
@Interceptor
public class PriorAuthCRDInterceptorTemplate {
	private static final Logger ourLog = LoggerFactory.getLogger(PriorAuthCRDInterceptorTemplate.class);
	private static final String IDENTIFIER_SYSTEM = "http://acme.org/fhir-ns/payer-coverage-identifier-system";

	@Autowired
	@Qualifier("paCrdDaoRegistry")
	private DaoRegistry myDaoRegistry;

	@CdrHook(CdrPointcut.PRIOR_AUTH_CRD_GATHER_CONTEXT)
	public void gatherContext(
			@Nonnull CdsServiceRequestJson theCdsServiceRequestJson,
			@Nonnull PriorAuthCrdContextJson thePriorAuthCrdContextJson) {
		ourLog.info("Interceptor PRIOR_AUTH_CRD_GATHER_CONTEXT - started");
		final Bundle coverageBundle = (Bundle) theCdsServiceRequestJson.getPrefetch("coverageBundle");
		final Identifier coverageIdentifier = getProviderCoverageIdentifier(coverageBundle);
		final String payerPatientId = getPayerPatientId(coverageIdentifier);
		thePriorAuthCrdContextJson.setPayerPatientId(payerPatientId);
		ourLog.info("Interceptor PRIOR_AUTH_CRD_GATHER_CONTEXT - ended");
	}

	/**
	 * Get the provider Coverage identifier from provider Coverage bundle found in prefetch of CDS hooks request
	 * @param theRequest the provider Coverage bundle
	 * @return provider coverage identifier
	 */
	@Nonnull
	private Identifier getProviderCoverageIdentifier(@Nonnull Bundle theRequest) {
		final Coverage providerCoverage = theRequest.getEntry().stream()
				.map(Bundle.BundleEntryComponent::getResource)
				.filter(resource -> resource.getResourceType().equals(ResourceType.Coverage))
				.map(Coverage.class::cast)
				.findFirst()
				.orElseThrow(() -> new UnprocessableEntityException("Coverage resource not found"));
		return providerCoverage.getIdentifier().stream()
				.filter(identifier -> identifier.getSystem().equals(IDENTIFIER_SYSTEM))
				.findFirst()
				.orElseThrow(() -> new UnprocessableEntityException("Identifier with specified system not found"));
	}

	/**
	 * Get the Payer Patient ID in context
	 * @param theCoverageIdentifier provider coverage identifier
	 * @return Payer Patient ID
	 */
	@Nonnull
	private String getPayerPatientId(@Nonnull Identifier theCoverageIdentifier) {
		final SearchParameterMap searchParameterMap = getSearchParameterMap(theCoverageIdentifier);
		final IFhirResourceDao<Coverage> coverageResourceDao = myDaoRegistry.getResourceDao(Coverage.class);
		final IBundleProvider search = coverageResourceDao.search(searchParameterMap, new SystemRequestDetails());
		return ((Coverage) search.getAllResources().get(0)).getBeneficiary().getReference();
	}

	/**
	 *  Build SearchParameterMap for Dao search on Coverage identifier
	 * @param theCoverageIdentifier provider coverage identifier
	 * @return SearchParameterMap
	 */
	@Nonnull
	private SearchParameterMap getSearchParameterMap(@Nonnull Identifier theCoverageIdentifier) {
		final TokenParam tokenParam =
				new TokenParam(theCoverageIdentifier.getSystem(), theCoverageIdentifier.getValue());
		final SearchParameterMap searchParameterMap = new SearchParameterMap();
		searchParameterMap.add(Coverage.SP_IDENTIFIER, tokenParam);
		return searchParameterMap;
	}
}